diff --git a/Cargo.lock b/Cargo.lock index 6518e25e8c..aade891fb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3046,6 +3046,7 @@ name = "e3-aggregator" version = "0.1.15" dependencies = [ "actix", + "alloy", "anyhow", "async-trait", "bincode 1.3.3", @@ -3065,6 +3066,7 @@ dependencies = [ "e3-utils", "e3-zk-helpers", "fhe-math", + "futures", "num-bigint", "serde", "tracing", diff --git a/agent/flow-trace/00_INDEX.md b/agent/flow-trace/00_INDEX.md index 8776fcaf21..a6d5e3b4cf 100644 --- a/agent/flow-trace/00_INDEX.md +++ b/agent/flow-trace/00_INDEX.md @@ -176,19 +176,19 @@ _Found during source-code cross-referencing of these trace documents._ | 4 | `activate()` calls `register()` → `registerOperator()` which has `require(!registered, AlreadyRegistered())`. So activate **reverts** for already-registered operators. It only works for re-registration after deregistration. | BondingRegistry.sol:308 | 01_REGISTRATION | | 5 | `E3Requested` event is `(uint256 e3Id, E3 e3, IE3Program indexed e3Program)` — seed and params are inside the E3 struct, not separate parameters. | IEnclave.sol:82 | 03_E3_REQUEST | | 6 | `finalizeCommittee()` checks `>=` deadline, not `>`. | CiphernodeRegistryOwnable.sol | 03_E3_REQUEST | -| 7 | `publishCommittee()` is now permissionless. The effective access control is DKG proof verification plus the single-publish guard `publicKeyHashes[e3Id] == 0`; the old `onlyOwner` note is obsolete. | CiphernodeRegistryOwnable.sol | 04_DKG | -| 8 | `CommitteePublished` event emits `(e3Id, nodes, publicKey, pkCommitment, proof)` — full PK bytes, pkCommitment, and proof bytes (DkgAggregator when proof aggregation is enabled), not just pkHash. | CiphernodeRegistryOwnable.sol | 04_DKG | +| 7 | `publishCommittee()` is now permissionless. The effective access control is DKG proof verification plus the single-publish guard `publicKeyHashes[e3Id] == 0`; the old `onlyOwner` note is obsolete. | CiphernodeRegistryOwnable.sol | 04_DKG | +| 8 | `CommitteePublished` event emits `(e3Id, nodes, publicKey, pkCommitment, proof)` — full PK bytes, pkCommitment, and proof bytes (DkgAggregator when proof aggregation is enabled), not just pkHash. | CiphernodeRegistryOwnable.sol | 04_DKG | | 9 | `_validateNodeEligibility` calls `bondingRegistry.getTicketBalanceAtBlock()` (not `ticketToken.getPastVotes()` directly). | CiphernodeRegistryOwnable.sol:668 | 03_E3_REQUEST | | 10 | Lane A slashing uses **attestation-based** verification (committee quorum votes), not direct ZK proof re-verification on-chain. `proposeSlash()` decodes voter addresses, agrees, data hashes, and ECDSA signatures — not ZK proofs. | SlashingManager.sol | 05_FAILURE | ### Protocol Design Concerns -| # | Concern | Severity | Detail | -| --- | ---------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | **Deregister-before-slash race** | Accepted | SlashingManager Lane B (evidence+appeal) has a window during which the operator can deregister and claim their exit. If they do, the slash executes against 0 funds. The contract comments acknowledge this as an accepted tradeoff for the appeal window design. | -| 2 | **Committee publication decentralized** | Resolved | `publishCommittee()` is permissionless. Off-chain role selection chooses the active aggregator, while on-chain C5 proof verification and the single-publish guard prevent invalid or duplicate committee publication. | -| 3 | **`gracePeriod` is dead code** | Medium | `gracePeriod` is stored and validated during config updates but never actually used in any timeout check. Either the deadlines already bake in sufficient buffer, or this is a missing feature. | -| 4 | **`activate` CLI command is misleading** | Low | Named "activate" but actually calls "register" — will fail for already-registered operators. There's no standalone way to trigger re-evaluation of active status; instead, `_updateOperatorStatus()` runs automatically inside `addTicketBalance()`, `bondLicense()`, etc. | -| 5 | **Active-job load balancing bug fixed** | Info | The Rust `NodeStateStore.available_tickets()` subtracts `active_jobs` from total tickets, reducing the chance of busy nodes being selected for new E3s. Previously, the `Sortition` actor's `Handler` was missing match arms for `E3Failed` and `E3StageChanged`, causing these events to fall to the default `_ => ()` — the typed handlers for decrementing jobs were dead code. This has been fixed: E3Failed and E3StageChanged are now routed to their handlers, and `finalized_committees` is cleaned up in `decrement_jobs_for_e3` to prevent unbounded memory growth. | -| 6 | **Committee member expulsion** | Info | `SlashingManager` can call `expelCommitteeMember()` mid-DKG. The `Sortition` actor enriches the raw `CommitteeMemberExpelled` event with the expelled member's `party_id` (resolved from its stored `Committee` list) and re-publishes it. `ThresholdKeyshare` then uses the enriched `party_id` to update its collectors, potentially completing DKG with fewer parties. `ThresholdKeyshare` itself does not hold committee state. | -| 7 | **ProofRequestActor failure bridge fixed** | Info | `ProofRequestActor` no longer leaves proof publication suppressed under log-only "will not be published" exits. `ComputeRequestError` and local proof-signing failures for DKG-path proofs (`C0` through `C5`) now emit `E3Failed { failed_at_stage: CommitteeFinalized, reason: DKGInvalidShares }`, while decryption-path proofs (`C6` and `C7`) emit `E3Failed { failed_at_stage: CiphertextReady, reason: DecryptionInvalidShares }`. | +| # | Concern | Severity | Detail | +| --- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | **Deregister-before-slash race** | Accepted | SlashingManager Lane B (evidence+appeal) has a window during which the operator can deregister and claim their exit. If they do, the slash executes against 0 funds. The contract comments acknowledge this as an accepted tradeoff for the appeal window design. | +| 2 | **Committee publication decentralized** | Resolved | `publishCommittee()` is permissionless. Off-chain role selection chooses the active aggregator, while on-chain C5 proof verification and the single-publish guard prevent invalid or duplicate committee publication. | +| 3 | **`gracePeriod` is dead code** | Medium | `gracePeriod` is stored and validated during config updates but never actually used in any timeout check. Either the deadlines already bake in sufficient buffer, or this is a missing feature. | +| 4 | **`activate` CLI command is misleading** | Low | Named "activate" but actually calls "register" — will fail for already-registered operators. There's no standalone way to trigger re-evaluation of active status; instead, `_updateOperatorStatus()` runs automatically inside `addTicketBalance()`, `bondLicense()`, etc. | +| 5 | **Active-job load balancing bug fixed** | Info | The Rust `NodeStateStore.available_tickets()` subtracts `active_jobs` from total tickets, reducing the chance of busy nodes being selected for new E3s. Previously, the `Sortition` actor's `Handler` was missing match arms for `E3Failed` and `E3StageChanged`, causing these events to fall to the default `_ => ()` — the typed handlers for decrementing jobs were dead code. This has been fixed: E3Failed and E3StageChanged are now routed to their handlers, and `finalized_committees` is cleaned up in `decrement_jobs_for_e3` to prevent unbounded memory growth. | +| 6 | **Committee member expulsion** | Info | `SlashingManager` can call `expelCommitteeMember()` mid-DKG. The `Sortition` actor enriches the raw `CommitteeMemberExpelled` event with the expelled member's `party_id` (resolved from its stored `Committee` list) and re-publishes it. `ThresholdKeyshare` then uses the enriched `party_id` to update its collectors, potentially completing DKG with fewer parties. `ThresholdKeyshare` itself does not hold committee state. | +| 7 | **ProofRequestActor failure bridge fixed** | Info | `ProofRequestActor` no longer leaves proof publication suppressed under log-only "will not be published" exits. `ComputeRequestError` and local proof-signing failures for DKG-path proofs (`C0` through `C5`) now emit `E3Failed { failed_at_stage: CommitteeFinalized, reason: DKGInvalidShares }`, while decryption-path proofs (`C6` and `C7`) emit `E3Failed { failed_at_stage: CiphertextReady, reason: DecryptionInvalidShares }`. | diff --git a/agent/flow-trace/04_DKG_AND_COMPUTATION.md b/agent/flow-trace/04_DKG_AND_COMPUTATION.md index 520a7690f5..30d54512e5 100644 --- a/agent/flow-trace/04_DKG_AND_COMPUTATION.md +++ b/agent/flow-trace/04_DKG_AND_COMPUTATION.md @@ -171,6 +171,7 @@ ThresholdKeyshare receives AllEncryptionKeysCollected │ │ Output: esi_sss[num_ciphertexts][N] │ │ └─────────────────────────────────────────────────────────┘ ``` + │ ├─ ThresholdKeyshare tracks the correlation id for both TrBFV requests: │ ├─ `GenPkShareAndSkSss` @@ -314,11 +315,11 @@ aggregation path can terminate deterministically instead of stalling on missing `PublicKeyAggregator` and `ThresholdPlaintextAggregator` dispatch the aggregator requests instead of pairwise folding. -**Failure bridge:** `ProofRequestActor` now converts proof-generation worker failures -and local proof-signing failures into terminal round failures instead of only -logging that the proof-bearing artifact will not be published. DKG-path proofs -(`C0` through `C5`) emit `E3Failed { failed_at_stage: CommitteeFinalized, -reason: DKGInvalidShares }`; decryption-path proofs (`C6` and `C7`) emit +**Failure bridge:** `ProofRequestActor` now converts proof-generation worker failures and local +proof-signing failures into terminal round failures instead of only logging that the proof-bearing +artifact will not be published. DKG-path proofs (`C0` through `C5`) emit +`E3Failed { failed_at_stage: CommitteeFinalized, reason: DKGInvalidShares }`; decryption-path proofs +(`C6` and `C7`) emit `E3Failed { failed_at_stage: CiphertextReady, reason: DecryptionInvalidShares }`. ### Step 6: Collect All Threshold Shares (with C2/C3 Verification) @@ -599,36 +600,38 @@ ThresholdKeyshare receives AllThresholdSharesCollected ├─ Requires EffectsEnabled ├─ Requires active_aggregators[e3_id] == true ├─ Reads chain state to confirm committee public key is still unset - └─ Calls contract.publishCommittee(e3_id, nodes, publicKey, pkHash) + └─ Calls contract.publishCommittee(e3_id, publicKey, pkCommitment, proof) │ │ ┌─── ON-CHAIN (CiphernodeRegistryOwnable) ──────────┐ │ │ │ - │ │ publishCommittee(e3Id, nodes, pk, pkHash) { │ - │ │ 1. require(initialized && finalized) │ - │ │ 2. require(publicKeyHashes[e3Id] == 0) │ - │ │ → Can only publish once │ - │ │ 3. require(nodes.length == committee.length) │ + │ │ publishCommittee(e3Id, publicKey, pkCommitment, proof) { │ + │ │ 1. require(stage == Finalized) │ + │ │ 2. require(c.publicKey == 0) — publish once │ + │ │ 3. committeeHash = keccak256(abi.encodePacked(c.topNodes)) │ + │ │ c.committeeHash = committeeHash │ │ │ 4. When proofAggregationEnabled: │ - │ │ e3.pkVerifier.verify(pkCommitment, proof) │ + │ │ e3.pkVerifier.verify(pkCommitment, committeeHash, proof) │ │ │ → BFV: `BfvPkVerifier` (DkgAggregator Honk) │ │ │ • pins `publicInputs[0]` = nodes_fold VK hash │ │ │ • pins `publicInputs[1]` = C5 VK hash │ - │ │ • checks last PI = pkCommitment │ - │ │ Redeploy verifier when sub-circuit VKs change. │ - │ │ 5. publicKeyHashes[e3Id] = pkHash │ - │ │ 6. enclave.onCommitteePublished(e3Id, pkHash) │ + │ │ • checks committee_hash_hi/lo vs committeeHash │ + │ │ • checks last PI == pkCommitment │ + │ │ Redeploy `BfvPkVerifier` / `BfvDecryptionVerifier` │ + │ │ when sub-circuit VK immutables change. │ + │ │ 5. c.publicKey = pkCommitment │ + │ │ publicKeyHashes[e3Id] = pkCommitment │ + │ │ 6. enclave.onCommitteePublished(e3Id, pkCommitment) │ │ │ │ │ │ │ │ ┌─ Enclave.sol ────────────────────────┐ │ - │ │ │ │ onCommitteePublished(e3Id, pkHash) {│ │ + │ │ │ │ onCommitteePublished(e3Id, pk) { │ │ │ │ │ │ require(stage==CommitteeFinalized) │ │ - │ │ │ │ e3.committeePublicKey = pkHash │ │ - │ │ │ │ → stored as bytes32 (a hash) │ │ + │ │ │ │ e3.committeePublicKey = pk │ │ │ │ │ │ stage = KeyPublished │ │ │ │ │ │ Emit E3StageChanged(KeyPublished) │ │ │ │ │ │ } │ │ │ │ │ └──────────────────────────────────────┘ │ - │ │ 7. Emit CommitteePublished(e3Id, nodes, pk, C5 proof) │ - │ │ → Note: emits full pk bytes, NOT just pkHash │ + │ │ 7. Emit CommitteePublished( │ + │ │ e3Id, c.topNodes, publicKey, pkCommitment, proof) │ │ │ } │ │ └─────────────────────────────────────────────────────┘ ``` diff --git a/circuits/benchmarks/README.md b/circuits/benchmarks/README.md index 63c2f3562e..9d3a110091 100644 --- a/circuits/benchmarks/README.md +++ b/circuits/benchmarks/README.md @@ -134,5 +134,22 @@ For `Π_DKG` and `Π_dec`, verifier gas is sourced from folded recursive-aggrega by `cargo test -p e3-tests test_trbfv_actor` (via `BENCHMARK_FOLDED_OUTPUT`) and then replayed into EVM verifier `estimateGas` in `packages/enclave-contracts/scripts/benchmarkGasFromRaw.ts`. +`extract_crisp_verify_gas.sh` (and `replay_folded_verify_gas.sh --build `) call +`ensure_circuit_preset_built.sh`, which runs +`pnpm build:circuits --skip-if-built --no-clean --no-clean-targets` by default (skips recompile when +`dist/circuits//.build-stamp.json` and marker artifacts match the current circuit sources). +Then `pnpm generate:verifiers --no-compile` refreshes Honk contracts before integration export and +Hardhat replay. + +- **`--force-build`** on extract/replay/ensure: full rebuild (same as a fresh `build:circuits`). +- **`--skip-build`** on extract/replay: skip circuit build and Honk generation (only re-run + integration + gas replay). Fails fast unless `dist/circuits//` and `circuits/bin` targets + are present for that preset (`check_circuit_preset_artifacts.sh`). + +`run_benchmarks.sh` preflight uses the same `ensure` + `--skip-if-built`. When preset artifacts are +ready, per-circuit `nargo compile` is skipped automatically (Stage 1 `ensure` skips too). Generated +`Prover.toml` files under `circuits/bin/` are excluded from the preset source hash so benchmarks do +not invalidate the stamp. Use **`--bench-compile`** to force per-circuit compile timings anyway. + `Calldata gas` is computed from benchmark proof/public-input bytes with EVM calldata costs (`0x00 -> 4`, non-zero byte -> 16) and stored in raw benchmark JSON. diff --git a/circuits/benchmarks/results_insecure/crisp_verify_gas.json b/circuits/benchmarks/results_insecure/crisp_verify_gas.json index 42985be404..ee6f0369ae 100644 --- a/circuits/benchmarks/results_insecure/crisp_verify_gas.json +++ b/circuits/benchmarks/results_insecure/crisp_verify_gas.json @@ -1,33 +1,79 @@ { "verify_gas": { - "dkg": 3037910, - "user": 2972965, - "dec": 3549222 + "dkg": 3042430, + "user": 2972893, + "dec": 3553544 }, "source": "folded_proof_export_plus_crisp_verify_test", "artifact_sizes_bytes": { "dkg": { "proof": 10944, - "public_inputs": 416 + "public_inputs": 480 }, "dec": { "proof": 10944, - "public_inputs": 3488 + "public_inputs": 3552 } }, "calldata_gas": { "dkg": { - "proof": 169920, - "public_inputs": 5504, - "total": 175424 + "proof": 169968, + "public_inputs": 6144, + "total": 176112 }, "dec": { - "proof": 170100, - "public_inputs": 16664, - "total": 186764 + "proof": 169848, + "public_inputs": 17304, + "total": 187152 + } + }, + "integration_summary": { + "integration_test": "test_trbfv_actor", + "multithread": { "rayon_threads": 13, "max_simultaneous_rayon_tasks": 1, "cores_available": 14 }, + "operation_timings": [ + { "name": "CalculateDecryptionKey", "avg_seconds": 0.111521499, "runs": 3, "total_seconds": 0.334564499 }, + { "name": "CalculateDecryptionShare", "avg_seconds": 0.610321888, "runs": 3, "total_seconds": 1.830965666 }, + { "name": "CalculateThresholdDecryption", "avg_seconds": 0.559050209, "runs": 1, "total_seconds": 0.559050209 }, + { "name": "GenEsiSss", "avg_seconds": 0.124032833, "runs": 3, "total_seconds": 0.372098501 }, + { "name": "GenPkShareAndSkSss", "avg_seconds": 0.226692527, "runs": 3, "total_seconds": 0.680077583 }, + { "name": "ZkDecryptedSharesAggregation", "avg_seconds": 8.500284375, "runs": 1, "total_seconds": 8.500284375 }, + { "name": "ZkDecryptionAggregation", "avg_seconds": 49.366586083, "runs": 1, "total_seconds": 49.366586083 }, + { "name": "ZkDkgAggregation", "avg_seconds": 21.116986167, "runs": 1, "total_seconds": 21.116986167 }, + { "name": "ZkDkgShareDecryption", "avg_seconds": 1.465883083, "runs": 6, "total_seconds": 8.795298501 }, + { "name": "ZkNodeDkgFold", "avg_seconds": 62.328322972, "runs": 3, "total_seconds": 186.984968916 }, + { "name": "ZkPkAggregation", "avg_seconds": 2.200691667, "runs": 1, "total_seconds": 2.200691667 }, + { "name": "ZkPkBfv", "avg_seconds": 0.336088264, "runs": 3, "total_seconds": 1.008264792 }, + { "name": "ZkPkGeneration", "avg_seconds": 1.351367042, "runs": 3, "total_seconds": 4.054101126 }, + { "name": "ZkShareComputation", "avg_seconds": 2.682164854, "runs": 6, "total_seconds": 16.092989126 }, + { "name": "ZkShareEncryption", "avg_seconds": 2.506225536, "runs": 24, "total_seconds": 60.149412873 }, + { "name": "ZkThresholdShareDecryption", "avg_seconds": 6.176445291, "runs": 3, "total_seconds": 18.529335875 }, + { "name": "ZkVerifyShareDecryptionProofs", "avg_seconds": 0.100550749, "runs": 3, "total_seconds": 0.301652249 }, + { "name": "ZkVerifyShareProofs", "avg_seconds": 0.221828033, "runs": 5, "total_seconds": 1.109140168 } + ], + "operation_timings_total_seconds": 381.986468376, + "timings_seconds": [ + { "label": "Starting trbfv actor test", "seconds": 0e-9 }, + { "label": "Setup completed", "seconds": 3.0715085 }, + { "label": "Committee Setup Completed", "seconds": 20.22829075 }, + { "label": "Committee Finalization Complete", "seconds": 0.006707541 }, + { "label": "ThresholdShares -> PublicKeyAggregated", "seconds": 304.143739958 }, + { "label": "E3Request -> PublicKeyAggregated", "seconds": 306.698077958 }, + { "label": "Application CT Gen", "seconds": 0.313315125 }, + { "label": "Running FHE Application", "seconds": 0.003688125 }, + { "label": "Ciphertext published -> PlaintextAggregated", "seconds": 79.884513625 }, + { "label": "Entire Test", "seconds": 410.2113715 } + ], + "folded_artifacts": { + "dkg_aggregator": { + "proof_hex": "0x000000000000000000000000000000000000000000000001104c69c76ea8f5f6000000000000000000000000000000000000000000000005c85075d6baa615c900000000000000000000000000000000000000000000000eb6de0b1c015f0f2a0000000000000000000000000000000000000000000000000002a0b5c2857c800000000000000000000000000000000000000000000000036176084b0205127a000000000000000000000000000000000000000000000004549377f025fd0f40000000000000000000000000000000000000000000000003ff07c8a94fbdbbd8000000000000000000000000000000000000000000000000000185ecac0421330000000000000000000000000000000000000000000000044f1f17a53eba29b1000000000000000000000000000000000000000000000004096147c1d40da636000000000000000000000000000000000000000000000007c2eaade9aae157c100000000000000000000000000000000000000000000000000023ccf2dca92b000000000000000000000000000000000000000000000000e02d12f90edb8cac6000000000000000000000000000000000000000000000007c223713eba54496600000000000000000000000000000000000000000000000ec928a9ef7dcf2da9000000000000000000000000000000000000000000000000000282e9bb83bee61a05d33c39ba3812376a494cad4c46e07e18763a4c0cc37c7ac2f3635530c6110f00693d937276e524dafd5fffac373d40ca9ac38bc4003aa97fa25c28eaae471e6801e127832204ea5a325f05bb8550bd90338e17663499f9908e07c1a27a4d25db068d58486c5ed1d571b154613b2a444f9ef333d6490c341531f43898470028e20e0d46d87d6e6a8c672bd88dbdbae7c0e0a9d06da0323fdaf7ee61ceb7611d45afd3c8ec55431dab1b693939c2a7f313b832a28959c3ae3d30629655cc051ff1a5efe96161c60a46f240cb6ca1a531353aec9b48b52ad525bf6481f17e0923676a74fc00629f08348ca4b4467e32b7907ccf75e78538096134b580c00ad016d8f24d8b2251a384465ecf7da74301f64008beb9c8b71af609a0085afa8bb10891080d365806d9ed9f21901108254290c057a4b986687bebd3eae86d9d84d52ba59894f06a73d164ff99fcb0d13873279ce4f307eef63d2c0ba38c4624e95e009c113dba40ba429e2620e10806283dd5fad8df1b6a85051c1f7167194c70620f370484b9bd06cf6e6199ccd69d2c0e0db004474b4ffc62084f7697d21fc04f1518380c30df7edd6752046611f209863dd69ccbd4af39b35e05dbaa35d7aea81dac6609d0b9b649962dd23bd220709758af7743abf5395724f809100dfd19cb13ee772bc80efdcb985314bbe58feda8ac8cb79523fe9ff183ebf3e6835eff81084ebea45358443421fb0f2d31a11171c0537eaf216aa68a5bfefa0d02b1c5b92a10ac9238f294ee18007a6f18f72214951c398ce84c3616bcf3c79e0f2e2f022a0c90527061c47a42c43cace4fc879a5a326863a6f82d9c6bb420290aa900d8244a98b1668bcfcb6023d101fde9f2fa579bbd8947480f7058466d6000b38c5c1a4fd3aa5794aad136c957e92be80cca60120b6d839e54f1036f9e857e14746f2433e79c2a2df9f7ea53e60405fe812eb086dfac1f0b0c638610dbdd208a28f2260c558292be011ce1ad7ea6fc1a18428a3199764be0e5e4169e261b655ffddd06ca1104a26cac71683ee832dcd3cac2ca05e81de30bed5f8b67ce620c6f88f62d90a64a9659cd90458edbd62bb6cc9f8d942669ccb243386ee53c938746a2462ab0830a5ee749ccf6259eb0ddd308297e3093c1e2bf8454dd5e900345907a8608b9832d8e40d08cb3dbf14939398e8c032b1baf82f3b45da26fc2aa8a69639d1379060a52801809840916499ab8679e0af7fa2b5e549f58ddfc8c60090ad5d42fcf59ab9661b29f6aee13a20e279602925e6fffb2328ef1334585e819ea8002085571a91540444e60b8c9350331f5cdfe8ba889466f4b26343d3b179b436d1015fdbeb6b1586fec95a850abe17e3d23dbb519b068c9c59ed740833e71319db516be4631e64a10edbbdfac8daafe9004a1dfb5631249e558132163eb6429c715143679b05e2edc9c236a9a7ca760761c3a117bb03755bf8d04aefc7742ab0ba811710087242ad211047ff4f6b9c4f8faa4640f53721a400815c301a8b079d1ca2b7184bc65e7bc3cd2c380df2376ec233411c4d429fb12795cdaa8b932bff94628703868796573c773ba5a60dbe2dcfdba86fbf73e2cbabe306511dd6f71509607ebc04687500585f37d8135ebac5386803439c01b36e449d3b029c1576fc2f422160f4fa03d8f11c89e134103a7918939563aad5285049c66b3479d416852b11896f8b31c6d91580c0cc03bd04ef40a9b201d686cbfec6170ee5a1aace7c7f2248c548038c030a7c267fe72915cd397e273c42561e11410672a1e41f71827eb247b679c4eebf11bf064f256f418ef2364b7eaa29fa9cfbf018eef1952daebd915d423652908cbd25b28b3b07d28cc918af5ac73226b02d6340d02ee74f643db15c870a4de33c870580fb55142ed86a7b1efb02d4f5d1d6e074137126f61818d0dce8e49b8aff13f2e80fa7d585aff6147ee7265bc92df749635d9cd77bfb87508e4dd08b4f437bb59702e34ec8c390bf6e7455a4619bb3586688b16e1045a9c0c8d0b760cf3d11357e9840fd3e702cce25045c7835bb1b0ce6275af5571d18d1e90731123ccd8bb5b7550b8ba901f3e94958acb3e9583067cdaf68cd913726817755888db2a7a28e1a4748b9ede248fe0ef76aa51bf8e5eaca3049ac9dd7984241212bdbe5b3d0d4b586a7f468056893fbdde4c94203e8ff8238fa1a028ab2b059669f73b36030f5205fcc5958017fd26f9fa8d827b6cf11aee31fa922e8f0c21c5cccf059ac7d29e54a4df6f1e43b8a4b22689859e8569dc98990b9fd1d1b2222e19e76cbb31fff18fcf40798cf42482bc063795fa19dfe65eb6e9a570b4c41e85f9c94ff56701adabc0cdb76def2f5770270aa236e1be1c18ed64e51cdc911a1133e096a0272e0675c680fe24f2cb4f9a201401977945b920b02e60c84f3309e8ba8688c6e982bc9357327d438c5d34986a3ee5c88fc5886a4c66f1d14ef625d0aa01c82cf320cb1543887eea14b4481733f213beaef47ad92251eb2910bb1c23b4c930200102e6ec848b5470cc88a0204f6d4a9aaa1cb29e808e3cf2cc7622ea3e6a331b26e1d2a78f90b99066780df63afffc89bb080ef954828fc64a9b0e589c3d02f1f8f8c03919178dcd7138e1381f54749a684c6c7f852b0e85251427b6dad8334cd11f9f2e16ab2d7654d1dad887e5dce9d872887c6dc9d07f45481835c2ae47a1c0c9b680a009ce8218506f77c3b8b62654b8fb93043f60dca8992c4ca79d52dc8431a240cc5d01a027438fa19c91f638b7cddd6db1a1f6faedbe1c7eda2cda8637e7e0a2f49d2ad0109f7a5bbbadf6c8478ba78e716fab26944e182e437f00afe8873f1030439bfed6f6bb3abc39bd1882eb2b6eda0078c680e924d942cd5b55449783c3a8f192e24aaa6c305167959fe1cf58e9065a7784325c2d0fe06c3e064f99ebc1570a82cd43c33ea443971e0f434ac11883fe84461b9821746609c618a3362bf051334253a22ae38e9b6773a528204c0797297835f3f61549c8cd8ad16bb415ada181c52d843d558dea5cd548c3823ac4e3d6df1838e0073102582f62d7dc0ac66710e9d0e8826ef77755403b7f12a2863faac6dfe4cb1914e29db1b956406e9f46ba2653617ac8ede05dfb69035dca3ee5c2d00d3a612ec25b4fe71e06659ef23bb53a839b6ee48c4e38207109e68d3e073fef16eb062dcc3a22a15afb381581cd7e9db2c78f2b801ef7104a5ffb41dce92caeebf6141190682aae5ce74e6b6adc7c901eb6db76c548746b9170a1c81930149032b19c0c0ab947223f7d82d1f7fe5930eb75cb6dd0bf5394a906376146da02731747ba17ee40b5061140ddbffbf7b01d0e6661cb6d3cca9eeca0a0c4640c5d61c72d9819f1b54c8878b1cacc853f1ca2e3ef455bd082bf5bf60e4b13ba7569e7804d5b1442193595af32b92e91b90c7f7c9999f7c665a9c7a7f5911d73d415c3339c6f0a968a68b6475c1dabe40dd46087630e1fabf2155f2017e4fb42180a3319e7d7063c027b22b6b8389f83c9aba5a25fcb0cee256c1c16760db9bdec0c82d90800249d026ad7e4fa1f8635c4ee66ac2ecc8ac01ec76d44981128e4000cd5a529b4011b6145ece1a1d5404a453d8f28fb6ecedf4584fc8a952cb6f9d6df93cafcd21eac2a8b63973d1643a07daf8ac82dd5b054c0d25445e09978693ac63ee2de6516fc2b9c0d2c59aa561b6029edfe22e85ec79edb34bdc7617ba11cf3d4c0f02b13c2eeb3c0faa2fd0592f8303ed4bac9e9f81e7c627493f4a334c539b8acd96f02bc66d56f149f0139979ef02b7f584ae703925e664182e410729af2b9675cb406169d27e032bfcc6e540bd4b7b1b11054f83ac31d5c5013e0ac3f6d6e6a97ec1b08b22c0d8fcec02e23c3d2f56227fdf155a9a7c363854deaecc5321bc94fc52e50df9ac72c04b4fb74cbf7cd86c427f9049ea0123dbabed674a4e2de9652290ddbf03a1835d5a92ae4ef3237137432ccc8146c33fbd50155eb4e68cabd0208196843c201f2ed0ff53d389b7845fe62eb1e873c6f5c9c1216ad8ffdfeadfb1718e74c50fe500225ee24b08374d2a8b7fc17d324f50220961759194b39f844b12739e80621a5960316675859bed49ede417bf5a5acc2e4b364b70bb92683986c1df944a9a3b8cc87e3951e156af6abca648b28be2b74e6df59df0801edc236b129ba40af8c1c9f93b26fd9a45d102fa7bf90e7f51f14dd59d241c4327642134210376431209d2593785a6a4a6f042505387ab87daf614bbafce0a71426a7e26d2ebe8f7a36e23272d68e4396afe0eb899fe01103e5190ad987834ca9971bed9c1030fa67d27207d4a97e2583383f5904f0a0ef868a6b8a0a2c85fe1c9554e620130e6c08293a578b5a28ea7c0021ceb00c5e4e171a08f2097216d3dced274a6407868f61297f9fe9e95cfa52375e1390c2a034d849bbce454638828ee58aec0b0e171dadb3c2ba34e649b6df427a1a22ec81e2406de5d9d3db670db9198fc1070ef752419ede5f9973c2105bfba9ccb21d5e02ea1e13024a8072d8d2816018970bb8e226425c4c82771c7400941b55dac1a82c6ee13100d8bda00bab5a6d4e0111f101af580b036e177b7e88d70ebf1f57d3d9869f488de7ef2e41923a71cda5153c0f99aa741088d700453e078bda0ac7cf72c4d40e5755f51e9f972d5193161ffbef1f56c0eaf0507bfe67e000aa14c77e2fc597669522fd7553bc3a340e622190378956119d6213836b644a25648d9b3463ff256fa07f431fb1254f38a2540d7d8d1ba4d4000d5470105399683fa97f32adc17549946b7d4e33a06085ea451bb9b0d600fe3202fa84f96bbe9895918438d9d23440f5d086cb4624eefc7a2c09554cefe010fc8412f7dea624ecba0b778302ee742b84e396dc43d3c76eb2b10567ee21da53b51452ef279344c3f4cf1797576436ef727f496641913bc0f28b2dd03f71184034d502788de0d7d8caa15ab98c454d2676e297017823c35c061419bd9a63ba9deda91b4a7f5cc27883af1ce981a40998cb00af959ef782a4971b2bdfd91e38d7045ff5b399c5c097e014ee9959edff45d11affda024527b1c03417b6609dd14487de0f2ab328f2c7066e2fe3d18fdad528fa097746a24139bfcd1361368052ae8ebd22969612d971a162c5cd161da46aefa32d4b540937b80ee404eae6eb13a39ce56f8fff92b54da51403fdfcf7946dd8a43ce26cdccee842af2f6eb15827f305af101464d910fb943488e0e5ba33853c6206eddceb9e2575bf15ab59f5b519e3023a368f7c1584b1f9e4e185f05cdf6b4ae976f075d4db94882711c2ab8e50b028f8f181b95604247e18cefb32c187176e0c4264b9d9e78f7c053277dd97cae1eb03dcf68ccb9c14d6f77256486d60a6ef3c8dfc54254ae5d317284ed44a8c2ef6ddf4aec97a529d841a43fdf3bff0d07776383574af343a6b2504328a61ae7607b1e792ad94fd63e0f5f7a714febd8866ecf4e93be767a16f2c6a4302ed3c88f3e59bf92c5343617ad9051655cd702ff03e0a52af7f0759fa18826dd0d6c0d6b9b58a943c485c911cc2e83d683725ff800e4f44dea9e5747c064f56dec7c38e976a8667949d972a1e8d5cf265e4f07d86e2bd4c2706fea5e50780f6bbcf004fad574131b2a5d060402b25a79ba39adebc44adec286e2641d02c06eb8264faccb1c5ba4cfe130df3ea472e3ad9df249f14eb4db5f2a7b1bc271d67455ab068c58b17a0eb2445f60d9788b899e3779594819895fadc61cc2e080daff29cee7c04c152928572b235c790f229121bf087c155efff507d086f273f11769248554252c8d5972cc79eb93724ca839565986fd0d23149a7d428b2eb18206374aaf52de2629a8215536912ce04303d8308cbe65b8b76a963b097519a531615325c2fd7a1cdd84daeaea5f0951ba4421342db3b0225bd35b659e31cff10180bd6dc65a34a851c7c9d943c9a600c76aa179626a52d8e9f77fb03b5f03100037dc56ffa38081b2a6db99e9299075f3b2c4cf6039d9586cbf123bb759bdb130475385704108ec22012b4742792a05037da6aaa56e84da60c467ea7d3a908e81d7ecf0f95150be7f4d5dec9a1dd9dc832495542d1c376395c5e7aa334e020a21b28b9245119102fd119e81c340311a9ae3749ba3384ba0f1204f6293e3937dc0eeb2fd7a2ac724da6224dfd2dbec16d3a3af4c70ef9ffc653a52eab8d1693a61bf5633124ef3a8eec373e13373abc59d5993e616593eba7dbb5e248ff802881102c6eb060d5d2b8968e9eef372763ca5183b873e5a581e9e865f47b6028bff71c19cd3c08fd68a23f0d9c99aab607387b9c6ec678f9455616311768fa832a5204da68b4a1d18935ff4523e6cf72b1850132058c7f150c2e126196b6723f19ad2fb8db2bfb259f034348221b3d3f87b85780619a6d54e67cf0a55965862b7fe52e23144adc595bc2be1a48f1c1cc41b41dd9da0dbe5adef141730e340d04585616328ade11c06b5003e195f1e3dab9003fa8013ffd3f7e6a67c1f51ebf65dad418a861e2f11f2ffe125ce67efb0eb74f33bd131b5a5d11b6446a8b3fa207ed8b2285a3475847e33e625ed4e7d6533778b595aff6607586bb0412d8210fe340552e3583fceba101476b4fd039726118ac87f80df3cba443836dc2a53fd6fcd34e0e18d5690c79a9e9db8026bb60f070b81acd43c1e5f7030ea7dd2d61bff42ea430279ed1125758d018a344fb17c2592a3d2c34594303a65937825b43c263ceff01c029ef10cc78125dd9f4a55a19c460e1ad391a367f976c8d14a2fb91320efe28825a32c3b76a082a9e42428bac2e25c4892681860db150836148b3b1fdb13d1f64fd78bb318ce7387682b34c821bedafa127f2556a9c2687178ebe195756f609fe81400fb471b4fb1d59f727b378ed82d87dcd5d496097eb293d973564d398058ff3208fb5c9cd219328dff54018be2374f4a66fa489fcdff636810ec5288a0f1428e907d19a12444d9075431e049e594078e1d039e1260075278fb374a93e0105ee257808016fb5c76dee7c048012653bed21b536bffc786e8a1d77a2b8290b41964caad2025868bca96f50308b0e8d7a814ec83b900c8f77583e86bae18a18d2d335215664076fbe4a32999c11aad848aaa1df092c39ba98380a3439943e1ee02ed6a5098b95951eb7e0447b7df1eef98bc02b65dfe974bb92a4ffccc41c2983166df1755e1dfbd5545f0d62e8a27daaead2c734a6e61a196f7c253b967c1528ef00362014c7cae847514cfffb599397f6fe6c6ee72025414d2908b47de40a84cb4e3c3424ba0329707761ff4b3262835631ea1a3e164fedf5077ad2ad20039921b628ef95d8480eb14371130e00af763739537e2d02d6f125589f25eb850ec1140ed345fc070944b3846169aaf337e145e157dba7bb5cc8ae1919e050e01864dcdeb4f64782d440a6e643bd1f58b00fa425237d8a1f8b9a014d7198127601a587ed01e73a590f2bb886b1526b9aa2f577b51ab869e9e11fb795efaaa6c31762c2ab563613d28bfb2c3d59f769eb526bff8eb35ce7a97fb655447093663f1d1095d270f54f28866027ea95f63a6e5715618c99e7e08f17948a1e8c65d0f223eb8346f3a9ca6c43ab9669df0c286376cb610b5a073c5371c2c168935bc1a82162a0e476196e2da58d90892d41a9a9ba1d51aea5d2e8fe1d3554036501ad561776fe8203c0febc1bc49c023b4f2095f7ab99dc9fa4a09c70050ea6c1a6f93d04e66dace55265374deb889c25cf2a56f3cd964ae8d3ac45ee95781743bf701a13b4cb3c6948375a09050916d900fb3d0811a077bf61fad07727b53c2564dfe216679c8ff255da315e1e475b866a908dbbbd515d620c7182b849e8863869ddd808902283f89ce762a42304280edf68f9a76b67fcb61a7a54cda8575384ef380b24d73b1e75b50a6174ae6ab664e0a75f91d4acd60402170a2bf967c9862f0ae40ea80f4d02e46dfc9d22f4c5d3358a3a741b39930b017558af7a8c9e268f37a00cd48b6a5afe6dc0785efacd85eacbf38ff3691f503bd723796d7a2b7a5505471c0a5dfa4b6eec5f56d4b7e4805da697d7a7e2878d717e21d742f9699ac0aa802f8b8c774afd950836e8ec22a520412abd775c4619aafa9dd53a9dba31f385d121f23710baecf82aadad99712d54fbbff07e19d618663216ebf13dd355389ed70ab297bb2e8f14c44d9db5aed00f4272956f940c814e02c329cac3b33e110f7b260c8b643c9225c725f638d415096330c953d46a6e6901548de47f050cea00921c406ed69b8affa8c49e5126b09b7407f1fe39e6c3a67ff985f44b4068d17ca2211a8e6004ac2ce57b738ea79b47a79212fe05f59fc333dfea5b973e0189f8711d2ac25b7da815377b5e0b79bb57edfeb0b3e249284b093f937eb3c8cd5dfc470e799e62210ee5038ca82113eb298d0a91ed7265809b0e3c41842327227bca7e179281876a2d730f88bfcde6a261d12b63b325fc4b8f8a07deaab29e073e24612e721bd4dfbc7a76064f51b97cb8c9aadaebc2219602c4018e412558f0c92cf50f0300b41c3af93217af662fae6c20aba5c5de25678a70e7548eed1465315e04260f3dcd91a642d67ec3157acf46ef336e01231612fd33a33d547b352838ff602202827e24bf1d82e874c4b2e56d6da2211d4f7ca4affadd0e17c9939bae8c861988b22b4b7bb9ef9dffa40b919b3a3182f30d07eb113eb168bd5c30bd8b206a032495cd76b9b5ded766b724b3e8a955b114b6bc8eb936462efea06162c87c2c1caaf7adc04449a6a314f788d3f2e7ad03a89388119434eb73467f6a22898b762192c947c632f83b1d839ac813849f7f22884a21461081a6d636bc2c044241732a226e71541009557abe207a50bb07ee6e5318c4ee2f10bb0bcda8e4fe00e6b71fc41469002dd8f72c043824f87eeaab33b31ac8effef573e9f15bb24f1af840107e0034eaaa8cce6143056e561c708175ebd2bd2b01f7204024529b36328ec107e1079b23231ca0576310db1dcddae6dfb2272b968d23ce655bfaa3b5b578bb051aa676102be135cff656a57bf369ca177e279e14f723c6d567cfa0cce54170301665691ed411acc68341b6e22d99e80c111504fb6e8fa565540666a6c139f21693e4c8d39fee103747a085926e9c36d672e0950b53e0168b556f7cb1a672ec12a0aa0eab6371061b8532a895927a22ff8cd0d1b0f4c4daa831cfdb62551d422abedad3879ba0e5d639f4ea58196f23087af2ffd496a7572303590001f57c652e0d004ca35307c2f8c99a335d6378a3770e5dea4aeea8e5a4493369f406fbdd1bb85993f3834486eb72a18278e27c76aa92986a4b9285143493f120104d628016e1f540e94796eb5b0014ee099328f84ceb614add86ccfbc550f7600f3413651c6d6c29222e50e8a15edef04969562fdbee5ffa843960d92d565d380cbe1def21d8212fb0ef618b09a78a0d3030ea274197521f239b7b82874d575222ec0ba81ee82dca840e340012136ef0b243eba0e650058aac4a5fc88ad5327ad848ecc710d71beeb1dfa88fb932d6125e181271335a9083d7fc6e13cdb92d1ea5b3d60912591a5d8eab8b8db19ca4336fc32c3147ffe8088684fdcaebf5f634cf5e1eab1b68a4d96dbdaa0afd40748e0b4a0ebfba0a627f30c9dbc621e727f7bef5e78e245f34dcd0a1828753e5723eaa14bb4313dbe15d5e76965f8bb765910f417ae403a931a5b653d4fbe31332fd04fc6e69626fb834cda6fe48674b98219ec25e212df043b86786dd8b06d34b0bb7e6cf4c5bbaa01158fc330b05fcee8b4fb9eed20ead836e6b8cdbc6cbc06457ac64cf3a72283181e35a9657ba381ed47169ef3f178a2f40907c36a2de63a99c8cbe92a23d9b10305c3003f5341ef1f9bdef0a99000586c10ea5861a049a13f7c69b0bf6526387aedb3952554218cb5ae0266b3d17107b45cca47a5078acf00a36247bd987db1d331c585953c27b3e7b68e34c5c086f1e38aef9ef67f6bd98ba574b8534c2f71e4ec038565f0b24c6faeeff168926ae5209a04acf180a8c7481af21deeb7a02886f61625e734604feae11bb965306c08ab20127db181eb638f57097f85600f251529faea4299afb46dc539ed447212bbf694211232606e3fc74627321d1188ba6d02f9e8269dd81843182e41575113b3b7b2c3b1a8698546d3aec50985c37a3184edcc69efc421fd3e4f939fde4182255831a27d9b5d835ed40def306d138225b855aa0b81e5707438d4cf7408725dd70cb357f50ec938767a6216c3c45ef2034d3fbc3c8555a67b7dc78b47d8628fd188cef3d2b8dfbf4fc38ef79f480b2efd8c4adfd46fb6205e251212ebaf31e70b2d8a82ef799db3afddc46ae635734ac0c700fe84891c053e63156981b0b0fdba632fd2f3c239ee4bd04254130f5d66e68515143c5f4d6f2b29e17bcb1a303aa93928c09c5312a4d16946121da973879c2af82cf71b14a2ecbeda0e5ec8b02462777d72e300a2f695fe1e4440becc12fea0e2ca14ff1862931e8175d31cb1c9f8844549a6ea22385d3a4f60cd14fd6425aec8890bde9221d42f60e54bca41eea53a6a00c6fe7b66f129dec025d3c05b1a7661322b803efc62b123918b9700799cf50fecd11f0787f2807bf01fbec1f9774eb693afa70d652dd59d292b74809f0b45fd23a36228017f8cfaffd39368d2317dfa86d5eeefabb69e13c7d7ca5128829e70548ddef6f0d1230f3674f752890c754e20a858ff699eb425595132818423036c330b0a4c86f547594d8e34b5abacc9933308d03ff4b5307c9f44b721d9e1d6655d4140a8adca0117a6ac07565e7e8887975eb3965583949cd93c18900bb301068bcbc64aa85a14a8ef8365ea3f57bbe465f80ed8c039a04a7c9e5da0e09ec9c44885c8ab72021e4f8f6c388240c577957dbdd7f64e929aa54c2960a071e8b4cd84f4f659b95605e75c42ca42547f2462b36f75b57972e6f9859d45f067723d028b166e84ad2a5d9921bf762376c3e90ae6b17bd87c27e0fc007a77d1f5f7d8b0028999ef82f084a250d8562793aa0ed27644ad82feb94e80d948a6f09feb51fd95f0632eb2b356c130b50c4f70fb0f967cb7eeddb222c546a5efb49050476a0d41bb023dc5d85b1cd7776f9a2c3c792be49704ef8e0bb09b9e6913728a0b8490ce3a1277aaa62aab1f07ebb41c1f395c34eb9e983884e8dd953bf4a0f0e353000cb746ce229ae769ee10c47f15ec40591d589d798d0c2bd2655751106774bd58d59720491a086b4721fe745209895969578d037e71ae982f8a9320322a859297e7a85a2002ebe2e883aaad92af39668cd0798c08b7eddd7d503b24b1ae2daa5c4eb25393ee6ebf4008bc4e0c072ca90b67a65c586fcd5550b29423f093d0da983505afaafb1eb0771e8e9e1cb3539fbe61f5efca2d4860b1fa1b36121e5effbfaf7611b946208ea448d990b3cfdaf50b40063af0b7cccab49f5c86b16506192e554f89afa326ed0528f6aa248eba2da1825d58628355393113a8fee286a02b1c4a452f8f15011bf27dfa4fd6832f09725a7219294e11954b957f9221166c24763a83391287fc3eefe14933c5c14f4c7d6937f7b75542347d04045a110890ee0f78b861b3af29a624e25b367017d565f468cddce5b7f0cf3c35939a710bf47754178cfcde50bc00ad8afdeb5f65ac80bf3130f8f916859fdd0d676b51a19030af15d64ddc9aefd991cd5cfa036cb80826b4373b9d7bcc892d88b7dc91054be1686426a50d43560b6f5a738e11ac395dab9fe8c808f8f8ceef391350406b72a33744c6e8340275bc6ba889bb2a39e4e44a5ec3608ba7e9ff3169958a41fdf27650f39023fd280fbcd8a14f01e01129e55d1f39690748e99810326fdcd20e052a932671c905b1eaa5c122a28ec8ee55385d4230903c923a10347dfdee01e17b2763b6a7060a5b8096bdf84673c406e1bbeb5fba30c109497c0aa3ce4d91814c363d790b240b21d0c46bca0a903c5fee1e5fd6e2278a36d7209bff11e701244171b2ba258a8c4b611fe9d842c33b90dc2bb751a4c9834b94ee633ff2f0c17e99d90e05e03e67dcc81f0482fe23b3edcf8af33abbd48817fcd2f01e5cbad02174e2613f854965fff32fcfe1b2ceb878c5e8451dd0aa5d75a96db1423038d224a2a1f5665b42ccf0cd2009d22d026f92aed1329fa0eeeac0bd789e8a094c82617ebca343afad708cbf7746a1a7b486be884219e41fc54bc92afa7c4fde27204e3b778f1434022e9a0f5af3cb796f94594c41fe3d1343ce8e95cfa3405e76024841490ba15b8d6e571c78b5fa9bdb4f42cf6939f0ca766f8a33f9af1388e9f0cb4e92a32b3f70b729d395a955e2080b6f0ef0d26e8692148295a7b56b5f6a31596ef09d919d4e9ff98704206e61a8dc0a9ce4662eaf6a10878f3180ecd6bcb0093e2dacd06fe78b044dd4e2f973281e38c793a05bc453015dd5d99c1adfa70234a32f957d93338fde57563ebaf78674ac0ecfd3bfe0a8293a8222791613d2c2ffeacc050d243fae78fecd4172ef8ac8d65605f37137ac2d95706f7fd8f331204bbed683e9949fba2e4bf9941b4939ee707c3973843138bebfee49358309dd60265751d08c2e979f56c6bd140921e7a66e34962c2e608d7326c40f95b797636285580e22fa6e96ffbdfa09b8be7d9c5def6bb69b24b832097fc8501a8ca707c0b7f05f0505eb62b7964b96d0c4913735b728fa4baf217082e8f47e2f582872412c7a05dcc806ce1d8cddcca1d989321c22e660aeba3d8945d7f932b6de9e6591b97a10e4e7f2ac05c0135756d3e162058d1b9e577760bfa12f779dc1b21c04300b8aa9e06aa51ffdcd11ff50c67a307276719bc15611fd86c8098faf7c829da2c4b1f4eb53f6fb595e1961d38512f3ce9827b9e4822b90fe6e5c0c52672cc1d012e591b62f714b671321c5ce756f826cdc2bd630a9a79272f7aa02baf56779d25d42ac69b671532b1d51d23e7c79160bc322015ca838b4e674eea5167aba83c218ea51067f7176b027556fd11238b4bcf8865d89a9cd0bb3e4f43477398ccf22aa043b2ff7867dea2472de15e42e20bfccd0fd02248e6f1ebf7f95edc2eb2312c0a6b7ad4f50c3bf03555011fdf65cd0e2fa85d3bb7df6dd924e7bb5794985118a1d10561c8f03828a912b04d1e50f8bde69235134a4d4ae2da48c118a5dce12e703a9115055cdecba78a75a6d10a5e56613e9dc3efd226cd0756e592f880642c9974ff67e8a91633f52d02e73ef44399b35cab4796c37156f0f9800b7a88660345dcbf63e44f1fa2d1f8eab547a67f70db529978f40217b5422eed2588a4ee300457f11907f9415e349dad8cb86d9910eebe588cc8c0cc798a522e39a669031bcc7172286c9537143a92c965481a89f3c4e860d5ca9824175d9c7a597ee7c61c115ec99fde4909f191e31613746673c5507ab6e01436e6fe5f07d8a929fef51ff7676cbb3def22e44a545acbb9aaee1773f706fc8684a7b465d2f92f8af7dc0a1800216db2c08004b42287c6df656f6b5dedaae8e1b9013c94532463df05952bbf330909de4d033727d32480cae73d2a2e9e50326fc605ae30c0c9f011128b1a678d3619cafef8cf5d5e07d61a849c05e91e9ce8290b8e0ee69c705736ed81117bbbb0fad9bfc93fbeda8ec8b9464853ee161b5fa9b5e954c36d10f7d2e01d0837f15100dc35eb17b2dad7ccd87b482048827c1716d510244380ac5b0934e3124b0552ca7a5902213329c982bf38782b0aa337a618d658aec9d01e4885977f1514eb3c815c8ac482050a2d19638a584180f196c16339e4652b1b7f1ad870891d63a0420da9390f9dc04588fdfb066906fbeda08ee28cf7f06541519f991aa7125c2099036a614739e41d2ee4266b3faec273304a8a7fb09758a64cdae16d281d06427553cb1acf30f1603889e575889f826a832acc44180f68c230647d971413a392f060a527885509f15ad448f8aece5aadc9836862138a8b6d3b52c33dd41faa36de1e5f4355825cc13a32d55f9d84a7337b691d12ab95d7eddcdd3f72a22ee84a7b8932c0aec98b47176220beadc273414c3a7d739e598b932603544fab03f191cf63a65ae49a832011f34c94d75bb99361b17399b27d77231128adfb33018fd3f19e9f95a38b4f4296e1b8ac28f6ee41814be442b889ffd99b621ce5bf1bf69588a55456a7f9911222a4825f68d22106aaf2ee07891bbcae65d952e75b2ce90f558af3f890bff0115d005d1e5f714935cb35aa8e12c3b0f194f53ba20427e5d13527c1a9f7563f61ae1f59a6dc16f2cca1df47ba4d47ad490a54d1a9af10e1bfddf43ad707f810b5b9b48a91b16d892c73403c3f5cd6670bf79e355e1d1cb721ea112226ce6a6d52283c887da649f153a7790ec04f440176987419b5421b7c694c646cbc5618e0f2e9d9ca5a10be1c9e007d519aebc3fcaa904cf4028d0f15c92504ec8655c6f5ec0bdac134b4194ab85c505cca657e295d2041c68be114b83a369cc7707cd41264238945dcc4d2581939579ebdc673ae8a5ec925776e28341d66f9f6eae02473c10b21c2f682ba22fd78f1b25895ac2adad8511422110bdfcc50e8b7e10c22d1061ca72d0945d2ae76eb874cca31ae41ce92e335e6732e0ecb8257b64e85774c95c601b69ccdd6cbdb5bce2bdb755e0f4309e735725f", + "public_inputs_hex": "0x2138b0022ab9af3c96b082bbf307bc9e79f8f1401462e3ac1cb3a9913a5b856c18c40bec999a837ec1f06dcee05102acdef50c501e771cef739dfd0a4cac5e94000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7011521e0a601b59f0fa9d199e9f861874db5d701a0c38f6d725d9fd8c1f0b53da03219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218625eaefc46d4dc1d14d29441b83268d90e246af546b51272b038fd206edb2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7296995105557a58df75d3a42759d29e124a15ef43bad6b7fd6a9d93d4efda1c900382d23bccbad9ba827179293d23b719de8374589fcad5bc6d2148bc787593a" + }, + "decryption_aggregator": { + "proof_hex": "0x00000000000000000000000000000000000000000000000dfa79688268e94f45000000000000000000000000000000000000000000000003b27d8c4969fe006f000000000000000000000000000000000000000000000008596197ae31284d9a00000000000000000000000000000000000000000000000000025071b1b78e460000000000000000000000000000000000000000000000049f29ba73988453810000000000000000000000000000000000000000000000037166cb36624c1ddc000000000000000000000000000000000000000000000007d050eee5ee699fe8000000000000000000000000000000000000000000000000000258bb7095c7a3000000000000000000000000000000000000000000000005704f0d79a04cd41f000000000000000000000000000000000000000000000001cc8608e7634392ef00000000000000000000000000000000000000000000000af88bb11f4b13a3c200000000000000000000000000000000000000000000000000029db74f7fe7cd00000000000000000000000000000000000000000000000f4a5900047ae9ba6400000000000000000000000000000000000000000000000a2f7b686593ac5c9b000000000000000000000000000000000000000000000006e5e184d039f43481000000000000000000000000000000000000000000000000000265f972d900ce28738b09735682ead7a4c64799135201b3899d799236623c3b56cde6eeffc14c0df0717f0a39df3d76c516e8bf543821b9f4ba63b14188d420b92f5ed32350042061c4c31ac25d95dc3913a7a4720dcbd0d2b502eea4245f0e8e0b648eb3664f0ffcf0587456eae3287e653a00e8edaaebecd3e65d8ec98782517ef25ca5f5ed17e994084f3bba80177c052107cd4673933d4d7d498712c3c1a765d4ddd106cf23121b833a7165f5c9a7cbae738a5033ca28022a37b8399326468eccd785a1650e921736cbaea5f086a1fc0b8d34c9b3cf259d4260e3a0fb734e9ba562371b5d22be915dc76a01693899c6a34254a2ee1d2034d4b4afb734de2afae62fe3949727c3b05c1e3ca04b6abb43df9172b580ce32a1ea52c6a13bdabefe41b291b61b0acf905985d7fe37c2a12230fc1fe3c698d1495d937e0315f8ebc4f08b81f07b054fd658b021f59f1486e8105180cf9ea58448782cea621e76ef6e2b502df53c097f54506c667839a3fd6816ce0201339146d1334deb91f8ea6a14405ad6153a182d352d88c84c0f0d3446535350ae13ab7965e65605009887d7909a2fa1d42e2896551a0829706edd47b1b5786e28188506120cab5c15268750c76c2282e001032b6979a88d90b20a1db9d030107ffc0677ebcb6777c7f4ca2ee0510182362e2657252207babe037b83a8d8b3dc52cc67e771540a593d889433e9cb38eec2d71d52810b29a729959f506e4ee054bd6382f9acfcfa7c288777d3a5f4797e9342229726d66b20423a7f33a255cc294690bea014d9afb0331f91401058a271c34d2ab341191877abb7207f8754970389d7dfcfa00ec4ffaaeb0524dd716cfe7cb11e9223897133507d5227ce3ce11671f837ab1ef85d0aa6e308de0ecae5e49f712bf468ea81ea81e5527ee9e0f1a6128b1d1d32c56b82e3da07269e74c46c9978078a4fc2c3ec815158339b79250151302bb388375cdeada8e2669ddf041f19621eabb305f4d3270b826fa6ed2f25db9ffe39fc47e81839abfbecd91abc210133053d60869e919a115fda8d5046e59bfb2f874261d17b698de9e524a7145be6c521e3e2c29389e805e67940c921c0dd97b619b10e3d3e1822e3b2906d448ec85a031c38b5d1f34c2d4b5b7d5b6360c16fc3f097a28fc83c272b1fce5a6398bbe20a3997e59fc3a0e2317de98fdb917166780523993068ec1cdcd514df1fe9083f1991ee90b63c34c18b2639cc3c3df351ba4b8ee53f5663219c845085116bb81c1639cac4dda73a16cc4d7f9e8e607200c85a8e0fad44becf3891ffe93aa770132a39310b85cbbff14f0bce323cc23f445f6a258707355b3779232a642eff4b1a09e4b99928bfd02b699bf248fd01e881d98aef5772a6043cd5619e1a61af8b3303c7e35dd434b2854019587951ffb7e885f616ef360789979c7851ff5bb479421f42bb812a236b6fca6f7ded6823a28d36810b5eac6732fc2ad4410f715951cb2b5e09eda26e7793afd5c7c865de1570c4e72d9a88ce4b31a88264717a070d802a817a31b2c84d4c1f13a918c3a73c88d8a67f6c81fcf41ecd278894e88485c5062a3ef24ec877338c2cbafd1e61205fa95e2b93c59326cbf8f6468453a1e85e054db79eff791b9a1cb823dd9566f06129dce2b1f1c15e9c6d878629d40f61512eced624da055ff54fd71cf3520e5a759b33d31ce3d711c6e1163e3645a725960c4b1b6a5254cb9b135176e02075b45e9e1ea54e21b1a420b1414abc132d02be133cc2dfd9cdbf2a0a44fd11b51779483b4052c658b345b31ba93b918522167102cd4824015fe51e5b84a6fb335ac4842f9ed11d6f5e69b4d8dd8ba64e0f36270f78b42c71621f1501e1ba49fa4e661de16cb8dd3c698093969b8964809106412790264f0ae9b8007b76649a949b69ac1d6ec2a955902ececb7d33336b485a7c2c3c6a1fadf0fd121f79fface6cdf947dae0f776d069829fa900f514ece4141616bbbedf7de53e30cdfab6d5619028b321d44e93184fdf01e7ab3f5a4424386c23b8e5447413e6639c215e2f7bacbbe08458fe90fcff82f4dc73b1b9fa944e91108a5c28ea9df2a9e1b17874a186d1d5301848073af15ed52a4836a71b9576fb284357773419bdaa332b8130670664dea49b96012f02b091e273421d579b8b7c0db2b2715658dfaf910c32aab84a6eb1daa3f8c4c72cd2b43abc44cdb4aa8a0b0dc67c649a6c3b9cdcbea178401c0abcb272d8d5240a492956cdb2e4a3de78841ec42a7c9a5ab3b10d4264cf887b1c81451ebfb5e4277942e5736a7049bc071c168f11d6111ca6731a245c4f6f0aa9acba6d334d552193f8453f06e454c0f1b30e3264e919b2c667507684454b0045f26da17f27caf045c7b4d2f6be92bfa160277b4cf55287f67b9560a68e53fde3b7b85ee9043123cd7039658e7f874c136d1a2c26f2deaf00a930cd611ae4ca28ec30d65792e9493c2175e557b21e31a5102a8f42f94c87e31eb528d7a5fd4ca83ac3a1b62ed65113bf25e5e0a82dd2cae52cba89c170eaf2134fd4b818630ab330f68c040bca7285e619b2d493d713fbfe079f72b0b80fe7f56ea6eb5b20bf7990fa72a7f26191f159a2eb29d01801330d26bad38bdbd921c0e68d44a56c432329d5477f1e52f1d720e9dfb09f24fcc2f610e4303caced66f68ebcb8d876ec6f7c1904ab11800505a020eb41124069deb92d748417971506e406a675a65eebf63796897742b6080c037c097e742a446ed528783529668433efa5bade2e3f9052c11418f54b8bac5ae047f5fd30ba9e031f2bf38e36125c725b69365847ab2eaffb80c917ac7d3a97a47c1a1a9950db209d0326fe9bb980be5ef2bf21a3e85f236f53aa3843581e6e49d3b4451db82ff50218cdf7411b81f746a1086be6f27cffbf9f2352b4fca25777ae421cb673afe74d276522587e772895b53893a247b5bfb427dacfe13c2992700becb2313d3dc00f1876d430708da7298c907dff0b5984eafba5b26cd6fdfd59363b0bc511769da02db19b422e86e8e4003ad6554001fd10fd87d5f32af8a9d13f23bbe12525038a1a7a3867ea9741941c29e3aaa8491855617b16f140ded2b19a0b03cc4a4cd74c20f4111cdff9aaca53255e23c1c6412be63bccc4930ef87a63fb8e59411f56d4214b5fdb1a07fb3d5e91b25b3df5df862ad9cd72d3a24325c122801358aa149d2c03a7e24a687a2135762b2c1108cf1432e73f5ebb8e20a552ad92a91dbb185f11f9ede94d1ecebb9b30bc4c1a7744e2d121a63bb8fb54c2a83dcb8bb61cd6b600571edfb0c5ae31403c4fdebd9bfba727fe0422077b4bc1b660ad5ec5db84b7279d5845420a92bc08b2e5698b81383cc1490904ea5f20406d04b670ac20b49919e8beffaf81535d507d4ca8b08778bb8b791d016fb0c935e0ad7f1c6146cc4a262ce42077ad7d82e2e3848618c2e9514a3422581329e323cfb5e6153a6131990a4326ca63611c14ab69058cdfe7289463baabde69bfb64c895637ad70f47acb101d099896c7ba7b7aaeb2292c376efdfe9278aeabc23363ec0d2c0fad2cf14325801e832e9d2edeffbe63a053f8d6ac11a13118adbe3cb26f66bdc367bdf2a11bf5271e7b3828c52104b02b5f157695823763e7093e3e9e680921cd0c3dce450f4251845969a5c04cfa21f68c982ad2303130bdb22134d6210746c76817e25a249c64fff8b9d2e3651db73d13eea4360f99ebea5b17fd312fee8b1117e4967004fcf53c8939497fd46ee37dc67a58480fa1d8f2cba62cd1a04755796bdb1dbd0625d390458c05bc57aa6cec0ecf86e5b90d7d7484ce043ba332d42367e4b5310c45f065d59ed77cdf230d709944f6dab4c7782c82a2ce64161caa970c2c071c11e59f3300de1c8e44688c10c9214d8ee5d1402f31710c6c033adcef7c521b550cfbf8b66cb58eaf5b4f600593e7a7337c5b37df382e5df9bb7da69acd0935db2f71443d93c858a05143b20f06298edcc053d6f52755f8791f02c80856e1f55b0eab451543b5001697d60235605a12ca6377956f5161eabb574ea08f2741d0501dc63400f0e57099a68241c1d29056336dd70b0ed371da2615573480f10f933212ec6e0b1f25cbfe5ab5958a232a3c6555bc5d9a88ca2a5433eeb71500a178dc1003e570f070517a79e4ad9d72892bf563aebc21f65a15617fba60ab62749c622bb9822e4621ceeae8fc692ec1384c31b3fa7f85ea545106bbd4f0c8b5b03a6a0f64ca4fc38aaf821910592887b951fe39a88fed773f3c32e9d3afc97ee079d406d44e6772130b54178d8e84cf33390e8b880c554746bf355472185cbff9ba4c218facbf53bb5db501c6c583ac7df90901c1a4c7bfad4dc5a1f811986294c3e30b018f42f8d486433a79cebc05ab5a4861a0a19f413346be6108d93bbb7ab24d0f1e374662c55fbd4000b52009915ae41ace2fd2798513822da5c47b69c627522fa60c93b96255feeb8fead0646f6c03c55bdf0ce8c90d8a4ced28275e6005101dff152a15dedc7a5077b8a6a24fb6ba47511dcf942b097d341439041c53dd82030dff114cb5c1acff5f422b9f9157306540025097b5ca9666848657a1bdd8ac035532d8747b5182f12d2d76caa80b6ef5f2c23ed91c230c03f3c38b667fe41f03c5292df7fcc0485405a81a40666c864a1c0bd0f9797d7f00211a2a4d7073be1a8cc3df21420e1ac68e87a2eb75b32473cae6554a8c5118662b250f3c8e00ae2e2973ca4bf0d376bfeeaabf8f7b5c4eb4761a0b51fc018d7a205f02979d60c2027172019511cbaf761d504bfb9dfc8e01e45cd38b4e10103c13b2146174d8fb073f021f5d8fb8369b690f7a5df4044a2acc9e308e6165e6f7f5ea5d0d5f695a201986328ac16e02384a0f49de5929baa1956458ee19a901e8fbe31ecfa803bd2954fe80592a60132ae23e7c8d4d79dca4d60db2dbfe343b01cbab95a814deef0d2f09686caba0a5e8714860f809bff73ea57ed27ff26c921247633ff0f53d010898444c0522085bf95583c6bc1ea11245794f6442c79c3467afd6de0e938b9905fee8793edd702dfee158d66580b78e7124a0aea44968f9ded2dd0500d8263218735ffa49cc44890afd2777727aa4f9895a7039122d6e333b3520dde3f6096c29ec16859e98a504c88d771cc47aec7ff40a9e4f201ca83dfc7574e01261a9ea214114b3db1469a1cf55002bbd38d0ea429b1e24004d7677a57f16b4b0cbc25803108c1d04f5c0c3ef669689f62188b71909f1c11d95d514ca3a78edc8a7976422a8c196a42444ac4076ff06e369f839e38244111f04d4f74cc3ca2d635bc3001c60ee36b09471a5ed2d5db3a067183c50ddd40f2d74469507e949541d101d7e16c41645a3fc37a00b4708cb588611fe15d807d9861ea110e6883f4df31cc8ec278d447019f5d65f772020851c65d6a10ea601c7c4bcf78e58fc905b2c664f0d2c457a65f6424d6739ccaefc361f1e700d1735c61328bc29e75cb0d76b1c013910c82a1c8b34214adff97e9d94943f069509a46742bcd835da11ebb9b440dd3624c70366a5708a3a10b9688401e4250bf48266aa77d0ec6e5403d5db41f718f30f947098f457716160288bdb4721cea1adc69d2745d7aefc57eafbd2e901013b2ccf7ff182845d214e0fbe248a08364934d0ff522a9fd3005df960972ab255052930025839cab3bfbb81d5127ddf6fa01a61a613a6e8f128a85004743292f3cd2c1792d9ba72f886ed7a121297461743136ce348913ca557297019e2a3aec0a51922836c33d87bb152b06b9b9f3bbd144c703eb94cdf020568660d841a255e5d276bde9c1bf661ff908ef89874dde149fc4dceb010e3a6a382e292716cb4b8d916263774fee4ab4ba83a3ebf0b1064ebd75b9ae887644471f86a6bf8221107cc078182f2a821d52e0cfec07bc6657e50526ef9fd0048ec552d0808a742742aa625f90291e0ca4e5a4bd0c2588f4f2072da4cbc09e48791ccc16cea22ca882cd00d0381fb3133577f3d82a0a0bdcb0db0e88fe939063377ee25026eaabd38be1902111b320f710bb3503857b61c13fed36475db6ed1080063626c619d22f9b0932aa34375d85de0439ab7c194f504bc2523abd9627a8eb0c3ddfd751df66f5c95293d54b5e457bb7a9f8362a8f0e2a8acc4586c5f9109067fce81c82242a2eb5f2558d88d1bb575b0651061ce1f9bc8c75a95c5f785ef7933948632c1cb5b43592f88a62189b6ddad9274e56b188dcf13db455a4801c175f2bf802dd46ce5aae405421fc32aa47ef04f6c1ae84584ad7f02e065e6a7cfe8d1854a0f5431c7dadb0437a9c689c31a4cea1d48dc8bc6b635382ab3f7dcab912b6169fa9550900047047ef7b1b8393d511c82c6551d90fecf2662f336597b24113124e3d13b21b27b05f81ed1c2b356defe173c7cb7e4a5d33e4dda4cf7020e7fb85bf2893696a1a3238660d480aafbb0c4271397203e1a80122314f7b9ad807960830b0cacf78e1b1d45f76d3dce3e1db3071e9055eddca41a84da428fd19241adbc656e5cf7255b0cf5ad55a164b6805f639c3f7202975845aaa64ec03b57fa721daf278099b20c04630ee5a1d2cf8aa318da7097dfc780e843e1e2b8d7a550db5cad5d2ad4cfbf2e115682cc648ca983330ffb7283318b6311873be9977637d3acc6b2eb932bd00f387b1c9aed7bf928c15e9af4b7c165e4b59cc38d8e190b8b3a81d1c6d9f83725e0695fb46317bebde0aebedd01b2ed491ce402d501aefc8f4c1c293705be6b000354686877258d5ec4bec33fe416c64ce5925bc9d9a537b439250967bf458702d23d65decbeb6752b51e297d25b2432a6f5b64c0773b205c4e1446b087a44324cce538d0ae9959129c92b2240f863c773941aa0d1c503d20b91f430a467b4f2bbe0a36f9facb42624703f09f4288e1c7b74a9cbc5b2bdaf212a49f219b618c2580560061039f9eb6c52b7688ff624844a0a4acda0f1db128eef1bd0259ac3c176b1db37e377cb9d25a85c75ba3643e894de5bd3e998a4160837cd75f1cdc723038cec04a4853a6ba6c62cd4918f1632ac30de6ed5c0f8b0a68398ee741e60f184ea704315635056068c59f3feb2e28bba86ca05e77abe071bf4d179a0e9e2d0d2bcc51f8249afca59bf04cfb916937a0183917178db300a3d477e6c83f018f0db99b774c888c7019932c91882095d48b2c84a5004642e7ab200a22e90de77515c4e35e9d6ec6d71aba421ab36b30e7328fa15dd936f1c740838181ff349e122ffeb6ee1157415c7f104ac0f38ed2cfad62acb25a58a89eea6a5f66b4bf392520de5b7a89e66f24a828b7141b01fa5c1067327831d040d0e7a07f565528f2ef250121b6f9948bb2f3f2cb4099853f11073ea5173ed10bf2cd22f90108fc7c4c231b03d6f484e3bf256fd3d4f82388d90090764a9b6eaf6cb2cc2806c5fff469294e11a6fafce22457c6817315bc429ad19853b7957af2af6c3389e10c5a105a2e8d982fe73afb4addc3aa9b344fabc343c6438c8a59098f5936add0947217cc2ab165ac1555e0264108944578a3738595d56b7e274644af28a52c992a33209c05dfa9b8864f3155f77a4b18eb1eb793f4721180a337c7fb5a0b499ea96afd5d00044ba5da625f9a36bc38107cbedf12e0a51a8a2f59f2096e0d20e065018da92bc0a7112a7e48a4444a728d936338120a122db00a096cb486e3b67164120ed11205e12b3245fff17ccc63ec28b2e2a1f3d2bc7c8e7403e0c9c5d5a1514a2b900797eb3f3ea1748dfe9e23cad65e839d8e3074d0fd24a1bec13252b57f821f9d068c1cc3c26382875bc0d27da9d3bed3fdfed96ce2b7ddd3446e35d91b31d301164e3aaaaa7534f8ad4eb17b0621e6e5c876d84fa1937a023d2c29e37bb14c9202c71cc7c96f699ecaacae99aa36e15dd8055793bc6276958cbcad551d2448d1199499f2720dc367e892cbec806b3c9459f49f22dfa2b990fc8282a4ce499ba20799ba426355a8ef8dd0fd899bcfc06372d212c6ac1f63c8bd5e6914b18cbcb61704504f2e1e2ed6d86e2da36bbac86aeca425a6720cb4facfb7fd429b85ad57032d86246b281117624b1b92e7da1c0d27bbbff6a32918fc2f5945cd0b4a0ae312ce4799fc5d07c7180005bab2956d23025adfa9e3e37b7a6166084eaec7740518fa072d7ef56b4c1f8aa21142872240e2dbebec78db08384dac3cf7c36628851830f724379349291aedfc0f9cf05c92d4af5be0a50f586929489f98bc520eb906de5f1f41ebe26c58492fcf53552fa0d1df87ab01ecf27efd93652d85bf06180c0bd83850c4ddf904a68bb0f3a24d6703fbb5e7e3e3d58561e1f21783729acc1c3d2d9b96213fba91b08d5a06eca9adb713d1636c1c20ee1c6ff40a786694870e24656dcaccb56da1ff15761c4128774105f4869db44cd54a07414e76bae9ab2bd6f76e121840d8e8f87364deaa979ff118965f2ccb1ef97b3e45187af7eee1034b6d88504c0eb3f27f35f0f36cced25475b2f62df8cceedd3f4a9c7808fe41219bca2c439d0b29739bea7622a1d7c44d8a1de6d59c63b7ab55283f5df05cb70692e71c660ed45d49f1fb0790bdf274bb6cfadb9fe7d0c436f8f784478cc8df189e594ea67b7432713bf22c1199d90e0043695858aa46cccc397e528741c6b52e19c9ff45986020241cec343c8d8f74989c21f2b86e94a704335942c967bc9c032ae6b105131dbd3e550889cd96d3577f80542ab10e53487ebad39ca428ecbb236b4ac29357495fdbcd24b194b37aef7798539cb7407fc2d16cc02647616fda1bcd71bbaf8633ca0fcd9bb267a051933c14313c8a09c665da7ab26b142e9d811d717384396cecc500f378df1db9683fda74d5bc2c4e78fa1a89f7cf4975ad69066156264ceee9b8b8926b5a7105c90889998882ac9420f532112a6f1f2f2b9c023a3ed64af572f19d017aa3ef6afaab087d3bd768155bd3df0fc9f7f822ca88009d54f9ab76967e873ce437bd0f7e3195cb48599df46f54ef9d2e424a93f59213e02a423870816fe39839111cf60a4d2ec4acd8e43863cecead8f660361b8a903bb39e0d785dcdfdbe89b85c713b3355eee749fb6027ef71e9984d38806510f18a4b230924b0b848a291f8e62922077c1034005c5ee611f550a746bba75289e04ea00ca60efb7b8587281ce5223eaaf8a07771df77a7dfee0d61b4d1e01602517cdae4f6c4ad7205b5c2d781c36bb7f9c36d3a1db2c4eec78e001dc931594700617d097a075cf9b4e688aff67aeef2b5befdca4f21e388b8c655c2b55c24e511251c2d400d40a3946224c052f1ce75a4442306569e701bcc086439a62f9e04c0758fd7bda12e1ce40b209d30d67f2f003fea544afaa1d0420f6608116269508081983a5d8a574b216c19749a1472029898399220ee4a6506f95e7c5787f5b9925e200ee2c2cf08cf40b446659aa9b72d867e89de012b1336c390f8884c2087e09f19183af33cab63051be64938e007258d7bc38158dc0e80b4f2b76d13813ba2926c0c2da99395ffbf9e8cd65c95721cffa67de1b3aacb1e40f9a75ae46d9a11e06d148dfe7adc51debf3a5ed2958ac53f09e30b368648762c53d629ea154aa10cfdd10faa8de5faa738ed3d7bded2740c0187ffd6fb2f51ae27931572d853d27b75276de25a8deb23b075f1581f71d8b45f9525f54c924a3057476123f900f1f8fc748b50883c13789486e4a0750c4c2b32d747542761d6b41b5afdb17086b17b7f3f2125e5df91bd8ff04ec54b3b732214ab81bf6e21560db4780f1f0ce7329d6540a217743efe23cd1c6694b52623718e1478973ba5f76afd37d376b8930082c5adf2d53ad44dd629106b3c3b3ef24829f1570d6fe0e6bc673a33d3f233406fbe881c13361f5495c94f2d43887657f474a5ca6ebdad16ee92ebf3755c619252bb90cee7c61ef1b3729012c54101ff03af47b6444e81ace561d759d309b050a82f6e71cfd7854a68ef7452aa7e48f7c5ae0d48b5f2d54902687a8f0bb78852bbcb6b17cc2f8cac0ec1526e2a60015d3efd9a0426d82aeee4260b71813bde80392ede8d86bf0d16af0977963ce5a573f7d561fcd20ab05e2db8ea7ccb334ab0307670beb2978093fdf7001199dd0d72b0b7752ecfb91da30847c8243072a7c2f199d811b6a6c1635c6ec835b05fd77235cb3d8451194f699293e70133d756f2c9881849ce8eae584597a83c53a47450a578d88f75f6982d17ddea04e9b9ed5095939009049cfc7cd6cf9f412a3cde99720adb91ee077da2aeafbc7a033044a0b672f1ad786fbd543528c38703fb4a37c1db9a2674feabf00ff33a5ceb01bab1aa064e846cd5d748df1714875b6a62c9dfe562519ab164540c0d7530589c288064e7b496b7184387d1d4686c18f22110364c55e53f3a70d016832be570218a012f6b252d06f73d254937d9062a293346adc20823419633ffed17822bc3259dc061a1a8863d10da15f11186f71f04b20e0d152385bc108ff740a68bf824f890f05b422bc8f53d3255aff1e028a79f6da0e0e24e931497d03ca96b04e687a6f6300ef2bf5af84353c1e1a3aec79fe45be15ff7c3791aa7dbb919da84d1106515f2d5ecbc9c4928ef292fc4de434d4b92ac996d21ebf2d7d0b9d99a295622cf2ed2ef5cbf883993dd846bae8f4fdbae671e7338c6e1743fb26ecfd0e40e409c60b03445ba5b1bad93b6d8fd88b0dfb82ea5a9a01db23cf5f74ec68b4ea42a309c624208abd552ce7d9b316865cbfad7d0c232c8f3589cc58f93168ad5fef7c3843002e357ed1e5708133f433b4e0976a4b1d8f75d99556678833e17699e399f9970d0053375c14a0ab5cd8135fe265e537ae1d98e32f64258458b7ca404128db1e2c187a91f43be9f07bbdf161b002391f1b31d31a2c8f62d7dab2f8d7c4e618a71a943d0f30fbce765f0a81a0b86f000a9edca80be34d9fb22fd5959a52dff8b214d45dd690880833365f782eaa2bbdba3cc6758d345dc129399b5ad29e5d8b1f25d06a5eade8a0ef42d3759d662b6c3b27d9ca7f5804c2b3e92f1cbf128efb05252410af5cc57c287a8f8c6c3e7e83ac898b59003c3c39da20e238659b09f1df157216dafe77fb079590574e4b4123bf304f18960ac407b2405de4825cc00c35061d04805f2451cfe3e026bb617a8e284ae1bb816526a9c506a33186bdfacbd016102199b0ef23d253849057f884b691e22de105d33dd87777305d5ea3c564ff00af3dfa4db7f4b2aa305bda33a2476a6b05cce69d61d9f75f986dfc4527af3f19102cb5b69b2842d6d7e9e90e8d575adbc16ad8a3003209e911b2a11d4e200225ec90847799d4821848766737493f708ece7a692e4885692d011ceade273fc4041c5d41854376102a27aceaa0aaa4c3257eb59982599d817fb2605623931306009cb304bbce9135174946a02bb039b7995536a8c4dbb218259ddb2c1c5b9dd411f093e4e518d590f06f8c106fa0f4df4b40f10db27b63d53eb4decb2481d15a1b1f9a4dcf66168ae5f6d7c79354ec366e79b5875482aed5d9a686fdb62b17630dc56a8b87bc1dcb6329bf2d19a56110dcc82f939acb1a6e70e994bb94ce7ff31a3b1db0cf696f5c842eabdc0a6e9d5372ecb94426fc8faef668ab3d9576705e304a945cf241ce3038a11c6f5622a3422ca25d6d0040b99e5cc4e4b39843b7d72534843b4222447511a5174d7c860e10896b36b505a0e16e37cdf8ac5691664e1e5ea49b6f6f35384f56d9faa8b6aa800fd2444e741c31814b3bb2c8c6cdf828187c46187808eac8eed732b528bd82ac8f43e6db3dcd19ed12205172f578245a1589aff49acc083e14f1caa589eabd4d490f6940acbabb055c05319dcded45bf21f0d43708de5ca2383859008ca641deed357917f5ec7ba58101d82a5cc8a6f524f19284b599173697a880f26ba158d39dde2cf107c3dec0a9723aa76b6bad28134544a94eff974c94c041ba956834fb7b8a20cb3f9594b54e896704c00828401eb747c909f8e2fd22eab075a9078c84b13b6bbac635ae9abaadb151c6e827b606742f6ff2939ada26729759830191df4708924fea7ebfebcff8f927d22df05724b550de94617b485e6049826fe78c7dcef0a4b2d23fcfd60d744b89dd19180f1b06d00b6b4c79b71bd446267e49ceaf11951b2d9082b09d0e3489fe070a744a0e64fa7d24d7703e2e82a7f26381ca659b1f66255b7efd0df075b6ba4de7a085030738dcb43875953999c2f7d5392df24b864833ccc9bca50062a633f8e7b8150bb74b7a7c537b12c72b109f8c212bdc542940fcbe580040f301baf107ae48ae17da9f15e0d3439be0bd2a45788973bf8745d03428478327de779fb78c055f53138a8e8df3e15405872ddae7b1ce4515871a20b0787503e861c20abb64c517e0042a2680e7a04527301326182626e560ba34cbcd567a6fbb797077ae12ee618312c49cbfef179c6440930137664d6cc87902a61de833c0aed0a616790b8a9ff71c492e8944bc3f60fe2de37788fef01f939351f4b1fc27098590ebadd75746f60b012641c5ef934924a686fb002c329d97277967b2da3706e342c7418340cef72d0392b4fae0d4ac069893efedb6739f3bf6c4ccc98c201a908dd8f2c46ec94720c00cce419319dfc91c3b842b3e8591e284dca480d39268d31117cdd8efc4e520f283358f61913978ac3430c515e7517268d57226dfab2e09755fd0fbb8654723c336ff3932cd6cd57377fc84ad99e65e92e3e62a10cd8cb84d1eabe63874b70602ec92c43565c29787cfbf0eb1066ce59023d4ae6b066217bdc050dfad86e31c4e357566f631a0ec0d3fa61c328756f7e8e9d5b3b7c8f86cbc08daabc2e8f31bf8eb84ff8a4a6db3643f1495b21c73cad93e3e2fd220aaf09a29cf4c9c5864053a1331b441aa1c585625e656e3e58df740cf3d457c40b0429e10e67b7544310643409645badd52389b0023568f354686018d5cc617ca0be53ea64144ab52b5109a28e74e789766193593c8bad70d10b403c06dfd7ca3b97079f9a4974f563a19019c8c895f9372f50226c3b0976ba2dcba703af39b1c50c7a46b720ba7d6491ee9143c7b653930901b4617eac146fee04757443f36c7156af58c8bb33670bf2928276bea49e7849cc27cafdf183902bfbed16820c68c2238e877290b90a118068947b5a8977360e5a952e0036257dee5e0443433bc39b931f3a78a42a124210a51c58cfd80c56b67a52a3238b4a47524f9e269369e91ec03c1b7ec246c04420d0035d930d1a4936dae183715bee51356873764905f7e7ca33c3f31a56996e22caba046602b6b24130d134eccc1cfaa4eeb4a5eba6fa0cbc022057243d8d478035a50d38b9c15b98af87ef36ccfcb1a41265398b117976d06a7b604b0945f6724c34befafe430b6e687635eb05e98b27b9e57fc05ceac658bbf43be2b055ceb12385938b72f3e4e0ec92cbec13b6b816fa60b5404b418c33fe661142a616b6e24e8f9c3bb35d37e457d1dac5b9c74f471beaf7f8f4d26f608f520ccf0e113801460fb5f0d9b7c6ec1f81756e4486d34752010a0dfd19ff23b9bab9cdcfb1df1251615cb508e4922ecfab788decf45b7e877c73e46391f8e7368dbc5f351ebce144bd31203ce49b741425627c097ec248008f704ab6321f4c59e6e6c1adcf21d255b9c0abc5e5d1e913335b2f5c18fed758628396b06073450bdc8e51b9ac17a15988467eb7f3ec60395c779f28a2a1d9998f24515ca5b47eb5cc29f875c9d1a1165b3fa07fd3b99b18269fa72901035818a9bd02031ad308ff76ede118c97350024db3130d1c0b83bc7b65c3bb1f886c3996c4cd8939139aeb8e749c34ff131274570245f1e762ee28f9876c9e240e56dbafeda6fe7047f8f56148b0440f23f0d011a69b14d6dc35825881a3eba8c695d89526348a2e783135364552adcb2de2bd4bb42f48491930f07c20e89c9f87dc463d93e72a7162f518cab3474af3cd60888cd45bad31620195330ad1fa68c7b800b83761b351b440ee1542ebddff7fc14b018c913564c935e83398d0e28e5cbfd160707ca15b6e4efde70def302103524f2d9162a684c86e6dd17b74948e34b7523839b5557457dae8b84d9679010b82b4f9b6ccffc1777904eda4e4583e195476f62b6b2fc96fa400281d935327130216f637efce4bd7967925161f603ef63854cd24c1637de8a8fb2fcc7031bfba6108270c3dcf4e240a99c15115a88522efafbcb2905c304d35cc0db64799797a10e49bd25c35c762064bf13db5ed47baaf7dd7c0f4a4e768926eb2b5f9f2b7e9b0780258805e32665ef178dd88e89fbeb7c2dbdc7f4c7672d6cfa8a46075a304407aba54c51707cf93558bf6f2bc15e138ce94d38ef015c8abdb37dc627159b601389b40547fdd18c07caa2e8c156ac50719ee2e1e57d111bd79ae6d03a1297a40c36bfcb7110608d12d503545f26013b67f6883ade09afc1a9ec2287c5e0b4fc18961675c195b7025239a4f728b6354262a3b333a9f49a39f5f740652ce6fb271e03230bc5559de174f64dd0d90f02b5f2a2eaf004278215a9d856042f48cb3e2028a458428b511f716a00e9432a28ba15a6eb8cfd6a26c33641dcf788c1f6a71cfdd7f6043c8cf84ada544f719aad323ec1d2ee9f5a4888114e008cf4c467cd2b509709b141b7d822abeb2f1122d0735485f29454e0077ef21016ddcd68fbe9", + "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441156615ed204aa948509f830e7e8756e609e419f8a6f8561fddd9202f8abcba01000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7001cad4adce90c01d548eb5a88e3935668204c5bddb827b618a40626d8bc1281f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000203219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } } }, - "integration_summary": {"integration_test":"test_trbfv_actor","multithread":{"rayon_threads":13,"max_simultaneous_rayon_tasks":1,"cores_available":14},"operation_timings":[{"name":"CalculateDecryptionKey","avg_seconds":0.115728250,"runs":3,"total_seconds":0.347184751},{"name":"CalculateDecryptionShare","avg_seconds":0.608609847,"runs":3,"total_seconds":1.825829541},{"name":"CalculateThresholdDecryption","avg_seconds":0.578625417,"runs":1,"total_seconds":0.578625417},{"name":"GenEsiSss","avg_seconds":0.124242194,"runs":3,"total_seconds":0.372726584},{"name":"GenPkShareAndSkSss","avg_seconds":0.223503888,"runs":3,"total_seconds":0.670511665},{"name":"ZkDecryptedSharesAggregation","avg_seconds":8.568398333,"runs":1,"total_seconds":8.568398333},{"name":"ZkDecryptionAggregation","avg_seconds":49.047040500,"runs":1,"total_seconds":49.047040500},{"name":"ZkDkgAggregation","avg_seconds":20.151443750,"runs":1,"total_seconds":20.151443750},{"name":"ZkDkgShareDecryption","avg_seconds":1.504357312,"runs":6,"total_seconds":9.026143874},{"name":"ZkNodeDkgFold","avg_seconds":62.889247500,"runs":3,"total_seconds":188.667742500},{"name":"ZkPkAggregation","avg_seconds":2.156797250,"runs":1,"total_seconds":2.156797250},{"name":"ZkPkBfv","avg_seconds":0.328596097,"runs":3,"total_seconds":0.985788291},{"name":"ZkPkGeneration","avg_seconds":1.329930791,"runs":3,"total_seconds":3.989792375},{"name":"ZkShareComputation","avg_seconds":2.693458527,"runs":6,"total_seconds":16.160751167},{"name":"ZkShareEncryption","avg_seconds":2.489975329,"runs":24,"total_seconds":59.759407916},{"name":"ZkThresholdShareDecryption","avg_seconds":6.047533777,"runs":3,"total_seconds":18.142601333},{"name":"ZkVerifyShareDecryptionProofs","avg_seconds":0.097465083,"runs":3,"total_seconds":0.292395251},{"name":"ZkVerifyShareProofs","avg_seconds":0.226985783,"runs":5,"total_seconds":1.134928918}],"operation_timings_total_seconds":381.878109416,"timings_seconds":[{"label":"Starting trbfv actor test","seconds":0E-9},{"label":"Setup completed","seconds":3.041689125},{"label":"Committee Setup Completed","seconds":20.243337708},{"label":"Committee Finalization Complete","seconds":0.007484375},{"label":"ThresholdShares -> PublicKeyAggregated","seconds":304.504600792},{"label":"E3Request -> PublicKeyAggregated","seconds":307.024598667},{"label":"Application CT Gen","seconds":0.318660917},{"label":"Running FHE Application","seconds":0.003694084},{"label":"Ciphertext published -> PlaintextAggregated","seconds":79.271051417},{"label":"Entire Test","seconds":409.917920083}],"folded_artifacts":{"dkg_aggregator":{"proof_hex":"0x00000000000000000000000000000000000000000000000469753df342aec0e0000000000000000000000000000000000000000000000006e4d829d66aff749d000000000000000000000000000000000000000000000005f6499be2b18300b20000000000000000000000000000000000000000000000000002be6db4c5558c00000000000000000000000000000000000000000000000eedb4b6056c881e3400000000000000000000000000000000000000000000000867b55169f2600f58000000000000000000000000000000000000000000000001bc9f519f74446bfa0000000000000000000000000000000000000000000000000002b6d6df53885c000000000000000000000000000000000000000000000007269f9ee62308a02500000000000000000000000000000000000000000000000fc8ef0ceed9608e82000000000000000000000000000000000000000000000002d32a3b72f08734b600000000000000000000000000000000000000000000000000018a5af26897d800000000000000000000000000000000000000000000000665ee11e35db35bab00000000000000000000000000000000000000000000000c29f716629ef9a6b300000000000000000000000000000000000000000000000ef868c0047d6dd22700000000000000000000000000000000000000000000000000026ab8350fbcd619e3c65ffa1c0d29b2cd62700cf8d71ebcb032227e21f28af6c3d9993353159827a80a592b60afb7bd0a5547279d7b7b6d745bd21e61cb30dd2fe6fa64ed7ee81bddec82e6608821134bc64e48afc548d54643761d84f4518e91e1bb576a9b3a1efdee0270f6a11edde9c2fd71e9de5a134a7ffcfa996506f17b7ded320b946905e9267cb38c0568773f0534e90cb7b63d7211d220cf75c33fef50d1b5a5100e055a47bec0d9798656da3a784b526caa90e53303c14eb63b919c2949535645bf0d9547c8dce32e13dd504bc6be4948f9635a4189cac34427ead69640255ad33c0d14a348d9edcbdb6ef4d4b0a379e7fdeb9801b76a0da963bdb56d89ba8f3a0210b7c42426c99152b8bbcdf2b36f1c1855f0ceb7482c347de29259ad7e05498a03d6dc7925daaca12e8661b8410ba878a1497660cac39150a0d2d1ca7b556cd5217867ffbd422a5ec0f3eda032d0da1dae248fdb76aa76f2aef8583db964d1491f5aff0a8af8585259f308839565b5bfa984c574d4cf02f2552749a67f4ee7f91fd21add31916d3b40f4006b7a83ebf00c14999182cacfc3b853fa33eb52c4bc0d7a9f47486d5c9f5dc5f1fba6a4c5edebfa27f2b9d47ef6a7de0f966356dfac080b3dab741554edf23aad2a27840334a132e4ccc09bc438f503346aad442b0214216a2005c8c7a405b68cdc0032c8a6f8ff1c663bfcfd165d7de791193c31c30dd9f2f2f2a0431be2e4e4f1fe5b4be54f4df8b761ca81b8634e42a243789b7219142015b3808efb3a739c019f139df3488006f7e463f6d19fcf228bce9fa6d613cc0c01c36911240ee0501a0cc007655ea1fd15b8a1ad2f8d1ddf49931bc0bf177827b2cceb2956abbee92ecef40924cb1e618efef90f0194b8d8df4745ac94211fbc877e3f1c1843dd9c04c81659fd1071b38a33797f6a6c395143aec09c8901b9d02917af3362e348cfb2e9aabd53ebbe6b3565508163ea1901f214764dda2cc1ea3a3e121b0655786495091b1b6eb05be9d77b5149795f94e4bec6e2b183149dc7fb2a6c49197a09199db3d00a13ed9d3fe11a18f5fac973b7349533df4922301951689c04b3f866c7f8425c047237cf8d409e8ba27c49e924268817c9e9055066deefa06a0b869217f5fed30835f92bd9662aca74e8b06d29e525ade59a1fb24ae716ec7d331fe77e298f28024bb1fdcc10c4390920b5592dc36749909d0c0f625429773d2393a4f713600cabfca65ec0617333ae5764f69790a9f97bab2f003fff339c5965274e74d713ade8d48df30bf48503c109d9e6c124b70b6277299d62ad7b2b7138796b217dbcc3c4acf6017e1bd6fdbc366957610a0f79eb4f17ed4c180fa64e56f7ce6c9c3aab320f1552db2274fcd7a4576de6cfb0d3db3c1ea4b1ce1f3afd3ab96c2e78be599e3d94f43d7f89851fc6ed825d6658f005e815a7cd1bd26641e038a56293b8095be2f287d24612af3ed6ba44a1f3f3a911e3302a5476eff60236e0580cf8b25f9efc8244b30ed8786f66e39dd4456aa4f024029eba613ba4fb9a7994e9ce5afb6923109490c62e0c988df549f2e9dcc3a56829bb3f7054a4b8cab4aa1769fa658620e87d592cbc03f9a71bca647f275288ab02dab6867241f0d9d7a67a4b33933a1709d75274bf5bbdca414d3ec79ed120fb064ea0f18c25252dd3a82b941e656196dae6336b385dbc60cb74e8cd668c6f631fa549c5ccb417790c6e015e9adb9d640012eb6c177e18eb7a319e4fd7a266671c31bccb4604b5acb7226d74e075d4276b4e9410a595e91dc5f864d35c6e95b72d4308c3be58dc29da40e25d1f63a36940f572b901c39f31e355b075dfc95a2d2092ece23729f1bf832fac0ec1ccd994f016562ca1efebf54428b688f1603df1076714c5d7d7ccd14a87225c15c5178ecb331bf323ab74f8240715fd0166c33605affcaa1b4b75d30f034659860df6af13b6ee9e6e5c1cbc5e131c2709ea226c11cf137940d661f8f254ebfe274cbd889768cc23d728cd2c5082012f427228cd21cf49509a55121e5756aa33e207a548d5a8f15e9f4869564fb2fcef1c4577e81f237f271365e73cbe12dfdee90ca49799cfef0cc0af26d57ac820007cf3cfc9073dcb3915ed77c7e50f58441879c2c5bb450ada48fb95182dd02943e980031a257c5bb6c116e0e17a1efd1877dcc3a988d9b5680f05f5dd7927bbd0336c143c0aa03fbd503e48787f9296c4cdb00160adecdd0ac45174988fbc535e86d6e4250b3b669d61dbca0afec215f54337b74b36820a3794c4824c9c812aecbdb860be238bcc0ab026c45a1329e6ccbb1f0e6abd83cb9910e5468c9e22ce6c4c3c5d1b2892318212462091cc6f082e3946445e67456576206a0777bdafae6420bc108d0d545b60b47a8647c9acec31abd3eb4a940ce24304658f9ce2ff50a5f5a656f80dcec5d9ed6e857d317c33e96e97e19dea73112a08b301cee1c5a26264b2033918a03534a00b9812d0dd992842efea7d0323402034bef78dbc11232402264318246fac64ff0d90acbd0b1930b4377ba08f35e91ebf526c3802640b74f6b786ec118f486e979a8f8d9bcc19307bee149a5a4d459a145723fa863d8230753eb1dd08f4187ced1f037867e3308affbc4fd535746aa6760d018f75bca7bf3396a59902320058d6cd5935e44ea6943d47fb9d45ccdbf8ef6de9a5231e2e4e2a1558662b10e223298ce2cc72aa45a021f1437be501b2743c08bfbc9708db8b2cd7a9ce17256be9fee29f8d3dbeffea7001aa6648ed7fdd53c0e9117d88379f75466d7c2cac187ce9ea645f137c8531c417fa019100cbdf78be2763d38414b97a6b00871a954bdc2d8e1df7970a636eb0e9d8e5acaaf827e955adfe4a8a2a43598a4cba094833c3e3dbd1f261a5d75b5fd313a5f240ff30d989823dc45a3c3ec90082c626ae27a87be9dadb61eff083583ee3568378e95a1ba75f4bfda023c820466f822adc5410bfa974d63142c051bcafb9f1b00ea44385db8cf1d0c36be3e71899c00cc356ea4a7f52ace0bf72913493c437e3a0cda118619333e1b503b29a7e008a0159746030e90700e49f97c957078dfe35497ae3c4fab77cc9c6f080f84637291d9bd340a31415e39c83c58e3f3b901ccf2e2e2356feb40dc496008982bd189118de77f08ce5a1515447c4a04a8c35e9c89f86d164f10d3df3c3701d8148e5681c027f18f613d5f5d6b22de99a7e7c5d1154db617adb0f4aa4b140a4cc4946ba2c6a68f07b9c6b738d4039291b0e7bce61dd330aed09aadba81f6658e15c46251c44e7e03576d9a2d902f93d2cc226b10a6e44adb7ac928f8275333365101c821d0ce2c8b77aebdb5aabffa4c641b602cfb62c3c98c9f966b2d950a193a4c6e4196464c9eab169d15ac12cf5c4ba880c3bb829afc21ada4364d6a4f81299de8b21679e06e1e557e7c831c03cdb1b8629cb925d4fdc7d44fce7f4ec1517897ec72a2ea327bc07437e1a70ce03392e1d739c2f913698ee590e86c3a7c5e01e70292b73f7dd483bd896583d2bd30e736926227cf981f05cd4d718c6f8025127da4b205d377c16c2d412e76aa1486b04538dee538376fe1522413e41df227cdd52e72c8c867f4a3ea87ee1328f964365e79338fccb36c83a0518445e3c09aa2005ef15405379466c46a41cabae490c736d70476264f3b78287804bca97b68bef27c409883a5ce11bb36fe046d33a2447f7cfc35506203a2e3a01d389c060aa3604cc237fbc043276f8bcbfb7d2d1adadfaba9cbb70a9220efebd6ffc62ed96bd9bf02387189dc44aa75b967986a74ece75106f97c17256baec95737d6de103c6d7a2118ed1f68bbf4fcb6647e625e0a210b31dd9399f49665aa4c27d88a639767a521dafb03ac0ee4f48394d53fe6d209740009a1c11886f6c721cf91e29e268e8cb2a7dba0ab3bcfaf639f230f5cc32a443d1f9afca79a77113657e12b3a4023f130838602c3c9bcda88afbf7ce8fddd16060ec4e0e955bffe48ce7795a750121a7304f58bf35b291bff1e28314c5e1aec8a7301a178b3e2e76b81f27951a2550b817406d894712963faeeed76b7069a0c164e685255aa0ec245c5d223b36b05f760307a8d077c47184df6356e68a3df1b6e645a7a1f68c3a4ec30a79497dbeee8821f4cc5aaee04d9c0c28cbe66e5cbcc48994a4efa36572343f005e385aaa301e157faaaf53694d880169b06e0699f6aa01cd14868786ca9be54a5571ea0791df156e53a49573829a7493415d75ea54104d64b800d4688fe718eb4069b59f93162277d97ac74c5836b5078e713d2181bba46a58bd1be7cfb2d359473be276081f1b6ccb434bbb6f226e9188bc9bcc75826becfb2b589244ff57e97a2994682a3e007aad5202beb5bc1a5ee1fd908cf63b2d36f76e04978c164ce4d36a3646d7581474432c9e22f05b48726087539ee97f746f73cd9d414d242ab5bdfd7609d0b32155a9da08e2067a889517aaf8cb024a8168f94dafce6f93b2f12dfc00641d5218c35fd80cc79d0b4bbb1f766f20ad4ecfc79ca94562895c78057587e9edcf1211fca08a404520fb20794782ed562767d84c1e6bd5d1121a2b58b63d633cb3d528392519b02c9a33d6200c2b94bfeae8eb83460ba6ad4dff419969ce80ad48540cd03c06c82c17abae5a66cd8db314d6cbcfbed1472a446afe81b08ee8e710121bbc002b678d3e50d223f02e4edb538e65fe35f26fa0d21cd77169d208d1cea6188ad9b99abd82c6f89525f6f1034be005f761a9503d049c955ce43bf0997e192ee5118d2c94ab12ba2df5075f42f1572f28660109c53a4051c8aeefb2015915127447e3992602c10f17fa0248d4a63d3fb51d02d7c87575ddd2a228838d54e015405e3aeeb0eda949ed50111d0881e0d2eface34b66941e9ea7246365202f1d207ad9eaf4c7ea11527fa2ceb4c32496270b04edd79eca3542d97606c3ad946601d47aae61d27411aabf3fb0d5c57301ee1ffb7c01ceb4d04ff39180475d097f2b07fc67bf89790286b97b1d814ee45b760d49ddecf8dc3907cfae048afc82550a7f416d7de4c9a6e3a847c5700b4642b637ff9872096679d2d5921eee91c5e11110a2da4abbceb28aa0f9b4bbc132493a2ec0f2712ab0d2cb8d2c589168f9af2f14df7d9de5d4463ff031988639bc2bc42c844a737ca569dc14045284ac011e02992542a5ae3e06562f08bd9eb6d695652b0c0207c3514b292402a5745a60cb22cbfa325db3d30866e1739fe38aca41517e9076700489344ddf68c38c28ae9619b91304c3e55c8f4ffbb089b13b2f04ce5d61caad3d2cb54341b5d1a930d35511de0fd7e69802c35962bd45cd5733a23093208051359e4257f5c9cf68082b362f3744ac22c015a9ac28540106e7d03ddc305882758a50c372a580e5d70c09a720755d74fa777039850e88a289095bc3fda6e3de76a661307c2e77237916761e1dc2e2fb9e5e3e31b522be2e0d8f2e3e7e9cc1dfecb73a1a79a0e26c7c9083080a1e1842116ee304103ebdccf52062bf9578e864afe05f3983c17b84f7bf4d1209460b438ba34839d978ec1c5bf6aab43d09bcada67751ba23a5d39910102bec0c09b6ed88010416941c845ff0402963a715b14ae1a371e9f1913698b402ca86250046ab1d84ba0a6bb12686cac9ba831fa28fa3d0ba72589da190425b42548e220351f64ece113e51fdad160958af52e544b5d08fde40fe37bb84cb659bf593033e291841fa82a53a8f2c141b596c4ed461f562e632b2ca893c12a53bf0de5d2f084d18fd57562a366766d549e205cb36846670c81b92ceed909400a673e53223e9c3b1001c31f367bc9125089c292d5c65dbe914f59cfb0c1b702c7847f2151732806c02b5aa5e97871f60839b79d3e6feef3a3f696115c06e05b0429e1d5321042be272a689d6010378e100c44a1ea4c1841d88a61ded92b9c04347056b3e098fb4e93729884cf98a415354961cb468d38c8c5dab2466952e1863952de5d22bce831cc9e2f11fc39a4e1911e4e391aef8fd7e2f2868e7e8593519a4dbbafd163660310bbb68814e644e234d2a6214d3c2d84d5e78091ce6a3167f992d6c411b70840ca25c4251db8cb551e4a37170bcc4e0aad6a73ca6eae85ae85437a8c12fdf8773e4d6896da6b5510c65e8e5ebe2214ce0aeee893aac3b5169ace00fd20cd9084610949486651f579981d04ce71f246593a621b94b11bf2d4a53a9b7272a75ec707e5d6e9b94cba7277335b4dbe3a721bcc5d8d33f2d6521047d8b2e33035d2aa05920b16961a8e9f5091d1e8dcb0ef43ed663dd29d95e24307a3cbb14248a1fde5949b811c8cb64d561a5814c4e42db4c2a82ed3f85428951892885a92727050ec02883b4fae76a8ff11f88b279cafc825d492c8d88e6a21b8069bdbe3020b22284e21dbc649e9fea5576619b0d5a6c20662adc00a8cae9dc666fe84d2a33893fe7fd23a4b3602b1872968e09b248a1e5f009b8221019113733a639e314bce17972dd81107ac90a257fb403b80809e8a41f298cfeb0be9d87341e9e8026b58446c8f6efe18ba6b664917d764b67f883a1573207364f3a05ea5ac4124a247da1fbf361caf35db0991d02d7cbeec4e6867b454e1c728cd64859a18ff1d72ade435bb8dbed3cf274c0830a6adc7e9aa296f01e451882b007fd972875c54a2a76150e904347222648306798c03ad2eabf742dee661f1ff2ee8b7aad5061f408e8c42347c0400fa8fd99c1e5d560ffd9c45e274bba4f8e3de5f6899a9eafbc05c680f29f0e759926432803bd257f347279ad57e0cfae3ac1820766f2bfa89a2a054c1318608489a6149c8ce98f751f4f90897fa87921b04885242913fd053c29d2250a857eadfa84a16b5b4ded1c2f89d817a2e005da0b94a425b9890920c829d60b0fc66656f0a79faa3e5496317705e56c49f69b3732213b652469ede8b62007b1e8209e5e0eb0842a86321e49413e7d1c48539b8c8689d932b368452d8f00a415eadc12aeec854463da5ec3e848343d7e035b69fc369e03b45d426c80cc21af387870e76a693d616c271e15dbaf75d32b19d1e6ccbc63ac71e155d002ad2992a221a39a21245e9ce4d06a5d450398bf7fdad0fcfc4edc1f12c3a109d98d1b24c341201ab7ad61528931ed868d4ae748b0935ab27304779ac23257a0b4e40fcd390fe49200b9b9a086a7756db0a14b232ad01be5356c40d31c1aea918a7206b55b1f8d4af81e1cedb29c4368641a2a5d2440c70d6908fde350ac8a26c7f22d3b2f21b2c3632af0f2e9f3c9e52e99d9afb03fddd83f09cb28d206f67086000dad45940c134287e81c13e4bb5bc22ef82e4c5e061e69084a781a21997c063010b394acfd38162430147456b9de74aad70a060df546ca38407bdcbe464b01aa140d5bfd0a61d5158d157b2f9eb42ee971192939f25f02448cb5782b36d5ba5413dde40e8944b03e710c31402a37c420dacb73603c0e62af12c136f833aa3437064f488a6685c8f0b0c291eb33aa33b81a9e4c513e6ac55c7175c3073335d9740cfe4ba38839d89625ce94c63e04178c0c76553844241b8ffbf82c53237a02390282e7cff22065a0568345157ed5e428b107946d5003cc6ac9718b020a21e589158a93d1249c81b6f5edc19b1a461d4886f40991c89be5c89ac77ec5486d77b12852972575eea908a0d0ad066ab7ff71ff02720e41b559dfaf5cc99992a1e82b267146784c9faf18f0a30b1d2c8926de25b4a2b5d4efcf00aee059031129823405e5c2b04465b50e6a6300c519152d3b175595d3ee4a7c103c90a46683bf33900973a27e9d6caefb89a1d148934865286ceceb2eb2a6dcffbf93f40d6b8141f32df15c9b7528bf722ac0cfcd16b5d3b5992965d3f49c62a5516dcafc36be9bd117d498ae3e827c74807a0f6120713c018891bc502fcb2f3a3ef5df92fd36e09123278dd884d45abba015519edebefbbe07b19dfb6eee736e611a001af8182f7d28d2df78f84999ed714f241de56318517b31798f9bedfae1771e43d28c74ec01236fa605728da81f251b890f3ae9375925ce406c5808328b62d0c1f61d507fee0d603e2271f6256b38c56b4d51698152dd71d572f18aef64bb8956cfdbbac8291420757829b48a402faa763299af4f927add42dfe05421d6f381015fd09950cb1d49db81efd5ff650a753c43ef4d6c56742c82663cd9ccde44c04a9d16efb3f226f10221eb3fb7fb9cd29e0ca0a9bef0f9b7ce84f43ea5bf4c7497642e2ee7ea1cfe335df4a4cac533cacec297ac86541cfdbb6baa5d5ac993ea49936cd81b391fd9942ed996e79fa851a07adcefd1c2a8b8f57810e54d04a23aacb01abdaf8d2e2bb8819d1ac0ecd13c2e7af62f8407d63039b06b61192c4d7a82f65bcab66e05e769b154a29cc138b5119a732f22dc15ccdd3beed12318162f437d9da4532508b3af66a3e7a10172a476ec9de4a05d3cef956d6ad5bfbb0ec8923723117f5a046ef296f2b5d88055a90b443c25e5b0b877e3474f28f2cdc79f49c618f44aaa02d3d1638363ea5018f4710ed06eeba5776f89dc9dc4afc3fe942f92f90326771de423f8057cd1463a148594606857c7410f3de1767f89e692f64aeb9c80dbd6063943261cef4c11bf08aa50589f51ac7125d9fd81d005b2ddf1d8b1c5e7f97512b4bc9df1655304994d4c05d0881eab395a5925b935d565194e3db86ea73f9e0cb618907cb0aa0d73720855ad56a543d380344559d846d0c87d2f66c010826d2f0a5280fafcc55461e94a95c98123087fe7c5afd72020c01b5bb159507bac36081c5efff00bc7e17f6289e9d2c2c5e9beb2bf4dc4465c3e954f2393e70ceac216ae4898e4821f8dee3c88d8c1085a01d6abd2a23f0ff1f6b92df037992c73a602cdad1370bd59f65f93ed6344a19ffcfae76acee1f8e2444d8fa27b346719541a4dd20cb3c9f3dc615bac655270d1362c9edad97c23f13b6897d65ef2e3d67b2e948af7af733a7252895958bf669fb507eae810fcadebad364fbb3b5d1a68a1146f82fe31c5e8c26c46d4fd4d134123c591bb36cfce94158faadd437ae2ef3920ee3821c8ef268c38cdcdbb380ec23ad56abf2c5cbc9fcdc291c02269af47df0e6fbd50a5e974c1e50024975c390f43b6da32df921c90f11d18d6577fdc99c120126a58a070d74d076cd1b872e0cbba7354f30dd38057fae7023c6dcd63527a1c00ad87e6e3ba05bda510ec142acd5a3c662373ac3f7a7cc8a10ed678466446176938d996ea81ab6002cc8f4c41e5269d007637a81878e6bf0bd562e0d1b60e10da7445419432b35618cd61bf90079a08b5a0fdab94cf8f36d066351118484606ed4fbf014e02b795dfd62b14b16ba950be77d5c317dd70fb058c0d896e18a1073024ed35b213beac45d0eed9cdc684c954bdf3c18f365dc541b68618b8c06e1d8a83550339c96e752a82d077cfb8ce0211447e4bbdbc3b127712004fb7caea05d2641dd30ce23b7d8b9c5530671324cc9aa1bd271ac6c9be835fec30741fa103c877e6c320cd6c0bab7d62d3bcb698b6605be618784663158b717f37ab03000f60911e4d3e33184fd26170e83152da85d24a8f095334e59b7b62cf4c2ed8400688807ae631070c134aadb8290c356a9521af9333a69da38904671ef89c4d97004d118138a5d8f7d945a78c0abc64881ac3ab0c86060db570be08d3dc2445032afc433cd6ea04a649a3b523471a5d2ad1431f3584f5142b2b5046b5f39bc69d16565ecc4219043483b3906d8e2623ca40a26cbf9f18f51ac5259545a592d5f827e0ffe8b7ff77b8f63b0ef131ffa4c5667134828fe82cdc754d15c7cd33cb6c0077f04d332e7ddf9956d603ec3c9c0a55e1db71f19642c7f876452248a70f3b1cdfb9da087a8ca3055014df3aac51deddcbc64dd8d5a8a221d8e91e749b308113fbabb99460f5785f829d0b922389a673cb6dd7cff8c3d288a77f07823028da1292b1f04a858b4630c8306b8fc5226f918328babcef14b9dc10c1880582877e1d450f991999bb052fa475bef0846a915a9d643aff92ed06420fcba96e673339288c3fc6586c13eb5f581e6e7200163a5e011881ebecf259bf2b84139ede52f60e389ecb2a3b2d75a3cc041b4fca6ef2cb232527ef829a8476563013a4d336e204e8ec63f06e0917808f60401e320069d022f661d3ba23965bc66155ac3623f30b29bfc132f9b01495f4c869c57e8cc42cd2242e72fdca3ae4727c02d9ac881c0a145fa3f17edb13347bbd19819e570e3b016cb952295952683f30761f4f03cc105cb9a489ad41d21c68151afe3def6129200c5de1b932ab352119aeae31df5121e519547cd28f05371a2c65f716c239ab69d20fce2af689bc05f99ce4247cfa29cc49b35b4358a3b42ae5c91d95fb99655002e2b0d6d535f21a6c58b9f82a2119649e434ee728c3248ed73b956bb9667ca6b77443651eb331f0b6520d62c5852e3370acf4ada80391db77ba155e3aba9e8d821c2ce1d31ec09f9898ac21b1112dddc3ef15cb12590a98531763b8d043596632648e08f8b80de1767e74855ad7259558e9228544d393351f17db1a37f55314b6d2a39ff65ff22247ce74073deb24cc708bd37b6ff151588a7c0d107521ae217f13afecd55265888f3263cb2bc924a1faf27e8345e2cab32ebc6aae03b62d115631527b68761882befcaea90c0102a7abe55e1764b18199cefbe32acd68f76650b5a83204dd677195396700b93e268fd11b30f6aeae2288c6b31926a50007a0e85eaaf2f7a6c3c040369df5111e1f8e3e91e40e7095ea9820a37d8ed5408382dea8fa3be255dcd2432ac79c3b2a1072aee7d8c69cfea210a58c99dd9c158744bc20b17e8dba95c49091b70ba4f4038acdad5293ad3f47569799a1203e607107575ad494b4857aa06a2be9d0d4ce2aa07260c845899f56d89fbfb7e18c24130097b1e41bc0ec6d7243558f2191bc1ee0b5ece2d0d55c02d3abb80cfd8d10d6bbf360068dcf6cc17debe3a4e8ffa3287fbddc25ef9071872116ea57fb9055a978d85768f3dc162876957749af16512290c1d094e99bde4c38c864d31bbbf85ce2ee488f943be32e2727633089385f2b461d8ca9e0855827cda5fb219fb1717ff0a838ed1b27d82947288e5e8c14590e039cc9b1ab4a33501362144ea57353d0ce3ae7f845bdaecd9e1304b5472ff61d5f0fe5673507d3b79974ae6d6294e16ef1918a4fa4a8d023e89823124327d21b74fe4ae3c1ad52801ad8210a3cefb6ddc0297038ce08f9e4f49ae8f1f99e5e293e702e81f1c7861c1c445fcb48d92ba77eea9b250ba2967d506925efef7f261ada0b3d9f2742502c26d1ac9f750649cf0155a7e327a3556b2bd9f20e009b9601165f5c53fc4b398b8f3f7413d065aa3fae26a12917fdf716f1360181fd1dc81444a57a6b94fd298742cfadfacd30076bfc6ab47be4f09b66cc76b022a47ca5191e725f35288a70698d51c5cf43b77c2f80b2b3bd4d35c2ea033008cedc2f042eab11def2bcd80ba95c3ee8c4fb917435c62c6aeaf2f4a7131b429b5cb2a4ff23081ade5ac7c55b647aee9aab520bd3869f9c93c36aa7326ca6bff7af3771a201959164e8a0978053f0c13e7a87916c47c7d7ba0d1f1d1c826b8873eb31f7d22a07070f5d5fcad09bc1de1960c10ec0ee3285aa2dc35bc42d8b206ddfe119b621ff709b9861e00dff5f5caf92d33c79082c90e3e9a811cfb225ccf802c6c51e0dd1ffc5d73e22eecdb9be76ac089ac3cbe39613b2e6f4948ae91a42c6ccbe9f278c01e611cb037785788834d4b7306a5f94e0f3bc26e9731c53db35e41fd2b41ea68bb1a63e21995c245b20761bb235c4bdb5248afed40f7531fff2a4e300c80ad0019f2ee27ac9ab8181f077b7a0bebcaf59459cac8ff3758a91b051e89dee24ec65c2bd9503a6ec590079fb13870f775c5a56325c5317a88e5c439303808c0846b44c4526e81fd78c7cc680ed2993cbf600b108e88aeae1e772b0b0f8ae5806f883cebfb726b4263916b6969cac42ca7a9e5910be070fb64d007d0a7315d91daaf0e62bb35b5e24c1e2a5095a294afe753fd690a0f4bf298d5f1d0e3fb5311399d876cf50e48fb817b3e8c7146c1d061f07f7d0710e182991462d793227590788cd56236e23963e9a41d9b6fee0eca464fe0b5ecc58b78151f57622a97ca700863f02eb1bc9d78d1082feb4f383d1e2eb5bdcfb4fd72020922208eb19f7e809e9e7b184a15bfa5a0a43863b5de3e191059cb78bf74c53bff6104e6c5637ad0121186bf2df31b19bf8e87fc74d1c71d8d520f181c275958a409dcb7bac15021cc57260697c1b3bf9c2db1a1e87f6db39677caf5445f6e85853823a0d358472092cd19d6850a62402d1e425a2d7c0fdb61d2e02f86928c3fbc56d2ff048147b07b2e6dd21224c6bfed79c76e49a5d79a1da6722776e2c4cacf6a71f4fdf8c3421001e4747173ea80422461affd27e3af8ce9fe9eafe6bd76e47ca4bfb9f54e01787798b5ebc4cf20038ab846044605785202d2ebedc82441c938599daa982200676dab42c70099280328e8899465ad1cf74bbc27cefdbabdabe85be02dcc6be2780dce9f7f6b97c77bf7284dc71ce4fdf48f13b36553b372bde71f04c1010f719c9e06ad95bf42e16fb4c5e9f5779cecc8a99830b62e6452cd80f8843dae91517bca2479d53cf305a9d43105eef240fcf12a391e92c49596770405de304801d27b4f39ddf78d44201072df5a66c3753d6cc740f42fca640ec8a9c2aa509941c2d8a8d9dda693b87dc33c5b641332770cdeff855b01b7d48304376e48925c963036bce8d831d7efd5f879447cb403c7e4d7b01c62e0ded5dbd39ccdbb545c5f30bdff5b42ced0c62cd22918e3598f7a6cb7c9cbdb7cc8cce49be5fb57fedbf702e06430500eb0bc6b794b6172145c3d7e0b18e36f98f98861f8dcd0511b707b91dd03caac365db1699acc849db995026ffed7dedce3505260acbf7c4b09aca9d0b09ef40ff6a704425e1195ffcccffca50ddb4c9cd440fe5d8f918774b2852b7177d38c0a40a9325dae46f5c11c30c0b4043067451cd714925e0799f22524d0d0c2997d8d76af181579491ae7893f4d087b1daaf0a5e38723690b34d70a1d0d32b0eff8e2c99c5e155e65f42c60d0fbcc7604b757896e0910f97a1f49f6283ee2e09e4434f0300af0e0abf8b98762f5c6295427fe8e0fb6748b7e7aafa26b02b1d819b307c1f70a1a3ab3812f41571c1b85dbe9603288f4afce9591e8449d99a0c07aa3eb97c33a646725cb03d52fc53ba19064ce10ae7544921f23c2eddae110359572c3d7b81433fcb47a8ed65977667fdbe70a029dd1f9ce9dfa4db220f8a2bb209257dd8d49b864ae9621cd32e3772d453207bdc88ea8be26869afcb5a3c114c5ed52c900da7ed5489e6e199c7ff224a18275897d832bfe121afc7d663750613d5ad6f4ca266eaf1f69c6e0f1617c647e6a5830ceeb3f4d5a2e70730fffd259aed34a0a6d955f29fbbbb96a7051a9b8aeb3de2c077dd632f0f91ae4d2fcc13ad02527dcaac974cd68ce11d09ee138b586a61ea77db1f4d8877146da47b710d5e19796318dca7b99638e5450448ed4b0776331585b6846d0b3f504854665421ba13580166db9ba74f35923efc566aca7d76e32ed30283f7c5b96a12a4cba7130476d1a3b19df10ba213cf604761861d3b4264b342a68811bcaf6c26c4ded5189b15e6f0deafa36e7396871fc0054270765d9cd75681bda91ef8f1f156f51528c7e724218c156417cabe8378dc773cd875b748baaa0360dcfec3f8b5fd79fa15758af830260018537aabe640e55fe9e8d3ba07fd4e849035112962edc1ff6d26a4bfa0e267a938b358a6d95d86a3208e3a1ac448dd043cbae10f847b76a8a20ce0a559bd0f3cba36be6fb50512452bf06915094f7a7c7b1a7a517c7fe3a666249c3368fc161a3932f2d10cd88276932d3d2315ec9bbd8a1511216be52be76d1cc48820c98e773afc3e24181c2666fe05cf22c763103498316ba0759750d575156016a55d457f3a538a4822d1f4dc598d9c9e25fbb0381f2aee56bad06d5c6a1430f3a6fd2b33477e72b8f91a066301dec27e6c9bb69acb1fe54f692ff9b20e14a2a71e577f1f5f7064bef074b0654239599257dc86b12bdec3376250f97f5f005ae534014c6a69ff11c135d18b4dd33c13e4cc11018b7445104b16e6d94b580049efe999a49bc660ce9f8757ea3456c42319d1f91e21277ede209bcb9bf2da1aa875a2c36bff51aeff4e2c01151a0243d5551e016b5e1ef76d8a98443d304604391d823e2248de66f8a0348170e55f5b635d380ccfac02b8fc88df515c0ddf26c4c9d9b7980a35b819aced7c720ebe1fa773e33e84c79dad6f46d3f9bc35e92d2c337a767350d906769ef475cb72fe2e03ecc358f1ee1074f5d620b36480f21255cf596afae8506f5a7b164314cfd890f45fadb279bcb742345ddd9007b4492bde23b40195702ec4cf12305ef29d751e1a31c1fbd3ffd9d29fff53a3dfb371227c0f79f3487ce0e76d7188070768a8ca64021d32ce22f13989dee1c46be72b0d2faacc65a02532940e3759cfd742171bf642d8ad3321c96fb7a6da32a70300226f637fe241477c36bbcf1c01a059b520194003c1f6bb6983d74395fa5b48f914801b01405c4d89b666b6918ca546afcce05aa80dcc4da69af0bfddf2a5460e","public_inputs_hex":"0x2138b0022ab9af3c96b082bbf307bc9e79f8f1401462e3ac1cb3a9913a5b856c18c40bec999a837ec1f06dcee05102acdef50c501e771cef739dfd0a4cac5e9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000211521e0a601b59f0fa9d199e9f861874db5d701a0c38f6d725d9fd8c1f0b53da03219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218625eaefc46d4dc1d14d29441b83268d90e246af546b51272b038fd206edb2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7296995105557a58df75d3a42759d29e124a15ef43bad6b7fd6a9d93d4efda1c900382d23bccbad9ba827179293d23b719de8374589fcad5bc6d2148bc787593a"},"decryption_aggregator":{"proof_hex":"0x00000000000000000000000000000000000000000000000ab6871f5e0c604e230000000000000000000000000000000000000000000000063e0c5faa3697e97800000000000000000000000000000000000000000000000c4edda900b7425ccc0000000000000000000000000000000000000000000000000002befd5183896c000000000000000000000000000000000000000000000004d8f5da040d18947000000000000000000000000000000000000000000000000e372e41542c47b15600000000000000000000000000000000000000000000000eb6fd9729b1572bba00000000000000000000000000000000000000000000000000020aebcd8e4cd90000000000000000000000000000000000000000000000027d1ef6bdc1bdc6fb000000000000000000000000000000000000000000000003b63834a1a171bf2700000000000000000000000000000000000000000000000007d98d752da17665000000000000000000000000000000000000000000000000000218b2af27d6fd000000000000000000000000000000000000000000000005fc5b00c064fff6aa000000000000000000000000000000000000000000000005475acb7f772fc6a300000000000000000000000000000000000000000000000d5eaea21fb7f5474c00000000000000000000000000000000000000000000000000025c5ad7f49b8206f35cbb5b62e5b765b61ee0b49a1f8770bea9d70025c2700523a6cdeffad74e2d17c339a3922f7ef70421fafba18febc1023e82b90cd74104a98902574f6d1c226c706d93043c153de5bf841a134de7656959e544c04017eceb0069aa692b1b09d09bd7a13e5ed5ec3350da8de0eb3d4bbbb261473acd3a03e1f56acf424efe0c6de5bfd3bcd37d09cc02b16d1a369712519dc1e780047008bccad88b1517ab06359968bb78d1f165250eefedd6b57eab508d2953f5240a27b3c8f21fbfafb207bef508a58b51480594683a51f7ea0ab2210a377696def48a79ff7efbaa8e0823f41ad197d6b1ee7ee556998280123ec1b9aaae6dd280edf895997e038d1c1c25a9dc3e528367cd6ddf78257f8f4a4c8c13a20283316c3eb5d11cb539b99e5806618d8b39dba1be4c13bd33f165d43ef169b3b372eea8224a06ae43caa0d921207c4f8a36cdc97347efe815d7f3321ce22eb52b6258a38b98f20205e737b6f61ec9e8a86e5cb149f99b66f85d8a15b805fb61123bb0b5dec773cb3b297fe0ee07c1cdbd49dbcb2961b3969e1607c7518a382930487888e32d9bed12a4b7298a26da1f07cba3368953cf9f4a5c127d3fb11a2477adfeebc6be03f27dde2c51742d449697cacf031c884d94c35016ade6bbffa6a1ded069664af9617665c4ed7f09333f51d61f47a9365621869531df3ff6fdde13d7571858c89dad97081a5d032db062ed586adde96838ac6e2c39cb5d50c316062bf90f0b49fa7acd55e6ba1620d7097883c0c1432d691f8ff8fcd8c8075c631e9d6268bed9ca37f2e49bdcf215c9022b55733861a9e7bb732ad6df58cfd3446e7ec2067b2746836af4f7f89c06f25e697f3401aa322174f68a210066a5b63035baed84e1406dc44ec30e74d91129f27facb96b2eb96dbda62db646bbfaa784d1a5fba7dba608196df258f5020c01e07ebef101e89b91d5dec206ff84318ba1638547fe25aec6b87d674308840cae64a836af4ef9ea8cd2ab455927f23633e086b6f6b741485e76bef2b6cc032bb4e67d1a535f5a810fd3cc9899368676a27a90f311557be62e196f20ff52ef13f86ea9ba08fa7eaabb18c6b1afbb4f7771d605e4b1f2be6fe991394d0e2f0626490f444e9ea9fbd75efdb2a25d56667fae74512e2fc0acbd49afee2b2c23e72373c15067632bf4180a0cdc54e9c9394e7154b900a48eba42ba1f44b1d9fc72128f4b3bedaecb9e70e27ed92a46717fb202dac7e349a24736229c5c0836ea091cf2028b1a7eaa6a876513fa071249ea34cd4e1e27e33cd996b948907ebc60990d5930a69598cdf690b2c2c4a1ae184affe235d854ec81da06447e2738270b582081a0574605536f0f836c368de05a08b39fd2d65450c5c5d6d6cf1d87a7cd5a0a079aead0c9239382526011399682aca59d1ac68ee5c18aa4c3f61d13d2dc9f1940bbfceb517ddbe3d02b950661d24e7ed55d0550eb3689f421b3a2a9056451192059863b2f5bbf2fe06feab1df4d0b2165f90a3dbafeca86e3619716ccf0980bf1fe0721c73d5cfcefd66b41e50aa7eadabdd8c455f2779c3b3398132087261797ac8754b7044232941f4d74818e58ed96ec7f2caaf282f7a531758636d2020f7ad743013efcd97a076ead680b17dd244cb55039f07344e15a1a8e2f38870a29edba2439b0837a103e1a8c00e450006e6b589a654b8ccbefd5de0045c8e21c1545fa845e862ab714a464c0b6e00265beabcbaef383504fcf2c5f80cd7360b10d5c24f04fa84e22c6a8e81696a7d4debd55b2058c64ee4339f7e1acb1c8674f2ba9e03d761ec3bc086bf76ce20afa4cbf8328033c71e096a1b21e3e1bbb980c260b3e581b7f7afe02b1ea39b3b73031d0b96080204bffcbf3a04b43f5365bdb249ae301120746252ac7b763df1d20111dc3827f858fc8b12665c07364f9e6042b8adb4df253af298a3b669077f4aeac1aa8f6cc0b44af53c3c1fa4cc56a075d2857a42d3b05cc24d8e929608bb93e738fd680f4cd8af7e6506808ecef185b2b2ebdc44cb7a9ac2efa142c54b09cd054bda803a047c314060dc259796a51bea1238b6879fdf41ffc4269cbc9859c6220dd57373fadcfcda2548125a04d9447280a0696340db71c34a8cabeaf6636088c0331952ccce04a506c57ad047ad7bb9222907f98f62436ed0491d278b5ed7b273a27601258a9ff54c7ac8d3dbb68cf3f1749e0a4c950d439213e3bf0524945627736e7e8fe7f07029b26979c722849f62eedf78929c852c7bd06c10d5a69015ff5983519c3e0937bc3c825472e519547273409dd5643ecec7d1630979937792e5ed4b7cfaa110c7d87ddb2e600ae1cba2ba7b5464a14183ed799350e4d18c512d14b66266eedafd5d32e1141c543d6db248547031da4097158b87ecb7845a8f659c5c02b9ea2ac6f636f3e3d4015739223049f86005714294ac037d14a7ccdac80e89882751314baa8dda7bcb024504e2e27c6a101a3035ff6ef42b99d56c20c824d839f3d98e3131932867267d947c02bb2270046b020798f033e718352799c0cf9d26c86961efbf43562dc263b9d250e36aaa19d199f1d2789110fa14b42d0cd40a491ba99682f72fa9b301d08528b0cd55651c7fecb9fc18e4a725043f251aa9b69be5d31aaee787dc8771fbf31252a90ad86466fbc0eacd6a4cd0d6b94c53ab9fb4c6398b68c5077d5fda03d7e7a1d60824bd6a0859b7fd17c5e3ea922c212b33b1b36a7c5c060eecdec697ba38c0f968500d89f9543e48accf3511e6d0fbb18f089137a7db279c6abe326dd15532f7ce125605cbd676ab45449b2ac04d190420e48f1c0a029eda9944c2b651f681194348f35c5946265da9ae92238bb49a90f7a05e723b185bf8083ee7448ec9517320c5f10fd917b0375e3c88136b03d916220b42d3ef345c9617873212e1e6d1af9a175a5da49ca79114ab1bd3fa654bb9dd1cb9a287c2278f367cc7ef0e35d064982209f67c25194f6d480bd1af6da9c21e590bf77f8e556bc82b3f36629e51ba0bd9e8e8f2a59d7bbbc20be61ddd3d78efba879719d28c116762ad44f7a1c17212136d31493bc280107ecfc3e7f56a3155e6a8dc95ac459573523c5db8e9726948905e785fae860f81331108d539f7f1b8b4c914936d1a06976787a461aed10fcc5ee13a48ab03e06c2eb6d80964b9faad63932663a5a02cbd28b40f159d3191fed983fd4a451dfc47cf6bc11201e2d2faf3049e8ebfb3c7422ca072136f3294c96e6a0fd7348adc0080aa0cffa5ae817a64bf74e78406e6f12e2ce53b20f24795f8d35edf71c5de2ab175685fab6f9c73dc06620bda26f67208c9774b7e52526e6da846f50a867b53b0c964535f5e52c14958463d58d2417c74b2a25d8012d22f20b89f69d9cafc3744aa9a3435674cc2d23c1e68cce4216211907defcc128f00687ab857061bb9fc3fb5f4d2bc70d8652f2f9cf0808c69135eab8fe2b05192d7577511195d93abab820c9f30795df0b10c7f55de58c03d19139b28f5d90128f7041b76c81e6f1444d47642da90ad4e2903cac9481dd31dec5947d5feb56114e0d1865a7bf262de8132d41340ad3aa5e1938c8692b7d9e6af1633d74a3a21d0b65ee6e74bc543b648cfeb52beb7fc0e500afbeab9bdb8a425e43efc6e0ba03f2678dbb80015852281938260095069eaeb25fcbd581d8ebd64babae79e41d11efceb26339550bbba1e36ecc3c91f71ea9f1cd23c0ca5036758e74edf7858e14ad89c7f9c8f71c3cf32fe11c37f583c932bcef67203e999e45700d3a5816870afe8a87a72d9be4d639fa57feccb778e06dbba738460fd0f511c0ad977dd06206c54e18c4a57066e49e55e207d36107037ccc095ec6fa2feae81aaaa44b88370906d542c020f0d3b0e2d80843567501f13066782c96646ccfbe031283544962216425d07ad1796b75e2e9d402062083da2d671d32e1c34e3647bad0322067911656aa8439e56e08c30a1384877c1a32e69c3440d5a25f687c175239ee6cc75c04d11f5e379d21a7e8b32943f9772db2e168f4f1b7b087ee8b7119fd1f18aec2269e83608b1d071924f9f2dcbbfcd070bab6d7f5a447e3a3da752065677b64921849ccadc866212b4a74dfdfe4b8430bdb74f4a9f17a6a99495f0886b442625f2547a6f4500d0dd6f5416d1f40310b3fb8ca4a72861597ffa93f0f9c8e3955fa2bf139bd084522a6726933ffd9e47077365bcf03a3ee29f99edad41cce14458f0684554a86d665240423b236917bcdb313a210c1946d234dd1fe542e742668fd0d64b6ee71070db72111e430e1f27beaba2482951428015889eaad1482b4c2b3157c8eb633ce89bdb8cc75ec48b40e2c50fc5c46e897efa49a7e4b535b16dba729a619462465eef8f964af5497553815acb5545f74d5d677d2c0c1e339416b9c219e50a898ee88e1fb2f1db566e9696f253d79f68772a0aecc07896d2e49332c0f18fd89635440b49b7a80d33da8557759c2fb146fb125ae93087fc2b6749e6a0726f493c7ea11b9d67a1be2dbf04a50105d2b489c75a2efcad8658fb92521580df1b992af777cb0e3ba2c825243eb0e6bdf3d0a6978d1411104b59a46f0bf720a79728ba37648d5d60c06f92608a4dbf1c99fc3e449de7549a7e50762d0232c2b116994593bf466bb0dee85010662193d8ec2fd8a25ecdb2a7b34f7478aed831b3025e984f0ada44ea0333d2d72380d11ea5c1b5db3d182548eb261b77b13181f48514e3f03784963faaaafe860688661a8bbdce565ead9184b182a9802311d19069af44ad2e08496a94d229f869f5a2830c420d4e1bde78c230d8da4384b220c88dc1324a1b82f54e16647c431dd5011a1421c785e130013cfd882192d72f01374b6f2b7f6011bb2194cb772e337033fd01038f1d77810506f0f93aa4eae822649b30fff4c315bcd99b6cb7bc282d60e8aa24fa71bc754482ab58e0d721c3c2ec839f0f8b1c83585fe7ebc00368d3baa4a381440565216c8d2bd04fb96d32311649b8a7a3ca661a0cf53114a8fb32d33cad95318a6154178abc8c06440e21d22e5c70296141521743a8a37855d70b311927b84716de2f8fc092c91eb3a7a1f221f26aea2f88548f3af4b19fc475bcf49786adfc8d7e7349e1693548f512a221f381f9587f1fd3cf3cd069024a1170feafba8229cebb8923a7ab8fbd856196217b589aa128af06c775f25ed9b3aa9bc23803fa5965ee8b7794206585ab63ebc119c919779bcd9b1e024982c6fb199b1679c9af2da8f200348f68ec3b2a00c0f17a15318a649ae59bada674e3a149bb1d6431461411e2df3e2aa1958b722048b16a07dd414de7958c407c3eb8c760779358ec1e2439b58b8d00378bdd2e9e9450de9e777da0eebf79d558d029019a16d1f8c076fa5294863dda329ececee07020721d000c002b15cc3fd3cbf0f0fbc80d75c1bb53ae1b7a244fa507318c57e4c2d6fafb6038ee34355adf14f0363881911843ba3c655934688976f48ac38ca4e162f5b94463b38687726d27320a2d8c97ff9d8a79e81261babee9852ad0958c210d8ae1fe24253e9229b410ba1f11ab4cad40642dd7c818aff33430752c5f36205ef43d3378c9968b0b16a881404aa643c3d555f84b78446cb9bec133cbc10ad00b9207a883ec2d82bad1051a9c39453d1b63188f2c5c052643e597db86bdd1621806a9ef2c04e8cbd9fdaba392d0fc997cf5a49811bb4c8b68f104ccac280541ac123db803c502457797ba6ef0da3b43641d8406b78f1007c09560d45062a65259bc7636f785729b40176ebd0ca1c6f2ffdb9ef2915602c4a6275ac8fa7cbe71adcd397d6043297be672053abf8339f90c137a367ec7d6a782a51b8285f63721916d859797c32299e9413788fc27175800859f9bfc7d3939d4f6b5cc9777b2f198710723aaa5fb5f57450a5ceb88a674796d19ce70fab58e730240326a016922b06a453d8c9f93c4f6a13bb87c227a297ba159e626f5823114a76cd7b0f39410cc25f0afd48083c62151fbaa1853b27d7a17fa1b9e2fa28a284200bf12a6f5a2f550ca3ccff9b6327e4f7d9983a448cae3e7f9ca4e628df133a58dfe58d741b284a4e0b987dcb8dccd1f21874cd434280feb0e942f8f0e5ad8fed96b73bd26f024f4f697877b9a2164985542d2969f52a5b57c433eea4f07a445aa9e833a37f15dc67773cbb58f86cc70a1b5779b019ad98af907b00c0a1fec4492d26e38cd72085f1cba3e5e9c54abcd00c2108dd54aef936879809260609e0787ae4bea1f618a9df278efdd7f15dfe9247dc384fa4f971588fa356b4e67377e8fb6251408f2b82baac18f833a2875d3bc642a5838432ce511b38005fb7024bc01688ef3f670da2fd6a5794ae972da048893816c19549b73421e0d585751496ed222a7cfbca1d415320f214e7cee462d0689ffc31bd05f4c9a5ea3b1791bce9fcbf374d2d14004ca233a4b174ab409e968d6399606527b624923f381eb8c17b2805dfab7cca280308a2b5af4f1aab2d05e78198ee4536f2deebeafec0eebb33df157fdbbace2e747e434240c5cfe49275180859832b2d69923bf08c0d597d9112eeb73568c91fd8ea19778ae26aa6a872c78c89c957d2518154b689bab59b2ffe5bc04361ae131dd276df1a28b2e06a9df883220bcf76424cf289b94d5bd90056ca2a6828f210f1ff74decbe9a8961ee9c5963876aa8face86ca89e9b038fbc5b1ba5bc962c128107f963cd0d439c4fdb465eb7834c943f21c1f3d46a7f057b75b42aac8c472a5c5521abd8d5913f59e4798f9edd0bbe643ab68d2d5f2d4d7b7dba52dd5c8c01fc9c7bdbc80873c54c494f37b6f6fa4536f37b101a16a7da7ac943fe0f666304c7a6659b382bfb94977ea2f22e244f5224369d6025dabac1e08614146ee2501ddaefc72b74b56f7f72ee8d908bc52a354105655e85edb6dc768a83f3dfc0a317c66db9a34532d5f7356579f0741dacf256f0af84798ee17836c4a40fe4b5cc04c199f7039d38a4bc5bc7f2d99fba60a0fdca779b92f02ad5aaf76f1fdefb091381e6eb635e8634516faf93dc50ee8b484c07b917f28d75a657b00a68ba0b71015191755b4d819437281f7565299d9d5ab193750340c3436c4e1ec8af65c201101a107fb877fdcdbd711cc0e888f6a3918bbab8780e9651d6c8bc29d473a25a263d53cc7805cea42498373014e822341492cb0b5846f3651c4de21d6a02b449249f136615c3fa59efaab74793ee99dea1346e28a861afe2f931757642bd3ea028fac43df603f0eef3eb0387cd88048d715e733dc835545af0a970b030f6bcd40739b526796af9c7636fc1e0023beae25886eb1ec9fb69465f36cb8db0143282114a980ff547ceae0ae0328b0a2ff83894cc7efb1d8d3268e623e20257143ddf1690c3f89ba0cea9077e7448601c66a68816c5d7adb596e9df73a9e7d4f3b5151e8e6dba9f96d00681e644aa6cc33f2c88c76c3f204f9e0f4abe5667921cc5dd0a77e105a39ddd0f53525089e44c33468ab32cf7761380760d7c24966908f7291f3cb7b08e1addf167d9a5eb038f1f433e711c6e67adc478606f09c33400928b09658bcc54c224cdca2dae3dba6278e91f8a416474312cd9325be5c38d7f5d7e07f54faf13c87c1b95c0f7f21f9f879644988df52091918a8fb17defcd05035b2c01c5516e3c3a8cb16dbfc84ebf730cc91c289ae1d9a2247ef46867c4c3f8b214c7e231c7382212bcfd3bdfba84e5befd2d04ead43d97823562f066e832f1f31e830d7e9747675bde52ae766e1b6f1fd1868b78f7acd5e595aea09c9dfadbd42088b2218775b734708929cd68d07da0d0544236991c2b7cf3b1c8a535fc2a741e04a56884e7fec5c8b37e770b9ce037d6d9e5963f682452e8d786a57ea1ca4c11dafb71c383f1751378b133a730dff48da6d638942abb532cbcc712975bb260159681bc8d1480de29c8d1791ececbebef1dd47e7055855bd32ab876af784fad1175e04f583e93f827e3336d431ddf5f2a9347290732acb2c1e70b32aa39a1b61535d18522b8e335ee209aef0c81c3ba6c2902fb07d3d35c978a48c6242a5c0a0e5a2a7ab8189202cad4eef209e352db7c4548e813f6479e5ae2cdb3eaf32b601bf6758cf1a0678a0daf9120dc0fa7c4a30f5602f2ae2cd64d49f6cce7de341603a1e9661d5b7553dd96174da8b0763cb968592477ac917adc4dafb94d89522c29bcb39fadde0390e904c2638779567407ab30dabeb7f8beb0b49947dc9e8fe7291197bd5ebbf948c0326263c7cb67a772e3ffefa7d93deb6fe34c83db575bd913e74272a40222380713812899c64497ddd2f0ffa40bd9435ccd8dcf07812318062d0ce0a9887f24c623352f28434512a3f02497d08f70e2acd92c6f9c7db9c70ce84edc6d0b2e6a85061ecbbb6d524d77900e545869d585f02e66c11c5683262a89acb3a1d01fbc647be2e4ff6850475f86dbbf3a5533cddb04f9f759ed3f8c1a58e6111f8ab44f6eb753ce9b76b08ec2c1ca1e8e4a0b12f2468685e97514f80084f9ec72296c13c390174cb7058a1cb652524e152af41bdd9db80f4b26159d019c5915c863e55429c22b5df53f3c2c708d16dcddf9ca6144b3b12c102f6e4726abcb1e662e072858dd31ebcb6fec808ae3818a0e1529bd7f967ae9e4965f942953dd62008a7880ab0f25d1aba340e932e7ca5cfc654d05efae33677e86e73c1e16c255cadb04bfeb1f46d2a57eda2e9e0125c6a25e611177db2f81b52e4ac6270c29e8222702c6a2590dc3853e75a6dc26aad0dc20e13b71d273946564d9d7258d3a80b86cb1a2b655be37f8b0f78265f6bb866571b384a0792cd7ccd6f9f61514364c60b0d46d272ddf70cc26a62f1132e1edd6f617e815dadc8febd9a74e2e645c1d5c5e21b5c8747ef39578966822fb78829299d4ffe3e411f3d3bd5f092e06ad539341a69ee6302e31511830369f8bf22dd7204099269cf871cc0997191f1a2d248d13fcc11672953d9f5ace68497ee899bfb32b4b7bbeb46047e4ef821402516b83cb78caadfadd9fc6c12a398d99f1b878ec66b515e7483a9a0cbccb083041b2aac57d88f01d6d47b3ae84186a84792b52151c25f6587e21f8e6b07b1c0fc000b43896466542644603e14a650e16686d853e62db267e023569d5469c0809a8d114f1007b7827216e65fafee4b603e959641d11636efd348dbd46ed560624ef25c04f501716ef93cee02aad775bd9ee6919852491f3d29b942372e1882085117390b7aeab2e50367937357f59b9f3a24d1c14cc6497dbc0818fbed5041553c7bc5740d0e9aef2bf62243c1ca12f8567c9d3f39a40110770253767fa7c26a871d60e27b75d9e142b1162a4130343e788148124d712988045ef96d48f8920e88ff5c9f60d09d2f77ba9b403bf6c6d0fc0799048710792a96035c73a3e450c283036736b9628210c2497b080c5abc5372666768ca864d18a6f203fed35cf272622ddb9a3970878f471c80de989f90ebd8cea6120f8bd4c593763bdbc5a98058b8395cb3225c7060bb36acc2d22c0338edaac7d75befe39ac4206479c86fa237ab01ca34b0328eb6699049f29188e92e7354e69dd727f960802fefe99c3d80c097dd8728bf5d5825041d67e5ac9858d748bf30271341377176ee8bca796f60e5c92647f6871a1579155741c7b634c268068d9941eb9acd84569018e4de82811c568bf95b24c04cb3cda2a83b14307e668bb54db1a2569360d0caae00498f91e0494092814900d31c78e68f63f06cb09a782d204a10067a78a04801888f8b707e647e4d114ea7c1e7faba4176bd2977b7c1d0e97d6e3ed976c66930ea8d1ea278f3899dc95fad95147a22de703ff82865da597000525a1bd0656d82a84f5d2255bca0b9bef6038b61f0e92a5ba1395707daa095674120eec99fc8ac392eb5a178588131cc52f9e6d45d766712bb3eaf094693a5af7a4f746175bf7aecd09831d846931480245a862576fd3a006b07b1fd9c2db51db74543e275d9e7cc26f2d27452fd95e45041aaedc81d99067f7567db1fe9759e84b4fb2d1bd93bfefdce805a6cabc48654d9d38ebf014ecc33eab6dfe7fbe12b4007cb490b235982a55a611fdeb14cbd17ae02f6dbddc8b4ab0e8209312dfc80292b4c072401ff7336ce8055b3fba6b7058057342f5e55266f9bf87220d9c9ac9fe0853f3d4f4d019d829195d64b5e10165b80751e8ed7945c9a19a7960580b7f3a9d7a6065ce6a26fd3128a6e7e2d8d168db7ce213fc75b4315145a583fdcab1de9a71a41fda973ff1490721ae0f3ee28441b6a46876cebe7b6d692d551bd2746bef1fd28623c1af91c020c7c80ce66224b03e7b9106196f94b8e0c9b5ed67af49449aa45213b412de6e24c842e747291b84fa0553bd0fae951fdf6e70d9412ef0ba752166a5dcf09ecb079b9de21279373de98b9ca059e22817390f90680d8d338d7e35d0dc81751a500d4bd7104c7cc8e52af19d74caa3d6928ce9b0bca085889fbf59a86959c2dcdb13df2f80658bacae156b7f1f4865db24b07fbb6b27942099f9d61e57ae43c3c723bfd52acc8ffaf4fd9cb1147322dc31f7ec5671c5f0ca5c5155ed6d9f2e2413248241722317c262c5bc54875d886f0d90780674e073c5f7f921a6666e3048cd16d5814372e0236fe69a63a4f7118d7eb75bc4465dd01181c9a197ea72f8307c2841f6397a9baab5a97fb04e109006d8127d604f0b7d6736162c40bd8b1c09221e0922d2139987796499a7fb097c9d0a4671b898532936cccadae32376c93dfb059ad2915af4a690d40a516c72d74ce5d4ab9e752f58873ea88227546e021f701702aac2d40191a410dea52f40a4bb996be8002e1c57413e0dea9914098f8a880a8c387b2e3309533a4c07aa51444956ed8fd2a314017814af55da77e40ff7051641fde9c392981a5e7d779529be3e0be0f6890bf19b24f53ebdbde0faf9d69f10e9fe5c469cd99083a9c572eb19b940f9b0e8094a75fc98a7131f2c923408620f3d931493d5a7f759cc6a21edbe9dbe770a109672574d8bf6aacdd48623e833296a76845bc8dc66f9e0bf4d05b889bee67c4c2852750c30d06903783da6ce172c02a8f8653d8211beecc345dc19b6f7cbcc803d66ae2128ba1ba055f761ca3a1aad5843b15c067428741c224242e5c518ffddc45193b3a5ecc922cb13c0d0a72d4130a3f278c1f463f66423e4710027d0b319048abd0a6fbb66c195b9d1452e2e0c7c0e8374b22294a2129630e2cc3dea0b98c2c13758345954fa86eab6ab710a512893425e0268e10b34ee3e2e6a4fb03040687698c97982e30bc2a8a2b2fd2248da56fa8f2105609a497670832678fbaf89a7935cf26768c2c03f443fcc9012eb0427bcaf487189c20e24956f34d23792ad3f62596d3767ac07ae38f3fd4b11324800ac6e2d023729dd5df77dc4e0cd81d0ba8e10e90a266711e69d577bd406b1e218645fa2552bf747d0d1a87fd66c7644155f6f5cba9115d114d7631cec08770d53cead9762e9eb24399c4f97d98fb3c365d158799be00cccd3d20c3b090b431b0c2f7b7c2ef333ec898e469fa101f1adf6f73815f3b09bbdad8349034f1f90f27a8046dca9070e149c1c23150321e612756a0c2c7942d7e30059be4908050ad08455affab49f27dd02ec5169cd976f4567515baecfbadbe97c382d3f1826774b8c096b6862b740081c523d47bd0b9639994b4ec95ab12845086dd5fd482538707df831ef734170cf55d329490aa2e0e49643922241739793a8c75e7386283a026efc405fe0598677d246226a3ece5958e0d48de439e944a05fc643d0641fff61f83de97b677bf4840a977ef5625bc385b7591755fe89ee851ea5d15ebf2655014e914e878ae7c1f8282c6189ecdcfd5110178786f7faa3b05de46b43cf17e113d1492df5303ceba990b322420dc3220d8d4415f89381df54d5ead445821656c02d97585ac6f793d80d33115e53d6415f05f0c5d90c3d77c3d140226be02a3ee5564c70975456bf79d426c8c33efdf706cd178ac3d687e28e4d2204547d0fd5af73db10f93e0b6c523b4ef081426af896697aad46e292ae0c5fab03ec3d0d8dbfff9127ba2e3c4eb3e7a55d92890674bd6132382df800faf6b8b407cb5e2f34f902cc48285bc99e308f2acf715a3b8f884aa21e144ea9fe2a36eadfba592775d95bfd62c6d71c3089734d67d08cb00dd85d23185796cd641089a93e19b12beac08125be0a38ea27cef99c4cdbeddb4b278caa2fb8d47e2745d5c09e83222c0efa0932bba4cb4546e28667c714e5b2b974eabe47fb29b3f78cd5b43742f101e475b51ad373772e93166104a79b4efb175dac3b442b52b9504c88304419102b169b8bacf4d47e97ab2c69e9f5654f5a0cb6f55d8fea831cb665e93bda050b2ad2bee6223c4f9377be451cb1bb4d7d5445b1eb9b58549ec07694f34940216118b0e8add0f6d3ff6199052ea7668d13954c7caa2fe6af1663263c9a6210ae0b01981a9f0fc8d9d2eeb8d92572ad287146f3bf0c20d23de8d08c40c78dad3d061c8102981be8ed68bd6f3b7bf768c40b86a06b6da762153c82d045133d3976a50aa6637a1eec72f4f886a043ee57a4e6ecf52067f7f1dd512d0829b36989687320fec9da648b374ad4e0247d1fa97700c286b7e1103f696941674e6f3a6f9ad4223aab447b6b691951dcceffdcb30f047653433c4f8a1abeab791b5ac76b18502575e60cd921ee2346e0ede35620fb30907dfbfa218913647ad415c9a48ff09305f729f2bf156c6478011766cb094981c086bab98c384f67a7dc579b811ba5c11f607412b5d8cce667aade35ed4efee23bb261c4f278e09b257d502bc61ae48712daae64de5ae2bb6d679b43fd9669b02023aa3eb4d01d10c4603bed9416d06f16bc522446aa35b063e490767fcc90a7bf197281c5c295c1e0415dc27d1e29df06d659418c6c2d19a198517016a3c76ce82fab8d540e656ec7170093c80446c42bb2ab499e9eeed746759a7814701b945e602522926c49aef0d217ba7f3ec0ac1495c4281a7b4a9e1464ce6c97788d617101c912e7918be268957e80dd37fa1c1daef5d845aae5ae93f3d73e13e95b2f974ec218a863270fb89a30f0a81f70f815e9e11d54842d2997758695e9e919c49ee9568970dd985f95ad792c4de69c602ca2a090660e70cff6f75b308d6b58fd3d41bf6c2e1ab5210914a167f161efb208999866e918d0ac040afd7f314e279aea6a9503c0fe69b94c0596ec7204937c282c824f63fa7641a2732762083c6fd099f8538f33fabde31df0ff298e4d691403845eb37769b4a7e325f7b4b90dc138807c7bf8c94b3308c8131021dbc702ec1b0d2773d0d393b5ee72fb1b8c46bf5a2d96e008f0a27bd052c6ce663df466bc10b34b779436e65c9da5839de588d9356cf64f721915fb81cf1107e5861a4fe51ceb29793e3bfd641066d690ab8a27bcd93604040376f886a2bddf62b99aa21012f03a25b1808210494fbfb7c5a6e98c9b0183db9d9366514708d725bd15d6471c37dd3530ee3ab502f0bfaf4639574de4088216596534660c852c04f73e77270a40fd0514c085057ceb30638d46641a2429e8aeb06b89a01c7a19bb9287955c17d5b7abe02aecf3f5e497b8ce13ff4402e42e044c3d270c04db487f5d00f04a0697b0af7a5e27a2a7c04d5bbd73c3e91e2ba020b861cf43676ed66ec9c18f4129399d25127fd3a40f696bb6dbccf3829d8babd3a13e6aec6f0e6bfa632bb90b26c35be6ad3e9fea820c0327735cc17a5244802c9466dd98739a06bb34e742dd044554adfcdbbe8d300cbc39c983ac1a9222513ebf33bd79f429c47d58beece61dd0536dfb22b4ee0b661069eeadf37d8c1456b05f3e19ee3e058c732c8d1ba62a6a39994da45c80490e4a53575e6a739a01d8817ced669ef6dee1dedb34984b2688cd26b1fd6e4ed748d8dba93b6ee4a21493066c1a10f7fa44f50a02206b342a5e15c483ce678c3f87fa37ae6701c4105ea18957e330b13106f6d62f55dd9e05f880741b3c98407fa02b8b956a0b42279f01abf85630fbbe613129d4a710020602b5ce04f6a3eb5c329dc34aa10af6d222c111845bb6016b2cd69f48e4edde14106fe41edd0cc43ad8800ca68c5aa644bdc46f64654b3fa561e10dc84c4612059e79b06da8e2bfb580c268e0c94f02625b1feac968586930f5fa9daa1d52e2166bc02b21f5b5a51eac5219ca1c42b6f563ed338189e34fa6c3e8d5922ca880062f1a75d8d73e3cce28ccd91097acfac61ce220ced87115497eda778f752709011be2b3aec8c33879c1b7d9f041cfea2e9f10ec121a0887e278396eb143953a261cc5d74697fb31f3b525f2129e9dce7542e906372204e07e6d68f59f2bfb9d194e059fc2816cc7b5faab72efde88c1daafb9dce629acf1bdcf7516b7551a8f0d427ae711881bb9dd56f6ddf46d96644fd2e7bd577830779ac1e706b6dc298e0b89cccbea03d22a857589fe4895f822cd5c5fd1634ffe6ef44b7dca09e57cf30126afd120fbdc1cde39aa695bdce2ca770926968c345e801bac05c163e4bbc4279d02daac4bb1a306be1941d646c5e93050adca4277432645be6a4ff50ddf5805d1070e4775d2d6e006453d6b67e718f8289e49ce80b841212e613e505452a827677548ec16fc965456db4e86d45b4d59be76f01e4ba348015b12e75937bf20","public_inputs_hex":"0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441156615ed204aa948509f830e7e8756e609e419f8a6f8561fddd9202f8abcba0101cad4adce90c01d548eb5a88e3935668204c5bddb827b618a40626d8bc1281f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000203219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db70000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}}, "test_exit_code": { "crisp": 0, "folded_export": 0, diff --git a/circuits/benchmarks/results_insecure/integration_summary.json b/circuits/benchmarks/results_insecure/integration_summary.json index d189e8d124..3d536b39c3 100644 --- a/circuits/benchmarks/results_insecure/integration_summary.json +++ b/circuits/benchmarks/results_insecure/integration_summary.json @@ -8,164 +8,164 @@ "operation_timings": [ { "name": "CalculateDecryptionKey", - "avg_seconds": 0.115728250, + "avg_seconds": 0.111521499, "runs": 3, - "total_seconds": 0.347184751 + "total_seconds": 0.334564499 }, { "name": "CalculateDecryptionShare", - "avg_seconds": 0.608609847, + "avg_seconds": 0.610321888, "runs": 3, - "total_seconds": 1.825829541 + "total_seconds": 1.830965666 }, { "name": "CalculateThresholdDecryption", - "avg_seconds": 0.578625417, + "avg_seconds": 0.559050209, "runs": 1, - "total_seconds": 0.578625417 + "total_seconds": 0.559050209 }, { "name": "GenEsiSss", - "avg_seconds": 0.124242194, + "avg_seconds": 0.124032833, "runs": 3, - "total_seconds": 0.372726584 + "total_seconds": 0.372098501 }, { "name": "GenPkShareAndSkSss", - "avg_seconds": 0.223503888, + "avg_seconds": 0.226692527, "runs": 3, - "total_seconds": 0.670511665 + "total_seconds": 0.680077583 }, { "name": "ZkDecryptedSharesAggregation", - "avg_seconds": 8.568398333, + "avg_seconds": 8.500284375, "runs": 1, - "total_seconds": 8.568398333 + "total_seconds": 8.500284375 }, { "name": "ZkDecryptionAggregation", - "avg_seconds": 49.047040500, + "avg_seconds": 49.366586083, "runs": 1, - "total_seconds": 49.047040500 + "total_seconds": 49.366586083 }, { "name": "ZkDkgAggregation", - "avg_seconds": 20.151443750, + "avg_seconds": 21.116986167, "runs": 1, - "total_seconds": 20.151443750 + "total_seconds": 21.116986167 }, { "name": "ZkDkgShareDecryption", - "avg_seconds": 1.504357312, + "avg_seconds": 1.465883083, "runs": 6, - "total_seconds": 9.026143874 + "total_seconds": 8.795298501 }, { "name": "ZkNodeDkgFold", - "avg_seconds": 62.889247500, + "avg_seconds": 62.328322972, "runs": 3, - "total_seconds": 188.667742500 + "total_seconds": 186.984968916 }, { "name": "ZkPkAggregation", - "avg_seconds": 2.156797250, + "avg_seconds": 2.200691667, "runs": 1, - "total_seconds": 2.156797250 + "total_seconds": 2.200691667 }, { "name": "ZkPkBfv", - "avg_seconds": 0.328596097, + "avg_seconds": 0.336088264, "runs": 3, - "total_seconds": 0.985788291 + "total_seconds": 1.008264792 }, { "name": "ZkPkGeneration", - "avg_seconds": 1.329930791, + "avg_seconds": 1.351367042, "runs": 3, - "total_seconds": 3.989792375 + "total_seconds": 4.054101126 }, { "name": "ZkShareComputation", - "avg_seconds": 2.693458527, + "avg_seconds": 2.682164854, "runs": 6, - "total_seconds": 16.160751167 + "total_seconds": 16.092989126 }, { "name": "ZkShareEncryption", - "avg_seconds": 2.489975329, + "avg_seconds": 2.506225536, "runs": 24, - "total_seconds": 59.759407916 + "total_seconds": 60.149412873 }, { "name": "ZkThresholdShareDecryption", - "avg_seconds": 6.047533777, + "avg_seconds": 6.176445291, "runs": 3, - "total_seconds": 18.142601333 + "total_seconds": 18.529335875 }, { "name": "ZkVerifyShareDecryptionProofs", - "avg_seconds": 0.097465083, + "avg_seconds": 0.100550749, "runs": 3, - "total_seconds": 0.292395251 + "total_seconds": 0.301652249 }, { "name": "ZkVerifyShareProofs", - "avg_seconds": 0.226985783, + "avg_seconds": 0.221828033, "runs": 5, - "total_seconds": 1.134928918 + "total_seconds": 1.109140168 } ], - "operation_timings_total_seconds": 381.878109416, + "operation_timings_total_seconds": 381.986468376, "timings_seconds": [ { "label": "Starting trbfv actor test", - "seconds": 0E-9 + "seconds": 0e-9 }, { "label": "Setup completed", - "seconds": 3.041689125 + "seconds": 3.0715085 }, { "label": "Committee Setup Completed", - "seconds": 20.243337708 + "seconds": 20.22829075 }, { "label": "Committee Finalization Complete", - "seconds": 0.007484375 + "seconds": 0.006707541 }, { "label": "ThresholdShares -> PublicKeyAggregated", - "seconds": 304.504600792 + "seconds": 304.143739958 }, { "label": "E3Request -> PublicKeyAggregated", - "seconds": 307.024598667 + "seconds": 306.698077958 }, { "label": "Application CT Gen", - "seconds": 0.318660917 + "seconds": 0.313315125 }, { "label": "Running FHE Application", - "seconds": 0.003694084 + "seconds": 0.003688125 }, { "label": "Ciphertext published -> PlaintextAggregated", - "seconds": 79.271051417 + "seconds": 79.884513625 }, { "label": "Entire Test", - "seconds": 409.917920083 + "seconds": 410.2113715 } ], "folded_artifacts": { "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000469753df342aec0e0000000000000000000000000000000000000000000000006e4d829d66aff749d000000000000000000000000000000000000000000000005f6499be2b18300b20000000000000000000000000000000000000000000000000002be6db4c5558c00000000000000000000000000000000000000000000000eedb4b6056c881e3400000000000000000000000000000000000000000000000867b55169f2600f58000000000000000000000000000000000000000000000001bc9f519f74446bfa0000000000000000000000000000000000000000000000000002b6d6df53885c000000000000000000000000000000000000000000000007269f9ee62308a02500000000000000000000000000000000000000000000000fc8ef0ceed9608e82000000000000000000000000000000000000000000000002d32a3b72f08734b600000000000000000000000000000000000000000000000000018a5af26897d800000000000000000000000000000000000000000000000665ee11e35db35bab00000000000000000000000000000000000000000000000c29f716629ef9a6b300000000000000000000000000000000000000000000000ef868c0047d6dd22700000000000000000000000000000000000000000000000000026ab8350fbcd619e3c65ffa1c0d29b2cd62700cf8d71ebcb032227e21f28af6c3d9993353159827a80a592b60afb7bd0a5547279d7b7b6d745bd21e61cb30dd2fe6fa64ed7ee81bddec82e6608821134bc64e48afc548d54643761d84f4518e91e1bb576a9b3a1efdee0270f6a11edde9c2fd71e9de5a134a7ffcfa996506f17b7ded320b946905e9267cb38c0568773f0534e90cb7b63d7211d220cf75c33fef50d1b5a5100e055a47bec0d9798656da3a784b526caa90e53303c14eb63b919c2949535645bf0d9547c8dce32e13dd504bc6be4948f9635a4189cac34427ead69640255ad33c0d14a348d9edcbdb6ef4d4b0a379e7fdeb9801b76a0da963bdb56d89ba8f3a0210b7c42426c99152b8bbcdf2b36f1c1855f0ceb7482c347de29259ad7e05498a03d6dc7925daaca12e8661b8410ba878a1497660cac39150a0d2d1ca7b556cd5217867ffbd422a5ec0f3eda032d0da1dae248fdb76aa76f2aef8583db964d1491f5aff0a8af8585259f308839565b5bfa984c574d4cf02f2552749a67f4ee7f91fd21add31916d3b40f4006b7a83ebf00c14999182cacfc3b853fa33eb52c4bc0d7a9f47486d5c9f5dc5f1fba6a4c5edebfa27f2b9d47ef6a7de0f966356dfac080b3dab741554edf23aad2a27840334a132e4ccc09bc438f503346aad442b0214216a2005c8c7a405b68cdc0032c8a6f8ff1c663bfcfd165d7de791193c31c30dd9f2f2f2a0431be2e4e4f1fe5b4be54f4df8b761ca81b8634e42a243789b7219142015b3808efb3a739c019f139df3488006f7e463f6d19fcf228bce9fa6d613cc0c01c36911240ee0501a0cc007655ea1fd15b8a1ad2f8d1ddf49931bc0bf177827b2cceb2956abbee92ecef40924cb1e618efef90f0194b8d8df4745ac94211fbc877e3f1c1843dd9c04c81659fd1071b38a33797f6a6c395143aec09c8901b9d02917af3362e348cfb2e9aabd53ebbe6b3565508163ea1901f214764dda2cc1ea3a3e121b0655786495091b1b6eb05be9d77b5149795f94e4bec6e2b183149dc7fb2a6c49197a09199db3d00a13ed9d3fe11a18f5fac973b7349533df4922301951689c04b3f866c7f8425c047237cf8d409e8ba27c49e924268817c9e9055066deefa06a0b869217f5fed30835f92bd9662aca74e8b06d29e525ade59a1fb24ae716ec7d331fe77e298f28024bb1fdcc10c4390920b5592dc36749909d0c0f625429773d2393a4f713600cabfca65ec0617333ae5764f69790a9f97bab2f003fff339c5965274e74d713ade8d48df30bf48503c109d9e6c124b70b6277299d62ad7b2b7138796b217dbcc3c4acf6017e1bd6fdbc366957610a0f79eb4f17ed4c180fa64e56f7ce6c9c3aab320f1552db2274fcd7a4576de6cfb0d3db3c1ea4b1ce1f3afd3ab96c2e78be599e3d94f43d7f89851fc6ed825d6658f005e815a7cd1bd26641e038a56293b8095be2f287d24612af3ed6ba44a1f3f3a911e3302a5476eff60236e0580cf8b25f9efc8244b30ed8786f66e39dd4456aa4f024029eba613ba4fb9a7994e9ce5afb6923109490c62e0c988df549f2e9dcc3a56829bb3f7054a4b8cab4aa1769fa658620e87d592cbc03f9a71bca647f275288ab02dab6867241f0d9d7a67a4b33933a1709d75274bf5bbdca414d3ec79ed120fb064ea0f18c25252dd3a82b941e656196dae6336b385dbc60cb74e8cd668c6f631fa549c5ccb417790c6e015e9adb9d640012eb6c177e18eb7a319e4fd7a266671c31bccb4604b5acb7226d74e075d4276b4e9410a595e91dc5f864d35c6e95b72d4308c3be58dc29da40e25d1f63a36940f572b901c39f31e355b075dfc95a2d2092ece23729f1bf832fac0ec1ccd994f016562ca1efebf54428b688f1603df1076714c5d7d7ccd14a87225c15c5178ecb331bf323ab74f8240715fd0166c33605affcaa1b4b75d30f034659860df6af13b6ee9e6e5c1cbc5e131c2709ea226c11cf137940d661f8f254ebfe274cbd889768cc23d728cd2c5082012f427228cd21cf49509a55121e5756aa33e207a548d5a8f15e9f4869564fb2fcef1c4577e81f237f271365e73cbe12dfdee90ca49799cfef0cc0af26d57ac820007cf3cfc9073dcb3915ed77c7e50f58441879c2c5bb450ada48fb95182dd02943e980031a257c5bb6c116e0e17a1efd1877dcc3a988d9b5680f05f5dd7927bbd0336c143c0aa03fbd503e48787f9296c4cdb00160adecdd0ac45174988fbc535e86d6e4250b3b669d61dbca0afec215f54337b74b36820a3794c4824c9c812aecbdb860be238bcc0ab026c45a1329e6ccbb1f0e6abd83cb9910e5468c9e22ce6c4c3c5d1b2892318212462091cc6f082e3946445e67456576206a0777bdafae6420bc108d0d545b60b47a8647c9acec31abd3eb4a940ce24304658f9ce2ff50a5f5a656f80dcec5d9ed6e857d317c33e96e97e19dea73112a08b301cee1c5a26264b2033918a03534a00b9812d0dd992842efea7d0323402034bef78dbc11232402264318246fac64ff0d90acbd0b1930b4377ba08f35e91ebf526c3802640b74f6b786ec118f486e979a8f8d9bcc19307bee149a5a4d459a145723fa863d8230753eb1dd08f4187ced1f037867e3308affbc4fd535746aa6760d018f75bca7bf3396a59902320058d6cd5935e44ea6943d47fb9d45ccdbf8ef6de9a5231e2e4e2a1558662b10e223298ce2cc72aa45a021f1437be501b2743c08bfbc9708db8b2cd7a9ce17256be9fee29f8d3dbeffea7001aa6648ed7fdd53c0e9117d88379f75466d7c2cac187ce9ea645f137c8531c417fa019100cbdf78be2763d38414b97a6b00871a954bdc2d8e1df7970a636eb0e9d8e5acaaf827e955adfe4a8a2a43598a4cba094833c3e3dbd1f261a5d75b5fd313a5f240ff30d989823dc45a3c3ec90082c626ae27a87be9dadb61eff083583ee3568378e95a1ba75f4bfda023c820466f822adc5410bfa974d63142c051bcafb9f1b00ea44385db8cf1d0c36be3e71899c00cc356ea4a7f52ace0bf72913493c437e3a0cda118619333e1b503b29a7e008a0159746030e90700e49f97c957078dfe35497ae3c4fab77cc9c6f080f84637291d9bd340a31415e39c83c58e3f3b901ccf2e2e2356feb40dc496008982bd189118de77f08ce5a1515447c4a04a8c35e9c89f86d164f10d3df3c3701d8148e5681c027f18f613d5f5d6b22de99a7e7c5d1154db617adb0f4aa4b140a4cc4946ba2c6a68f07b9c6b738d4039291b0e7bce61dd330aed09aadba81f6658e15c46251c44e7e03576d9a2d902f93d2cc226b10a6e44adb7ac928f8275333365101c821d0ce2c8b77aebdb5aabffa4c641b602cfb62c3c98c9f966b2d950a193a4c6e4196464c9eab169d15ac12cf5c4ba880c3bb829afc21ada4364d6a4f81299de8b21679e06e1e557e7c831c03cdb1b8629cb925d4fdc7d44fce7f4ec1517897ec72a2ea327bc07437e1a70ce03392e1d739c2f913698ee590e86c3a7c5e01e70292b73f7dd483bd896583d2bd30e736926227cf981f05cd4d718c6f8025127da4b205d377c16c2d412e76aa1486b04538dee538376fe1522413e41df227cdd52e72c8c867f4a3ea87ee1328f964365e79338fccb36c83a0518445e3c09aa2005ef15405379466c46a41cabae490c736d70476264f3b78287804bca97b68bef27c409883a5ce11bb36fe046d33a2447f7cfc35506203a2e3a01d389c060aa3604cc237fbc043276f8bcbfb7d2d1adadfaba9cbb70a9220efebd6ffc62ed96bd9bf02387189dc44aa75b967986a74ece75106f97c17256baec95737d6de103c6d7a2118ed1f68bbf4fcb6647e625e0a210b31dd9399f49665aa4c27d88a639767a521dafb03ac0ee4f48394d53fe6d209740009a1c11886f6c721cf91e29e268e8cb2a7dba0ab3bcfaf639f230f5cc32a443d1f9afca79a77113657e12b3a4023f130838602c3c9bcda88afbf7ce8fddd16060ec4e0e955bffe48ce7795a750121a7304f58bf35b291bff1e28314c5e1aec8a7301a178b3e2e76b81f27951a2550b817406d894712963faeeed76b7069a0c164e685255aa0ec245c5d223b36b05f760307a8d077c47184df6356e68a3df1b6e645a7a1f68c3a4ec30a79497dbeee8821f4cc5aaee04d9c0c28cbe66e5cbcc48994a4efa36572343f005e385aaa301e157faaaf53694d880169b06e0699f6aa01cd14868786ca9be54a5571ea0791df156e53a49573829a7493415d75ea54104d64b800d4688fe718eb4069b59f93162277d97ac74c5836b5078e713d2181bba46a58bd1be7cfb2d359473be276081f1b6ccb434bbb6f226e9188bc9bcc75826becfb2b589244ff57e97a2994682a3e007aad5202beb5bc1a5ee1fd908cf63b2d36f76e04978c164ce4d36a3646d7581474432c9e22f05b48726087539ee97f746f73cd9d414d242ab5bdfd7609d0b32155a9da08e2067a889517aaf8cb024a8168f94dafce6f93b2f12dfc00641d5218c35fd80cc79d0b4bbb1f766f20ad4ecfc79ca94562895c78057587e9edcf1211fca08a404520fb20794782ed562767d84c1e6bd5d1121a2b58b63d633cb3d528392519b02c9a33d6200c2b94bfeae8eb83460ba6ad4dff419969ce80ad48540cd03c06c82c17abae5a66cd8db314d6cbcfbed1472a446afe81b08ee8e710121bbc002b678d3e50d223f02e4edb538e65fe35f26fa0d21cd77169d208d1cea6188ad9b99abd82c6f89525f6f1034be005f761a9503d049c955ce43bf0997e192ee5118d2c94ab12ba2df5075f42f1572f28660109c53a4051c8aeefb2015915127447e3992602c10f17fa0248d4a63d3fb51d02d7c87575ddd2a228838d54e015405e3aeeb0eda949ed50111d0881e0d2eface34b66941e9ea7246365202f1d207ad9eaf4c7ea11527fa2ceb4c32496270b04edd79eca3542d97606c3ad946601d47aae61d27411aabf3fb0d5c57301ee1ffb7c01ceb4d04ff39180475d097f2b07fc67bf89790286b97b1d814ee45b760d49ddecf8dc3907cfae048afc82550a7f416d7de4c9a6e3a847c5700b4642b637ff9872096679d2d5921eee91c5e11110a2da4abbceb28aa0f9b4bbc132493a2ec0f2712ab0d2cb8d2c589168f9af2f14df7d9de5d4463ff031988639bc2bc42c844a737ca569dc14045284ac011e02992542a5ae3e06562f08bd9eb6d695652b0c0207c3514b292402a5745a60cb22cbfa325db3d30866e1739fe38aca41517e9076700489344ddf68c38c28ae9619b91304c3e55c8f4ffbb089b13b2f04ce5d61caad3d2cb54341b5d1a930d35511de0fd7e69802c35962bd45cd5733a23093208051359e4257f5c9cf68082b362f3744ac22c015a9ac28540106e7d03ddc305882758a50c372a580e5d70c09a720755d74fa777039850e88a289095bc3fda6e3de76a661307c2e77237916761e1dc2e2fb9e5e3e31b522be2e0d8f2e3e7e9cc1dfecb73a1a79a0e26c7c9083080a1e1842116ee304103ebdccf52062bf9578e864afe05f3983c17b84f7bf4d1209460b438ba34839d978ec1c5bf6aab43d09bcada67751ba23a5d39910102bec0c09b6ed88010416941c845ff0402963a715b14ae1a371e9f1913698b402ca86250046ab1d84ba0a6bb12686cac9ba831fa28fa3d0ba72589da190425b42548e220351f64ece113e51fdad160958af52e544b5d08fde40fe37bb84cb659bf593033e291841fa82a53a8f2c141b596c4ed461f562e632b2ca893c12a53bf0de5d2f084d18fd57562a366766d549e205cb36846670c81b92ceed909400a673e53223e9c3b1001c31f367bc9125089c292d5c65dbe914f59cfb0c1b702c7847f2151732806c02b5aa5e97871f60839b79d3e6feef3a3f696115c06e05b0429e1d5321042be272a689d6010378e100c44a1ea4c1841d88a61ded92b9c04347056b3e098fb4e93729884cf98a415354961cb468d38c8c5dab2466952e1863952de5d22bce831cc9e2f11fc39a4e1911e4e391aef8fd7e2f2868e7e8593519a4dbbafd163660310bbb68814e644e234d2a6214d3c2d84d5e78091ce6a3167f992d6c411b70840ca25c4251db8cb551e4a37170bcc4e0aad6a73ca6eae85ae85437a8c12fdf8773e4d6896da6b5510c65e8e5ebe2214ce0aeee893aac3b5169ace00fd20cd9084610949486651f579981d04ce71f246593a621b94b11bf2d4a53a9b7272a75ec707e5d6e9b94cba7277335b4dbe3a721bcc5d8d33f2d6521047d8b2e33035d2aa05920b16961a8e9f5091d1e8dcb0ef43ed663dd29d95e24307a3cbb14248a1fde5949b811c8cb64d561a5814c4e42db4c2a82ed3f85428951892885a92727050ec02883b4fae76a8ff11f88b279cafc825d492c8d88e6a21b8069bdbe3020b22284e21dbc649e9fea5576619b0d5a6c20662adc00a8cae9dc666fe84d2a33893fe7fd23a4b3602b1872968e09b248a1e5f009b8221019113733a639e314bce17972dd81107ac90a257fb403b80809e8a41f298cfeb0be9d87341e9e8026b58446c8f6efe18ba6b664917d764b67f883a1573207364f3a05ea5ac4124a247da1fbf361caf35db0991d02d7cbeec4e6867b454e1c728cd64859a18ff1d72ade435bb8dbed3cf274c0830a6adc7e9aa296f01e451882b007fd972875c54a2a76150e904347222648306798c03ad2eabf742dee661f1ff2ee8b7aad5061f408e8c42347c0400fa8fd99c1e5d560ffd9c45e274bba4f8e3de5f6899a9eafbc05c680f29f0e759926432803bd257f347279ad57e0cfae3ac1820766f2bfa89a2a054c1318608489a6149c8ce98f751f4f90897fa87921b04885242913fd053c29d2250a857eadfa84a16b5b4ded1c2f89d817a2e005da0b94a425b9890920c829d60b0fc66656f0a79faa3e5496317705e56c49f69b3732213b652469ede8b62007b1e8209e5e0eb0842a86321e49413e7d1c48539b8c8689d932b368452d8f00a415eadc12aeec854463da5ec3e848343d7e035b69fc369e03b45d426c80cc21af387870e76a693d616c271e15dbaf75d32b19d1e6ccbc63ac71e155d002ad2992a221a39a21245e9ce4d06a5d450398bf7fdad0fcfc4edc1f12c3a109d98d1b24c341201ab7ad61528931ed868d4ae748b0935ab27304779ac23257a0b4e40fcd390fe49200b9b9a086a7756db0a14b232ad01be5356c40d31c1aea918a7206b55b1f8d4af81e1cedb29c4368641a2a5d2440c70d6908fde350ac8a26c7f22d3b2f21b2c3632af0f2e9f3c9e52e99d9afb03fddd83f09cb28d206f67086000dad45940c134287e81c13e4bb5bc22ef82e4c5e061e69084a781a21997c063010b394acfd38162430147456b9de74aad70a060df546ca38407bdcbe464b01aa140d5bfd0a61d5158d157b2f9eb42ee971192939f25f02448cb5782b36d5ba5413dde40e8944b03e710c31402a37c420dacb73603c0e62af12c136f833aa3437064f488a6685c8f0b0c291eb33aa33b81a9e4c513e6ac55c7175c3073335d9740cfe4ba38839d89625ce94c63e04178c0c76553844241b8ffbf82c53237a02390282e7cff22065a0568345157ed5e428b107946d5003cc6ac9718b020a21e589158a93d1249c81b6f5edc19b1a461d4886f40991c89be5c89ac77ec5486d77b12852972575eea908a0d0ad066ab7ff71ff02720e41b559dfaf5cc99992a1e82b267146784c9faf18f0a30b1d2c8926de25b4a2b5d4efcf00aee059031129823405e5c2b04465b50e6a6300c519152d3b175595d3ee4a7c103c90a46683bf33900973a27e9d6caefb89a1d148934865286ceceb2eb2a6dcffbf93f40d6b8141f32df15c9b7528bf722ac0cfcd16b5d3b5992965d3f49c62a5516dcafc36be9bd117d498ae3e827c74807a0f6120713c018891bc502fcb2f3a3ef5df92fd36e09123278dd884d45abba015519edebefbbe07b19dfb6eee736e611a001af8182f7d28d2df78f84999ed714f241de56318517b31798f9bedfae1771e43d28c74ec01236fa605728da81f251b890f3ae9375925ce406c5808328b62d0c1f61d507fee0d603e2271f6256b38c56b4d51698152dd71d572f18aef64bb8956cfdbbac8291420757829b48a402faa763299af4f927add42dfe05421d6f381015fd09950cb1d49db81efd5ff650a753c43ef4d6c56742c82663cd9ccde44c04a9d16efb3f226f10221eb3fb7fb9cd29e0ca0a9bef0f9b7ce84f43ea5bf4c7497642e2ee7ea1cfe335df4a4cac533cacec297ac86541cfdbb6baa5d5ac993ea49936cd81b391fd9942ed996e79fa851a07adcefd1c2a8b8f57810e54d04a23aacb01abdaf8d2e2bb8819d1ac0ecd13c2e7af62f8407d63039b06b61192c4d7a82f65bcab66e05e769b154a29cc138b5119a732f22dc15ccdd3beed12318162f437d9da4532508b3af66a3e7a10172a476ec9de4a05d3cef956d6ad5bfbb0ec8923723117f5a046ef296f2b5d88055a90b443c25e5b0b877e3474f28f2cdc79f49c618f44aaa02d3d1638363ea5018f4710ed06eeba5776f89dc9dc4afc3fe942f92f90326771de423f8057cd1463a148594606857c7410f3de1767f89e692f64aeb9c80dbd6063943261cef4c11bf08aa50589f51ac7125d9fd81d005b2ddf1d8b1c5e7f97512b4bc9df1655304994d4c05d0881eab395a5925b935d565194e3db86ea73f9e0cb618907cb0aa0d73720855ad56a543d380344559d846d0c87d2f66c010826d2f0a5280fafcc55461e94a95c98123087fe7c5afd72020c01b5bb159507bac36081c5efff00bc7e17f6289e9d2c2c5e9beb2bf4dc4465c3e954f2393e70ceac216ae4898e4821f8dee3c88d8c1085a01d6abd2a23f0ff1f6b92df037992c73a602cdad1370bd59f65f93ed6344a19ffcfae76acee1f8e2444d8fa27b346719541a4dd20cb3c9f3dc615bac655270d1362c9edad97c23f13b6897d65ef2e3d67b2e948af7af733a7252895958bf669fb507eae810fcadebad364fbb3b5d1a68a1146f82fe31c5e8c26c46d4fd4d134123c591bb36cfce94158faadd437ae2ef3920ee3821c8ef268c38cdcdbb380ec23ad56abf2c5cbc9fcdc291c02269af47df0e6fbd50a5e974c1e50024975c390f43b6da32df921c90f11d18d6577fdc99c120126a58a070d74d076cd1b872e0cbba7354f30dd38057fae7023c6dcd63527a1c00ad87e6e3ba05bda510ec142acd5a3c662373ac3f7a7cc8a10ed678466446176938d996ea81ab6002cc8f4c41e5269d007637a81878e6bf0bd562e0d1b60e10da7445419432b35618cd61bf90079a08b5a0fdab94cf8f36d066351118484606ed4fbf014e02b795dfd62b14b16ba950be77d5c317dd70fb058c0d896e18a1073024ed35b213beac45d0eed9cdc684c954bdf3c18f365dc541b68618b8c06e1d8a83550339c96e752a82d077cfb8ce0211447e4bbdbc3b127712004fb7caea05d2641dd30ce23b7d8b9c5530671324cc9aa1bd271ac6c9be835fec30741fa103c877e6c320cd6c0bab7d62d3bcb698b6605be618784663158b717f37ab03000f60911e4d3e33184fd26170e83152da85d24a8f095334e59b7b62cf4c2ed8400688807ae631070c134aadb8290c356a9521af9333a69da38904671ef89c4d97004d118138a5d8f7d945a78c0abc64881ac3ab0c86060db570be08d3dc2445032afc433cd6ea04a649a3b523471a5d2ad1431f3584f5142b2b5046b5f39bc69d16565ecc4219043483b3906d8e2623ca40a26cbf9f18f51ac5259545a592d5f827e0ffe8b7ff77b8f63b0ef131ffa4c5667134828fe82cdc754d15c7cd33cb6c0077f04d332e7ddf9956d603ec3c9c0a55e1db71f19642c7f876452248a70f3b1cdfb9da087a8ca3055014df3aac51deddcbc64dd8d5a8a221d8e91e749b308113fbabb99460f5785f829d0b922389a673cb6dd7cff8c3d288a77f07823028da1292b1f04a858b4630c8306b8fc5226f918328babcef14b9dc10c1880582877e1d450f991999bb052fa475bef0846a915a9d643aff92ed06420fcba96e673339288c3fc6586c13eb5f581e6e7200163a5e011881ebecf259bf2b84139ede52f60e389ecb2a3b2d75a3cc041b4fca6ef2cb232527ef829a8476563013a4d336e204e8ec63f06e0917808f60401e320069d022f661d3ba23965bc66155ac3623f30b29bfc132f9b01495f4c869c57e8cc42cd2242e72fdca3ae4727c02d9ac881c0a145fa3f17edb13347bbd19819e570e3b016cb952295952683f30761f4f03cc105cb9a489ad41d21c68151afe3def6129200c5de1b932ab352119aeae31df5121e519547cd28f05371a2c65f716c239ab69d20fce2af689bc05f99ce4247cfa29cc49b35b4358a3b42ae5c91d95fb99655002e2b0d6d535f21a6c58b9f82a2119649e434ee728c3248ed73b956bb9667ca6b77443651eb331f0b6520d62c5852e3370acf4ada80391db77ba155e3aba9e8d821c2ce1d31ec09f9898ac21b1112dddc3ef15cb12590a98531763b8d043596632648e08f8b80de1767e74855ad7259558e9228544d393351f17db1a37f55314b6d2a39ff65ff22247ce74073deb24cc708bd37b6ff151588a7c0d107521ae217f13afecd55265888f3263cb2bc924a1faf27e8345e2cab32ebc6aae03b62d115631527b68761882befcaea90c0102a7abe55e1764b18199cefbe32acd68f76650b5a83204dd677195396700b93e268fd11b30f6aeae2288c6b31926a50007a0e85eaaf2f7a6c3c040369df5111e1f8e3e91e40e7095ea9820a37d8ed5408382dea8fa3be255dcd2432ac79c3b2a1072aee7d8c69cfea210a58c99dd9c158744bc20b17e8dba95c49091b70ba4f4038acdad5293ad3f47569799a1203e607107575ad494b4857aa06a2be9d0d4ce2aa07260c845899f56d89fbfb7e18c24130097b1e41bc0ec6d7243558f2191bc1ee0b5ece2d0d55c02d3abb80cfd8d10d6bbf360068dcf6cc17debe3a4e8ffa3287fbddc25ef9071872116ea57fb9055a978d85768f3dc162876957749af16512290c1d094e99bde4c38c864d31bbbf85ce2ee488f943be32e2727633089385f2b461d8ca9e0855827cda5fb219fb1717ff0a838ed1b27d82947288e5e8c14590e039cc9b1ab4a33501362144ea57353d0ce3ae7f845bdaecd9e1304b5472ff61d5f0fe5673507d3b79974ae6d6294e16ef1918a4fa4a8d023e89823124327d21b74fe4ae3c1ad52801ad8210a3cefb6ddc0297038ce08f9e4f49ae8f1f99e5e293e702e81f1c7861c1c445fcb48d92ba77eea9b250ba2967d506925efef7f261ada0b3d9f2742502c26d1ac9f750649cf0155a7e327a3556b2bd9f20e009b9601165f5c53fc4b398b8f3f7413d065aa3fae26a12917fdf716f1360181fd1dc81444a57a6b94fd298742cfadfacd30076bfc6ab47be4f09b66cc76b022a47ca5191e725f35288a70698d51c5cf43b77c2f80b2b3bd4d35c2ea033008cedc2f042eab11def2bcd80ba95c3ee8c4fb917435c62c6aeaf2f4a7131b429b5cb2a4ff23081ade5ac7c55b647aee9aab520bd3869f9c93c36aa7326ca6bff7af3771a201959164e8a0978053f0c13e7a87916c47c7d7ba0d1f1d1c826b8873eb31f7d22a07070f5d5fcad09bc1de1960c10ec0ee3285aa2dc35bc42d8b206ddfe119b621ff709b9861e00dff5f5caf92d33c79082c90e3e9a811cfb225ccf802c6c51e0dd1ffc5d73e22eecdb9be76ac089ac3cbe39613b2e6f4948ae91a42c6ccbe9f278c01e611cb037785788834d4b7306a5f94e0f3bc26e9731c53db35e41fd2b41ea68bb1a63e21995c245b20761bb235c4bdb5248afed40f7531fff2a4e300c80ad0019f2ee27ac9ab8181f077b7a0bebcaf59459cac8ff3758a91b051e89dee24ec65c2bd9503a6ec590079fb13870f775c5a56325c5317a88e5c439303808c0846b44c4526e81fd78c7cc680ed2993cbf600b108e88aeae1e772b0b0f8ae5806f883cebfb726b4263916b6969cac42ca7a9e5910be070fb64d007d0a7315d91daaf0e62bb35b5e24c1e2a5095a294afe753fd690a0f4bf298d5f1d0e3fb5311399d876cf50e48fb817b3e8c7146c1d061f07f7d0710e182991462d793227590788cd56236e23963e9a41d9b6fee0eca464fe0b5ecc58b78151f57622a97ca700863f02eb1bc9d78d1082feb4f383d1e2eb5bdcfb4fd72020922208eb19f7e809e9e7b184a15bfa5a0a43863b5de3e191059cb78bf74c53bff6104e6c5637ad0121186bf2df31b19bf8e87fc74d1c71d8d520f181c275958a409dcb7bac15021cc57260697c1b3bf9c2db1a1e87f6db39677caf5445f6e85853823a0d358472092cd19d6850a62402d1e425a2d7c0fdb61d2e02f86928c3fbc56d2ff048147b07b2e6dd21224c6bfed79c76e49a5d79a1da6722776e2c4cacf6a71f4fdf8c3421001e4747173ea80422461affd27e3af8ce9fe9eafe6bd76e47ca4bfb9f54e01787798b5ebc4cf20038ab846044605785202d2ebedc82441c938599daa982200676dab42c70099280328e8899465ad1cf74bbc27cefdbabdabe85be02dcc6be2780dce9f7f6b97c77bf7284dc71ce4fdf48f13b36553b372bde71f04c1010f719c9e06ad95bf42e16fb4c5e9f5779cecc8a99830b62e6452cd80f8843dae91517bca2479d53cf305a9d43105eef240fcf12a391e92c49596770405de304801d27b4f39ddf78d44201072df5a66c3753d6cc740f42fca640ec8a9c2aa509941c2d8a8d9dda693b87dc33c5b641332770cdeff855b01b7d48304376e48925c963036bce8d831d7efd5f879447cb403c7e4d7b01c62e0ded5dbd39ccdbb545c5f30bdff5b42ced0c62cd22918e3598f7a6cb7c9cbdb7cc8cce49be5fb57fedbf702e06430500eb0bc6b794b6172145c3d7e0b18e36f98f98861f8dcd0511b707b91dd03caac365db1699acc849db995026ffed7dedce3505260acbf7c4b09aca9d0b09ef40ff6a704425e1195ffcccffca50ddb4c9cd440fe5d8f918774b2852b7177d38c0a40a9325dae46f5c11c30c0b4043067451cd714925e0799f22524d0d0c2997d8d76af181579491ae7893f4d087b1daaf0a5e38723690b34d70a1d0d32b0eff8e2c99c5e155e65f42c60d0fbcc7604b757896e0910f97a1f49f6283ee2e09e4434f0300af0e0abf8b98762f5c6295427fe8e0fb6748b7e7aafa26b02b1d819b307c1f70a1a3ab3812f41571c1b85dbe9603288f4afce9591e8449d99a0c07aa3eb97c33a646725cb03d52fc53ba19064ce10ae7544921f23c2eddae110359572c3d7b81433fcb47a8ed65977667fdbe70a029dd1f9ce9dfa4db220f8a2bb209257dd8d49b864ae9621cd32e3772d453207bdc88ea8be26869afcb5a3c114c5ed52c900da7ed5489e6e199c7ff224a18275897d832bfe121afc7d663750613d5ad6f4ca266eaf1f69c6e0f1617c647e6a5830ceeb3f4d5a2e70730fffd259aed34a0a6d955f29fbbbb96a7051a9b8aeb3de2c077dd632f0f91ae4d2fcc13ad02527dcaac974cd68ce11d09ee138b586a61ea77db1f4d8877146da47b710d5e19796318dca7b99638e5450448ed4b0776331585b6846d0b3f504854665421ba13580166db9ba74f35923efc566aca7d76e32ed30283f7c5b96a12a4cba7130476d1a3b19df10ba213cf604761861d3b4264b342a68811bcaf6c26c4ded5189b15e6f0deafa36e7396871fc0054270765d9cd75681bda91ef8f1f156f51528c7e724218c156417cabe8378dc773cd875b748baaa0360dcfec3f8b5fd79fa15758af830260018537aabe640e55fe9e8d3ba07fd4e849035112962edc1ff6d26a4bfa0e267a938b358a6d95d86a3208e3a1ac448dd043cbae10f847b76a8a20ce0a559bd0f3cba36be6fb50512452bf06915094f7a7c7b1a7a517c7fe3a666249c3368fc161a3932f2d10cd88276932d3d2315ec9bbd8a1511216be52be76d1cc48820c98e773afc3e24181c2666fe05cf22c763103498316ba0759750d575156016a55d457f3a538a4822d1f4dc598d9c9e25fbb0381f2aee56bad06d5c6a1430f3a6fd2b33477e72b8f91a066301dec27e6c9bb69acb1fe54f692ff9b20e14a2a71e577f1f5f7064bef074b0654239599257dc86b12bdec3376250f97f5f005ae534014c6a69ff11c135d18b4dd33c13e4cc11018b7445104b16e6d94b580049efe999a49bc660ce9f8757ea3456c42319d1f91e21277ede209bcb9bf2da1aa875a2c36bff51aeff4e2c01151a0243d5551e016b5e1ef76d8a98443d304604391d823e2248de66f8a0348170e55f5b635d380ccfac02b8fc88df515c0ddf26c4c9d9b7980a35b819aced7c720ebe1fa773e33e84c79dad6f46d3f9bc35e92d2c337a767350d906769ef475cb72fe2e03ecc358f1ee1074f5d620b36480f21255cf596afae8506f5a7b164314cfd890f45fadb279bcb742345ddd9007b4492bde23b40195702ec4cf12305ef29d751e1a31c1fbd3ffd9d29fff53a3dfb371227c0f79f3487ce0e76d7188070768a8ca64021d32ce22f13989dee1c46be72b0d2faacc65a02532940e3759cfd742171bf642d8ad3321c96fb7a6da32a70300226f637fe241477c36bbcf1c01a059b520194003c1f6bb6983d74395fa5b48f914801b01405c4d89b666b6918ca546afcce05aa80dcc4da69af0bfddf2a5460e", - "public_inputs_hex": "0x2138b0022ab9af3c96b082bbf307bc9e79f8f1401462e3ac1cb3a9913a5b856c18c40bec999a837ec1f06dcee05102acdef50c501e771cef739dfd0a4cac5e9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000211521e0a601b59f0fa9d199e9f861874db5d701a0c38f6d725d9fd8c1f0b53da03219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218625eaefc46d4dc1d14d29441b83268d90e246af546b51272b038fd206edb2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7296995105557a58df75d3a42759d29e124a15ef43bad6b7fd6a9d93d4efda1c900382d23bccbad9ba827179293d23b719de8374589fcad5bc6d2148bc787593a" + "proof_hex": "0x000000000000000000000000000000000000000000000001104c69c76ea8f5f6000000000000000000000000000000000000000000000005c85075d6baa615c900000000000000000000000000000000000000000000000eb6de0b1c015f0f2a0000000000000000000000000000000000000000000000000002a0b5c2857c800000000000000000000000000000000000000000000000036176084b0205127a000000000000000000000000000000000000000000000004549377f025fd0f40000000000000000000000000000000000000000000000003ff07c8a94fbdbbd8000000000000000000000000000000000000000000000000000185ecac0421330000000000000000000000000000000000000000000000044f1f17a53eba29b1000000000000000000000000000000000000000000000004096147c1d40da636000000000000000000000000000000000000000000000007c2eaade9aae157c100000000000000000000000000000000000000000000000000023ccf2dca92b000000000000000000000000000000000000000000000000e02d12f90edb8cac6000000000000000000000000000000000000000000000007c223713eba54496600000000000000000000000000000000000000000000000ec928a9ef7dcf2da9000000000000000000000000000000000000000000000000000282e9bb83bee61a05d33c39ba3812376a494cad4c46e07e18763a4c0cc37c7ac2f3635530c6110f00693d937276e524dafd5fffac373d40ca9ac38bc4003aa97fa25c28eaae471e6801e127832204ea5a325f05bb8550bd90338e17663499f9908e07c1a27a4d25db068d58486c5ed1d571b154613b2a444f9ef333d6490c341531f43898470028e20e0d46d87d6e6a8c672bd88dbdbae7c0e0a9d06da0323fdaf7ee61ceb7611d45afd3c8ec55431dab1b693939c2a7f313b832a28959c3ae3d30629655cc051ff1a5efe96161c60a46f240cb6ca1a531353aec9b48b52ad525bf6481f17e0923676a74fc00629f08348ca4b4467e32b7907ccf75e78538096134b580c00ad016d8f24d8b2251a384465ecf7da74301f64008beb9c8b71af609a0085afa8bb10891080d365806d9ed9f21901108254290c057a4b986687bebd3eae86d9d84d52ba59894f06a73d164ff99fcb0d13873279ce4f307eef63d2c0ba38c4624e95e009c113dba40ba429e2620e10806283dd5fad8df1b6a85051c1f7167194c70620f370484b9bd06cf6e6199ccd69d2c0e0db004474b4ffc62084f7697d21fc04f1518380c30df7edd6752046611f209863dd69ccbd4af39b35e05dbaa35d7aea81dac6609d0b9b649962dd23bd220709758af7743abf5395724f809100dfd19cb13ee772bc80efdcb985314bbe58feda8ac8cb79523fe9ff183ebf3e6835eff81084ebea45358443421fb0f2d31a11171c0537eaf216aa68a5bfefa0d02b1c5b92a10ac9238f294ee18007a6f18f72214951c398ce84c3616bcf3c79e0f2e2f022a0c90527061c47a42c43cace4fc879a5a326863a6f82d9c6bb420290aa900d8244a98b1668bcfcb6023d101fde9f2fa579bbd8947480f7058466d6000b38c5c1a4fd3aa5794aad136c957e92be80cca60120b6d839e54f1036f9e857e14746f2433e79c2a2df9f7ea53e60405fe812eb086dfac1f0b0c638610dbdd208a28f2260c558292be011ce1ad7ea6fc1a18428a3199764be0e5e4169e261b655ffddd06ca1104a26cac71683ee832dcd3cac2ca05e81de30bed5f8b67ce620c6f88f62d90a64a9659cd90458edbd62bb6cc9f8d942669ccb243386ee53c938746a2462ab0830a5ee749ccf6259eb0ddd308297e3093c1e2bf8454dd5e900345907a8608b9832d8e40d08cb3dbf14939398e8c032b1baf82f3b45da26fc2aa8a69639d1379060a52801809840916499ab8679e0af7fa2b5e549f58ddfc8c60090ad5d42fcf59ab9661b29f6aee13a20e279602925e6fffb2328ef1334585e819ea8002085571a91540444e60b8c9350331f5cdfe8ba889466f4b26343d3b179b436d1015fdbeb6b1586fec95a850abe17e3d23dbb519b068c9c59ed740833e71319db516be4631e64a10edbbdfac8daafe9004a1dfb5631249e558132163eb6429c715143679b05e2edc9c236a9a7ca760761c3a117bb03755bf8d04aefc7742ab0ba811710087242ad211047ff4f6b9c4f8faa4640f53721a400815c301a8b079d1ca2b7184bc65e7bc3cd2c380df2376ec233411c4d429fb12795cdaa8b932bff94628703868796573c773ba5a60dbe2dcfdba86fbf73e2cbabe306511dd6f71509607ebc04687500585f37d8135ebac5386803439c01b36e449d3b029c1576fc2f422160f4fa03d8f11c89e134103a7918939563aad5285049c66b3479d416852b11896f8b31c6d91580c0cc03bd04ef40a9b201d686cbfec6170ee5a1aace7c7f2248c548038c030a7c267fe72915cd397e273c42561e11410672a1e41f71827eb247b679c4eebf11bf064f256f418ef2364b7eaa29fa9cfbf018eef1952daebd915d423652908cbd25b28b3b07d28cc918af5ac73226b02d6340d02ee74f643db15c870a4de33c870580fb55142ed86a7b1efb02d4f5d1d6e074137126f61818d0dce8e49b8aff13f2e80fa7d585aff6147ee7265bc92df749635d9cd77bfb87508e4dd08b4f437bb59702e34ec8c390bf6e7455a4619bb3586688b16e1045a9c0c8d0b760cf3d11357e9840fd3e702cce25045c7835bb1b0ce6275af5571d18d1e90731123ccd8bb5b7550b8ba901f3e94958acb3e9583067cdaf68cd913726817755888db2a7a28e1a4748b9ede248fe0ef76aa51bf8e5eaca3049ac9dd7984241212bdbe5b3d0d4b586a7f468056893fbdde4c94203e8ff8238fa1a028ab2b059669f73b36030f5205fcc5958017fd26f9fa8d827b6cf11aee31fa922e8f0c21c5cccf059ac7d29e54a4df6f1e43b8a4b22689859e8569dc98990b9fd1d1b2222e19e76cbb31fff18fcf40798cf42482bc063795fa19dfe65eb6e9a570b4c41e85f9c94ff56701adabc0cdb76def2f5770270aa236e1be1c18ed64e51cdc911a1133e096a0272e0675c680fe24f2cb4f9a201401977945b920b02e60c84f3309e8ba8688c6e982bc9357327d438c5d34986a3ee5c88fc5886a4c66f1d14ef625d0aa01c82cf320cb1543887eea14b4481733f213beaef47ad92251eb2910bb1c23b4c930200102e6ec848b5470cc88a0204f6d4a9aaa1cb29e808e3cf2cc7622ea3e6a331b26e1d2a78f90b99066780df63afffc89bb080ef954828fc64a9b0e589c3d02f1f8f8c03919178dcd7138e1381f54749a684c6c7f852b0e85251427b6dad8334cd11f9f2e16ab2d7654d1dad887e5dce9d872887c6dc9d07f45481835c2ae47a1c0c9b680a009ce8218506f77c3b8b62654b8fb93043f60dca8992c4ca79d52dc8431a240cc5d01a027438fa19c91f638b7cddd6db1a1f6faedbe1c7eda2cda8637e7e0a2f49d2ad0109f7a5bbbadf6c8478ba78e716fab26944e182e437f00afe8873f1030439bfed6f6bb3abc39bd1882eb2b6eda0078c680e924d942cd5b55449783c3a8f192e24aaa6c305167959fe1cf58e9065a7784325c2d0fe06c3e064f99ebc1570a82cd43c33ea443971e0f434ac11883fe84461b9821746609c618a3362bf051334253a22ae38e9b6773a528204c0797297835f3f61549c8cd8ad16bb415ada181c52d843d558dea5cd548c3823ac4e3d6df1838e0073102582f62d7dc0ac66710e9d0e8826ef77755403b7f12a2863faac6dfe4cb1914e29db1b956406e9f46ba2653617ac8ede05dfb69035dca3ee5c2d00d3a612ec25b4fe71e06659ef23bb53a839b6ee48c4e38207109e68d3e073fef16eb062dcc3a22a15afb381581cd7e9db2c78f2b801ef7104a5ffb41dce92caeebf6141190682aae5ce74e6b6adc7c901eb6db76c548746b9170a1c81930149032b19c0c0ab947223f7d82d1f7fe5930eb75cb6dd0bf5394a906376146da02731747ba17ee40b5061140ddbffbf7b01d0e6661cb6d3cca9eeca0a0c4640c5d61c72d9819f1b54c8878b1cacc853f1ca2e3ef455bd082bf5bf60e4b13ba7569e7804d5b1442193595af32b92e91b90c7f7c9999f7c665a9c7a7f5911d73d415c3339c6f0a968a68b6475c1dabe40dd46087630e1fabf2155f2017e4fb42180a3319e7d7063c027b22b6b8389f83c9aba5a25fcb0cee256c1c16760db9bdec0c82d90800249d026ad7e4fa1f8635c4ee66ac2ecc8ac01ec76d44981128e4000cd5a529b4011b6145ece1a1d5404a453d8f28fb6ecedf4584fc8a952cb6f9d6df93cafcd21eac2a8b63973d1643a07daf8ac82dd5b054c0d25445e09978693ac63ee2de6516fc2b9c0d2c59aa561b6029edfe22e85ec79edb34bdc7617ba11cf3d4c0f02b13c2eeb3c0faa2fd0592f8303ed4bac9e9f81e7c627493f4a334c539b8acd96f02bc66d56f149f0139979ef02b7f584ae703925e664182e410729af2b9675cb406169d27e032bfcc6e540bd4b7b1b11054f83ac31d5c5013e0ac3f6d6e6a97ec1b08b22c0d8fcec02e23c3d2f56227fdf155a9a7c363854deaecc5321bc94fc52e50df9ac72c04b4fb74cbf7cd86c427f9049ea0123dbabed674a4e2de9652290ddbf03a1835d5a92ae4ef3237137432ccc8146c33fbd50155eb4e68cabd0208196843c201f2ed0ff53d389b7845fe62eb1e873c6f5c9c1216ad8ffdfeadfb1718e74c50fe500225ee24b08374d2a8b7fc17d324f50220961759194b39f844b12739e80621a5960316675859bed49ede417bf5a5acc2e4b364b70bb92683986c1df944a9a3b8cc87e3951e156af6abca648b28be2b74e6df59df0801edc236b129ba40af8c1c9f93b26fd9a45d102fa7bf90e7f51f14dd59d241c4327642134210376431209d2593785a6a4a6f042505387ab87daf614bbafce0a71426a7e26d2ebe8f7a36e23272d68e4396afe0eb899fe01103e5190ad987834ca9971bed9c1030fa67d27207d4a97e2583383f5904f0a0ef868a6b8a0a2c85fe1c9554e620130e6c08293a578b5a28ea7c0021ceb00c5e4e171a08f2097216d3dced274a6407868f61297f9fe9e95cfa52375e1390c2a034d849bbce454638828ee58aec0b0e171dadb3c2ba34e649b6df427a1a22ec81e2406de5d9d3db670db9198fc1070ef752419ede5f9973c2105bfba9ccb21d5e02ea1e13024a8072d8d2816018970bb8e226425c4c82771c7400941b55dac1a82c6ee13100d8bda00bab5a6d4e0111f101af580b036e177b7e88d70ebf1f57d3d9869f488de7ef2e41923a71cda5153c0f99aa741088d700453e078bda0ac7cf72c4d40e5755f51e9f972d5193161ffbef1f56c0eaf0507bfe67e000aa14c77e2fc597669522fd7553bc3a340e622190378956119d6213836b644a25648d9b3463ff256fa07f431fb1254f38a2540d7d8d1ba4d4000d5470105399683fa97f32adc17549946b7d4e33a06085ea451bb9b0d600fe3202fa84f96bbe9895918438d9d23440f5d086cb4624eefc7a2c09554cefe010fc8412f7dea624ecba0b778302ee742b84e396dc43d3c76eb2b10567ee21da53b51452ef279344c3f4cf1797576436ef727f496641913bc0f28b2dd03f71184034d502788de0d7d8caa15ab98c454d2676e297017823c35c061419bd9a63ba9deda91b4a7f5cc27883af1ce981a40998cb00af959ef782a4971b2bdfd91e38d7045ff5b399c5c097e014ee9959edff45d11affda024527b1c03417b6609dd14487de0f2ab328f2c7066e2fe3d18fdad528fa097746a24139bfcd1361368052ae8ebd22969612d971a162c5cd161da46aefa32d4b540937b80ee404eae6eb13a39ce56f8fff92b54da51403fdfcf7946dd8a43ce26cdccee842af2f6eb15827f305af101464d910fb943488e0e5ba33853c6206eddceb9e2575bf15ab59f5b519e3023a368f7c1584b1f9e4e185f05cdf6b4ae976f075d4db94882711c2ab8e50b028f8f181b95604247e18cefb32c187176e0c4264b9d9e78f7c053277dd97cae1eb03dcf68ccb9c14d6f77256486d60a6ef3c8dfc54254ae5d317284ed44a8c2ef6ddf4aec97a529d841a43fdf3bff0d07776383574af343a6b2504328a61ae7607b1e792ad94fd63e0f5f7a714febd8866ecf4e93be767a16f2c6a4302ed3c88f3e59bf92c5343617ad9051655cd702ff03e0a52af7f0759fa18826dd0d6c0d6b9b58a943c485c911cc2e83d683725ff800e4f44dea9e5747c064f56dec7c38e976a8667949d972a1e8d5cf265e4f07d86e2bd4c2706fea5e50780f6bbcf004fad574131b2a5d060402b25a79ba39adebc44adec286e2641d02c06eb8264faccb1c5ba4cfe130df3ea472e3ad9df249f14eb4db5f2a7b1bc271d67455ab068c58b17a0eb2445f60d9788b899e3779594819895fadc61cc2e080daff29cee7c04c152928572b235c790f229121bf087c155efff507d086f273f11769248554252c8d5972cc79eb93724ca839565986fd0d23149a7d428b2eb18206374aaf52de2629a8215536912ce04303d8308cbe65b8b76a963b097519a531615325c2fd7a1cdd84daeaea5f0951ba4421342db3b0225bd35b659e31cff10180bd6dc65a34a851c7c9d943c9a600c76aa179626a52d8e9f77fb03b5f03100037dc56ffa38081b2a6db99e9299075f3b2c4cf6039d9586cbf123bb759bdb130475385704108ec22012b4742792a05037da6aaa56e84da60c467ea7d3a908e81d7ecf0f95150be7f4d5dec9a1dd9dc832495542d1c376395c5e7aa334e020a21b28b9245119102fd119e81c340311a9ae3749ba3384ba0f1204f6293e3937dc0eeb2fd7a2ac724da6224dfd2dbec16d3a3af4c70ef9ffc653a52eab8d1693a61bf5633124ef3a8eec373e13373abc59d5993e616593eba7dbb5e248ff802881102c6eb060d5d2b8968e9eef372763ca5183b873e5a581e9e865f47b6028bff71c19cd3c08fd68a23f0d9c99aab607387b9c6ec678f9455616311768fa832a5204da68b4a1d18935ff4523e6cf72b1850132058c7f150c2e126196b6723f19ad2fb8db2bfb259f034348221b3d3f87b85780619a6d54e67cf0a55965862b7fe52e23144adc595bc2be1a48f1c1cc41b41dd9da0dbe5adef141730e340d04585616328ade11c06b5003e195f1e3dab9003fa8013ffd3f7e6a67c1f51ebf65dad418a861e2f11f2ffe125ce67efb0eb74f33bd131b5a5d11b6446a8b3fa207ed8b2285a3475847e33e625ed4e7d6533778b595aff6607586bb0412d8210fe340552e3583fceba101476b4fd039726118ac87f80df3cba443836dc2a53fd6fcd34e0e18d5690c79a9e9db8026bb60f070b81acd43c1e5f7030ea7dd2d61bff42ea430279ed1125758d018a344fb17c2592a3d2c34594303a65937825b43c263ceff01c029ef10cc78125dd9f4a55a19c460e1ad391a367f976c8d14a2fb91320efe28825a32c3b76a082a9e42428bac2e25c4892681860db150836148b3b1fdb13d1f64fd78bb318ce7387682b34c821bedafa127f2556a9c2687178ebe195756f609fe81400fb471b4fb1d59f727b378ed82d87dcd5d496097eb293d973564d398058ff3208fb5c9cd219328dff54018be2374f4a66fa489fcdff636810ec5288a0f1428e907d19a12444d9075431e049e594078e1d039e1260075278fb374a93e0105ee257808016fb5c76dee7c048012653bed21b536bffc786e8a1d77a2b8290b41964caad2025868bca96f50308b0e8d7a814ec83b900c8f77583e86bae18a18d2d335215664076fbe4a32999c11aad848aaa1df092c39ba98380a3439943e1ee02ed6a5098b95951eb7e0447b7df1eef98bc02b65dfe974bb92a4ffccc41c2983166df1755e1dfbd5545f0d62e8a27daaead2c734a6e61a196f7c253b967c1528ef00362014c7cae847514cfffb599397f6fe6c6ee72025414d2908b47de40a84cb4e3c3424ba0329707761ff4b3262835631ea1a3e164fedf5077ad2ad20039921b628ef95d8480eb14371130e00af763739537e2d02d6f125589f25eb850ec1140ed345fc070944b3846169aaf337e145e157dba7bb5cc8ae1919e050e01864dcdeb4f64782d440a6e643bd1f58b00fa425237d8a1f8b9a014d7198127601a587ed01e73a590f2bb886b1526b9aa2f577b51ab869e9e11fb795efaaa6c31762c2ab563613d28bfb2c3d59f769eb526bff8eb35ce7a97fb655447093663f1d1095d270f54f28866027ea95f63a6e5715618c99e7e08f17948a1e8c65d0f223eb8346f3a9ca6c43ab9669df0c286376cb610b5a073c5371c2c168935bc1a82162a0e476196e2da58d90892d41a9a9ba1d51aea5d2e8fe1d3554036501ad561776fe8203c0febc1bc49c023b4f2095f7ab99dc9fa4a09c70050ea6c1a6f93d04e66dace55265374deb889c25cf2a56f3cd964ae8d3ac45ee95781743bf701a13b4cb3c6948375a09050916d900fb3d0811a077bf61fad07727b53c2564dfe216679c8ff255da315e1e475b866a908dbbbd515d620c7182b849e8863869ddd808902283f89ce762a42304280edf68f9a76b67fcb61a7a54cda8575384ef380b24d73b1e75b50a6174ae6ab664e0a75f91d4acd60402170a2bf967c9862f0ae40ea80f4d02e46dfc9d22f4c5d3358a3a741b39930b017558af7a8c9e268f37a00cd48b6a5afe6dc0785efacd85eacbf38ff3691f503bd723796d7a2b7a5505471c0a5dfa4b6eec5f56d4b7e4805da697d7a7e2878d717e21d742f9699ac0aa802f8b8c774afd950836e8ec22a520412abd775c4619aafa9dd53a9dba31f385d121f23710baecf82aadad99712d54fbbff07e19d618663216ebf13dd355389ed70ab297bb2e8f14c44d9db5aed00f4272956f940c814e02c329cac3b33e110f7b260c8b643c9225c725f638d415096330c953d46a6e6901548de47f050cea00921c406ed69b8affa8c49e5126b09b7407f1fe39e6c3a67ff985f44b4068d17ca2211a8e6004ac2ce57b738ea79b47a79212fe05f59fc333dfea5b973e0189f8711d2ac25b7da815377b5e0b79bb57edfeb0b3e249284b093f937eb3c8cd5dfc470e799e62210ee5038ca82113eb298d0a91ed7265809b0e3c41842327227bca7e179281876a2d730f88bfcde6a261d12b63b325fc4b8f8a07deaab29e073e24612e721bd4dfbc7a76064f51b97cb8c9aadaebc2219602c4018e412558f0c92cf50f0300b41c3af93217af662fae6c20aba5c5de25678a70e7548eed1465315e04260f3dcd91a642d67ec3157acf46ef336e01231612fd33a33d547b352838ff602202827e24bf1d82e874c4b2e56d6da2211d4f7ca4affadd0e17c9939bae8c861988b22b4b7bb9ef9dffa40b919b3a3182f30d07eb113eb168bd5c30bd8b206a032495cd76b9b5ded766b724b3e8a955b114b6bc8eb936462efea06162c87c2c1caaf7adc04449a6a314f788d3f2e7ad03a89388119434eb73467f6a22898b762192c947c632f83b1d839ac813849f7f22884a21461081a6d636bc2c044241732a226e71541009557abe207a50bb07ee6e5318c4ee2f10bb0bcda8e4fe00e6b71fc41469002dd8f72c043824f87eeaab33b31ac8effef573e9f15bb24f1af840107e0034eaaa8cce6143056e561c708175ebd2bd2b01f7204024529b36328ec107e1079b23231ca0576310db1dcddae6dfb2272b968d23ce655bfaa3b5b578bb051aa676102be135cff656a57bf369ca177e279e14f723c6d567cfa0cce54170301665691ed411acc68341b6e22d99e80c111504fb6e8fa565540666a6c139f21693e4c8d39fee103747a085926e9c36d672e0950b53e0168b556f7cb1a672ec12a0aa0eab6371061b8532a895927a22ff8cd0d1b0f4c4daa831cfdb62551d422abedad3879ba0e5d639f4ea58196f23087af2ffd496a7572303590001f57c652e0d004ca35307c2f8c99a335d6378a3770e5dea4aeea8e5a4493369f406fbdd1bb85993f3834486eb72a18278e27c76aa92986a4b9285143493f120104d628016e1f540e94796eb5b0014ee099328f84ceb614add86ccfbc550f7600f3413651c6d6c29222e50e8a15edef04969562fdbee5ffa843960d92d565d380cbe1def21d8212fb0ef618b09a78a0d3030ea274197521f239b7b82874d575222ec0ba81ee82dca840e340012136ef0b243eba0e650058aac4a5fc88ad5327ad848ecc710d71beeb1dfa88fb932d6125e181271335a9083d7fc6e13cdb92d1ea5b3d60912591a5d8eab8b8db19ca4336fc32c3147ffe8088684fdcaebf5f634cf5e1eab1b68a4d96dbdaa0afd40748e0b4a0ebfba0a627f30c9dbc621e727f7bef5e78e245f34dcd0a1828753e5723eaa14bb4313dbe15d5e76965f8bb765910f417ae403a931a5b653d4fbe31332fd04fc6e69626fb834cda6fe48674b98219ec25e212df043b86786dd8b06d34b0bb7e6cf4c5bbaa01158fc330b05fcee8b4fb9eed20ead836e6b8cdbc6cbc06457ac64cf3a72283181e35a9657ba381ed47169ef3f178a2f40907c36a2de63a99c8cbe92a23d9b10305c3003f5341ef1f9bdef0a99000586c10ea5861a049a13f7c69b0bf6526387aedb3952554218cb5ae0266b3d17107b45cca47a5078acf00a36247bd987db1d331c585953c27b3e7b68e34c5c086f1e38aef9ef67f6bd98ba574b8534c2f71e4ec038565f0b24c6faeeff168926ae5209a04acf180a8c7481af21deeb7a02886f61625e734604feae11bb965306c08ab20127db181eb638f57097f85600f251529faea4299afb46dc539ed447212bbf694211232606e3fc74627321d1188ba6d02f9e8269dd81843182e41575113b3b7b2c3b1a8698546d3aec50985c37a3184edcc69efc421fd3e4f939fde4182255831a27d9b5d835ed40def306d138225b855aa0b81e5707438d4cf7408725dd70cb357f50ec938767a6216c3c45ef2034d3fbc3c8555a67b7dc78b47d8628fd188cef3d2b8dfbf4fc38ef79f480b2efd8c4adfd46fb6205e251212ebaf31e70b2d8a82ef799db3afddc46ae635734ac0c700fe84891c053e63156981b0b0fdba632fd2f3c239ee4bd04254130f5d66e68515143c5f4d6f2b29e17bcb1a303aa93928c09c5312a4d16946121da973879c2af82cf71b14a2ecbeda0e5ec8b02462777d72e300a2f695fe1e4440becc12fea0e2ca14ff1862931e8175d31cb1c9f8844549a6ea22385d3a4f60cd14fd6425aec8890bde9221d42f60e54bca41eea53a6a00c6fe7b66f129dec025d3c05b1a7661322b803efc62b123918b9700799cf50fecd11f0787f2807bf01fbec1f9774eb693afa70d652dd59d292b74809f0b45fd23a36228017f8cfaffd39368d2317dfa86d5eeefabb69e13c7d7ca5128829e70548ddef6f0d1230f3674f752890c754e20a858ff699eb425595132818423036c330b0a4c86f547594d8e34b5abacc9933308d03ff4b5307c9f44b721d9e1d6655d4140a8adca0117a6ac07565e7e8887975eb3965583949cd93c18900bb301068bcbc64aa85a14a8ef8365ea3f57bbe465f80ed8c039a04a7c9e5da0e09ec9c44885c8ab72021e4f8f6c388240c577957dbdd7f64e929aa54c2960a071e8b4cd84f4f659b95605e75c42ca42547f2462b36f75b57972e6f9859d45f067723d028b166e84ad2a5d9921bf762376c3e90ae6b17bd87c27e0fc007a77d1f5f7d8b0028999ef82f084a250d8562793aa0ed27644ad82feb94e80d948a6f09feb51fd95f0632eb2b356c130b50c4f70fb0f967cb7eeddb222c546a5efb49050476a0d41bb023dc5d85b1cd7776f9a2c3c792be49704ef8e0bb09b9e6913728a0b8490ce3a1277aaa62aab1f07ebb41c1f395c34eb9e983884e8dd953bf4a0f0e353000cb746ce229ae769ee10c47f15ec40591d589d798d0c2bd2655751106774bd58d59720491a086b4721fe745209895969578d037e71ae982f8a9320322a859297e7a85a2002ebe2e883aaad92af39668cd0798c08b7eddd7d503b24b1ae2daa5c4eb25393ee6ebf4008bc4e0c072ca90b67a65c586fcd5550b29423f093d0da983505afaafb1eb0771e8e9e1cb3539fbe61f5efca2d4860b1fa1b36121e5effbfaf7611b946208ea448d990b3cfdaf50b40063af0b7cccab49f5c86b16506192e554f89afa326ed0528f6aa248eba2da1825d58628355393113a8fee286a02b1c4a452f8f15011bf27dfa4fd6832f09725a7219294e11954b957f9221166c24763a83391287fc3eefe14933c5c14f4c7d6937f7b75542347d04045a110890ee0f78b861b3af29a624e25b367017d565f468cddce5b7f0cf3c35939a710bf47754178cfcde50bc00ad8afdeb5f65ac80bf3130f8f916859fdd0d676b51a19030af15d64ddc9aefd991cd5cfa036cb80826b4373b9d7bcc892d88b7dc91054be1686426a50d43560b6f5a738e11ac395dab9fe8c808f8f8ceef391350406b72a33744c6e8340275bc6ba889bb2a39e4e44a5ec3608ba7e9ff3169958a41fdf27650f39023fd280fbcd8a14f01e01129e55d1f39690748e99810326fdcd20e052a932671c905b1eaa5c122a28ec8ee55385d4230903c923a10347dfdee01e17b2763b6a7060a5b8096bdf84673c406e1bbeb5fba30c109497c0aa3ce4d91814c363d790b240b21d0c46bca0a903c5fee1e5fd6e2278a36d7209bff11e701244171b2ba258a8c4b611fe9d842c33b90dc2bb751a4c9834b94ee633ff2f0c17e99d90e05e03e67dcc81f0482fe23b3edcf8af33abbd48817fcd2f01e5cbad02174e2613f854965fff32fcfe1b2ceb878c5e8451dd0aa5d75a96db1423038d224a2a1f5665b42ccf0cd2009d22d026f92aed1329fa0eeeac0bd789e8a094c82617ebca343afad708cbf7746a1a7b486be884219e41fc54bc92afa7c4fde27204e3b778f1434022e9a0f5af3cb796f94594c41fe3d1343ce8e95cfa3405e76024841490ba15b8d6e571c78b5fa9bdb4f42cf6939f0ca766f8a33f9af1388e9f0cb4e92a32b3f70b729d395a955e2080b6f0ef0d26e8692148295a7b56b5f6a31596ef09d919d4e9ff98704206e61a8dc0a9ce4662eaf6a10878f3180ecd6bcb0093e2dacd06fe78b044dd4e2f973281e38c793a05bc453015dd5d99c1adfa70234a32f957d93338fde57563ebaf78674ac0ecfd3bfe0a8293a8222791613d2c2ffeacc050d243fae78fecd4172ef8ac8d65605f37137ac2d95706f7fd8f331204bbed683e9949fba2e4bf9941b4939ee707c3973843138bebfee49358309dd60265751d08c2e979f56c6bd140921e7a66e34962c2e608d7326c40f95b797636285580e22fa6e96ffbdfa09b8be7d9c5def6bb69b24b832097fc8501a8ca707c0b7f05f0505eb62b7964b96d0c4913735b728fa4baf217082e8f47e2f582872412c7a05dcc806ce1d8cddcca1d989321c22e660aeba3d8945d7f932b6de9e6591b97a10e4e7f2ac05c0135756d3e162058d1b9e577760bfa12f779dc1b21c04300b8aa9e06aa51ffdcd11ff50c67a307276719bc15611fd86c8098faf7c829da2c4b1f4eb53f6fb595e1961d38512f3ce9827b9e4822b90fe6e5c0c52672cc1d012e591b62f714b671321c5ce756f826cdc2bd630a9a79272f7aa02baf56779d25d42ac69b671532b1d51d23e7c79160bc322015ca838b4e674eea5167aba83c218ea51067f7176b027556fd11238b4bcf8865d89a9cd0bb3e4f43477398ccf22aa043b2ff7867dea2472de15e42e20bfccd0fd02248e6f1ebf7f95edc2eb2312c0a6b7ad4f50c3bf03555011fdf65cd0e2fa85d3bb7df6dd924e7bb5794985118a1d10561c8f03828a912b04d1e50f8bde69235134a4d4ae2da48c118a5dce12e703a9115055cdecba78a75a6d10a5e56613e9dc3efd226cd0756e592f880642c9974ff67e8a91633f52d02e73ef44399b35cab4796c37156f0f9800b7a88660345dcbf63e44f1fa2d1f8eab547a67f70db529978f40217b5422eed2588a4ee300457f11907f9415e349dad8cb86d9910eebe588cc8c0cc798a522e39a669031bcc7172286c9537143a92c965481a89f3c4e860d5ca9824175d9c7a597ee7c61c115ec99fde4909f191e31613746673c5507ab6e01436e6fe5f07d8a929fef51ff7676cbb3def22e44a545acbb9aaee1773f706fc8684a7b465d2f92f8af7dc0a1800216db2c08004b42287c6df656f6b5dedaae8e1b9013c94532463df05952bbf330909de4d033727d32480cae73d2a2e9e50326fc605ae30c0c9f011128b1a678d3619cafef8cf5d5e07d61a849c05e91e9ce8290b8e0ee69c705736ed81117bbbb0fad9bfc93fbeda8ec8b9464853ee161b5fa9b5e954c36d10f7d2e01d0837f15100dc35eb17b2dad7ccd87b482048827c1716d510244380ac5b0934e3124b0552ca7a5902213329c982bf38782b0aa337a618d658aec9d01e4885977f1514eb3c815c8ac482050a2d19638a584180f196c16339e4652b1b7f1ad870891d63a0420da9390f9dc04588fdfb066906fbeda08ee28cf7f06541519f991aa7125c2099036a614739e41d2ee4266b3faec273304a8a7fb09758a64cdae16d281d06427553cb1acf30f1603889e575889f826a832acc44180f68c230647d971413a392f060a527885509f15ad448f8aece5aadc9836862138a8b6d3b52c33dd41faa36de1e5f4355825cc13a32d55f9d84a7337b691d12ab95d7eddcdd3f72a22ee84a7b8932c0aec98b47176220beadc273414c3a7d739e598b932603544fab03f191cf63a65ae49a832011f34c94d75bb99361b17399b27d77231128adfb33018fd3f19e9f95a38b4f4296e1b8ac28f6ee41814be442b889ffd99b621ce5bf1bf69588a55456a7f9911222a4825f68d22106aaf2ee07891bbcae65d952e75b2ce90f558af3f890bff0115d005d1e5f714935cb35aa8e12c3b0f194f53ba20427e5d13527c1a9f7563f61ae1f59a6dc16f2cca1df47ba4d47ad490a54d1a9af10e1bfddf43ad707f810b5b9b48a91b16d892c73403c3f5cd6670bf79e355e1d1cb721ea112226ce6a6d52283c887da649f153a7790ec04f440176987419b5421b7c694c646cbc5618e0f2e9d9ca5a10be1c9e007d519aebc3fcaa904cf4028d0f15c92504ec8655c6f5ec0bdac134b4194ab85c505cca657e295d2041c68be114b83a369cc7707cd41264238945dcc4d2581939579ebdc673ae8a5ec925776e28341d66f9f6eae02473c10b21c2f682ba22fd78f1b25895ac2adad8511422110bdfcc50e8b7e10c22d1061ca72d0945d2ae76eb874cca31ae41ce92e335e6732e0ecb8257b64e85774c95c601b69ccdd6cbdb5bce2bdb755e0f4309e735725f", + "public_inputs_hex": "0x2138b0022ab9af3c96b082bbf307bc9e79f8f1401462e3ac1cb3a9913a5b856c18c40bec999a837ec1f06dcee05102acdef50c501e771cef739dfd0a4cac5e94000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7011521e0a601b59f0fa9d199e9f861874db5d701a0c38f6d725d9fd8c1f0b53da03219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218625eaefc46d4dc1d14d29441b83268d90e246af546b51272b038fd206edb2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7296995105557a58df75d3a42759d29e124a15ef43bad6b7fd6a9d93d4efda1c900382d23bccbad9ba827179293d23b719de8374589fcad5bc6d2148bc787593a" }, "decryption_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000ab6871f5e0c604e230000000000000000000000000000000000000000000000063e0c5faa3697e97800000000000000000000000000000000000000000000000c4edda900b7425ccc0000000000000000000000000000000000000000000000000002befd5183896c000000000000000000000000000000000000000000000004d8f5da040d18947000000000000000000000000000000000000000000000000e372e41542c47b15600000000000000000000000000000000000000000000000eb6fd9729b1572bba00000000000000000000000000000000000000000000000000020aebcd8e4cd90000000000000000000000000000000000000000000000027d1ef6bdc1bdc6fb000000000000000000000000000000000000000000000003b63834a1a171bf2700000000000000000000000000000000000000000000000007d98d752da17665000000000000000000000000000000000000000000000000000218b2af27d6fd000000000000000000000000000000000000000000000005fc5b00c064fff6aa000000000000000000000000000000000000000000000005475acb7f772fc6a300000000000000000000000000000000000000000000000d5eaea21fb7f5474c00000000000000000000000000000000000000000000000000025c5ad7f49b8206f35cbb5b62e5b765b61ee0b49a1f8770bea9d70025c2700523a6cdeffad74e2d17c339a3922f7ef70421fafba18febc1023e82b90cd74104a98902574f6d1c226c706d93043c153de5bf841a134de7656959e544c04017eceb0069aa692b1b09d09bd7a13e5ed5ec3350da8de0eb3d4bbbb261473acd3a03e1f56acf424efe0c6de5bfd3bcd37d09cc02b16d1a369712519dc1e780047008bccad88b1517ab06359968bb78d1f165250eefedd6b57eab508d2953f5240a27b3c8f21fbfafb207bef508a58b51480594683a51f7ea0ab2210a377696def48a79ff7efbaa8e0823f41ad197d6b1ee7ee556998280123ec1b9aaae6dd280edf895997e038d1c1c25a9dc3e528367cd6ddf78257f8f4a4c8c13a20283316c3eb5d11cb539b99e5806618d8b39dba1be4c13bd33f165d43ef169b3b372eea8224a06ae43caa0d921207c4f8a36cdc97347efe815d7f3321ce22eb52b6258a38b98f20205e737b6f61ec9e8a86e5cb149f99b66f85d8a15b805fb61123bb0b5dec773cb3b297fe0ee07c1cdbd49dbcb2961b3969e1607c7518a382930487888e32d9bed12a4b7298a26da1f07cba3368953cf9f4a5c127d3fb11a2477adfeebc6be03f27dde2c51742d449697cacf031c884d94c35016ade6bbffa6a1ded069664af9617665c4ed7f09333f51d61f47a9365621869531df3ff6fdde13d7571858c89dad97081a5d032db062ed586adde96838ac6e2c39cb5d50c316062bf90f0b49fa7acd55e6ba1620d7097883c0c1432d691f8ff8fcd8c8075c631e9d6268bed9ca37f2e49bdcf215c9022b55733861a9e7bb732ad6df58cfd3446e7ec2067b2746836af4f7f89c06f25e697f3401aa322174f68a210066a5b63035baed84e1406dc44ec30e74d91129f27facb96b2eb96dbda62db646bbfaa784d1a5fba7dba608196df258f5020c01e07ebef101e89b91d5dec206ff84318ba1638547fe25aec6b87d674308840cae64a836af4ef9ea8cd2ab455927f23633e086b6f6b741485e76bef2b6cc032bb4e67d1a535f5a810fd3cc9899368676a27a90f311557be62e196f20ff52ef13f86ea9ba08fa7eaabb18c6b1afbb4f7771d605e4b1f2be6fe991394d0e2f0626490f444e9ea9fbd75efdb2a25d56667fae74512e2fc0acbd49afee2b2c23e72373c15067632bf4180a0cdc54e9c9394e7154b900a48eba42ba1f44b1d9fc72128f4b3bedaecb9e70e27ed92a46717fb202dac7e349a24736229c5c0836ea091cf2028b1a7eaa6a876513fa071249ea34cd4e1e27e33cd996b948907ebc60990d5930a69598cdf690b2c2c4a1ae184affe235d854ec81da06447e2738270b582081a0574605536f0f836c368de05a08b39fd2d65450c5c5d6d6cf1d87a7cd5a0a079aead0c9239382526011399682aca59d1ac68ee5c18aa4c3f61d13d2dc9f1940bbfceb517ddbe3d02b950661d24e7ed55d0550eb3689f421b3a2a9056451192059863b2f5bbf2fe06feab1df4d0b2165f90a3dbafeca86e3619716ccf0980bf1fe0721c73d5cfcefd66b41e50aa7eadabdd8c455f2779c3b3398132087261797ac8754b7044232941f4d74818e58ed96ec7f2caaf282f7a531758636d2020f7ad743013efcd97a076ead680b17dd244cb55039f07344e15a1a8e2f38870a29edba2439b0837a103e1a8c00e450006e6b589a654b8ccbefd5de0045c8e21c1545fa845e862ab714a464c0b6e00265beabcbaef383504fcf2c5f80cd7360b10d5c24f04fa84e22c6a8e81696a7d4debd55b2058c64ee4339f7e1acb1c8674f2ba9e03d761ec3bc086bf76ce20afa4cbf8328033c71e096a1b21e3e1bbb980c260b3e581b7f7afe02b1ea39b3b73031d0b96080204bffcbf3a04b43f5365bdb249ae301120746252ac7b763df1d20111dc3827f858fc8b12665c07364f9e6042b8adb4df253af298a3b669077f4aeac1aa8f6cc0b44af53c3c1fa4cc56a075d2857a42d3b05cc24d8e929608bb93e738fd680f4cd8af7e6506808ecef185b2b2ebdc44cb7a9ac2efa142c54b09cd054bda803a047c314060dc259796a51bea1238b6879fdf41ffc4269cbc9859c6220dd57373fadcfcda2548125a04d9447280a0696340db71c34a8cabeaf6636088c0331952ccce04a506c57ad047ad7bb9222907f98f62436ed0491d278b5ed7b273a27601258a9ff54c7ac8d3dbb68cf3f1749e0a4c950d439213e3bf0524945627736e7e8fe7f07029b26979c722849f62eedf78929c852c7bd06c10d5a69015ff5983519c3e0937bc3c825472e519547273409dd5643ecec7d1630979937792e5ed4b7cfaa110c7d87ddb2e600ae1cba2ba7b5464a14183ed799350e4d18c512d14b66266eedafd5d32e1141c543d6db248547031da4097158b87ecb7845a8f659c5c02b9ea2ac6f636f3e3d4015739223049f86005714294ac037d14a7ccdac80e89882751314baa8dda7bcb024504e2e27c6a101a3035ff6ef42b99d56c20c824d839f3d98e3131932867267d947c02bb2270046b020798f033e718352799c0cf9d26c86961efbf43562dc263b9d250e36aaa19d199f1d2789110fa14b42d0cd40a491ba99682f72fa9b301d08528b0cd55651c7fecb9fc18e4a725043f251aa9b69be5d31aaee787dc8771fbf31252a90ad86466fbc0eacd6a4cd0d6b94c53ab9fb4c6398b68c5077d5fda03d7e7a1d60824bd6a0859b7fd17c5e3ea922c212b33b1b36a7c5c060eecdec697ba38c0f968500d89f9543e48accf3511e6d0fbb18f089137a7db279c6abe326dd15532f7ce125605cbd676ab45449b2ac04d190420e48f1c0a029eda9944c2b651f681194348f35c5946265da9ae92238bb49a90f7a05e723b185bf8083ee7448ec9517320c5f10fd917b0375e3c88136b03d916220b42d3ef345c9617873212e1e6d1af9a175a5da49ca79114ab1bd3fa654bb9dd1cb9a287c2278f367cc7ef0e35d064982209f67c25194f6d480bd1af6da9c21e590bf77f8e556bc82b3f36629e51ba0bd9e8e8f2a59d7bbbc20be61ddd3d78efba879719d28c116762ad44f7a1c17212136d31493bc280107ecfc3e7f56a3155e6a8dc95ac459573523c5db8e9726948905e785fae860f81331108d539f7f1b8b4c914936d1a06976787a461aed10fcc5ee13a48ab03e06c2eb6d80964b9faad63932663a5a02cbd28b40f159d3191fed983fd4a451dfc47cf6bc11201e2d2faf3049e8ebfb3c7422ca072136f3294c96e6a0fd7348adc0080aa0cffa5ae817a64bf74e78406e6f12e2ce53b20f24795f8d35edf71c5de2ab175685fab6f9c73dc06620bda26f67208c9774b7e52526e6da846f50a867b53b0c964535f5e52c14958463d58d2417c74b2a25d8012d22f20b89f69d9cafc3744aa9a3435674cc2d23c1e68cce4216211907defcc128f00687ab857061bb9fc3fb5f4d2bc70d8652f2f9cf0808c69135eab8fe2b05192d7577511195d93abab820c9f30795df0b10c7f55de58c03d19139b28f5d90128f7041b76c81e6f1444d47642da90ad4e2903cac9481dd31dec5947d5feb56114e0d1865a7bf262de8132d41340ad3aa5e1938c8692b7d9e6af1633d74a3a21d0b65ee6e74bc543b648cfeb52beb7fc0e500afbeab9bdb8a425e43efc6e0ba03f2678dbb80015852281938260095069eaeb25fcbd581d8ebd64babae79e41d11efceb26339550bbba1e36ecc3c91f71ea9f1cd23c0ca5036758e74edf7858e14ad89c7f9c8f71c3cf32fe11c37f583c932bcef67203e999e45700d3a5816870afe8a87a72d9be4d639fa57feccb778e06dbba738460fd0f511c0ad977dd06206c54e18c4a57066e49e55e207d36107037ccc095ec6fa2feae81aaaa44b88370906d542c020f0d3b0e2d80843567501f13066782c96646ccfbe031283544962216425d07ad1796b75e2e9d402062083da2d671d32e1c34e3647bad0322067911656aa8439e56e08c30a1384877c1a32e69c3440d5a25f687c175239ee6cc75c04d11f5e379d21a7e8b32943f9772db2e168f4f1b7b087ee8b7119fd1f18aec2269e83608b1d071924f9f2dcbbfcd070bab6d7f5a447e3a3da752065677b64921849ccadc866212b4a74dfdfe4b8430bdb74f4a9f17a6a99495f0886b442625f2547a6f4500d0dd6f5416d1f40310b3fb8ca4a72861597ffa93f0f9c8e3955fa2bf139bd084522a6726933ffd9e47077365bcf03a3ee29f99edad41cce14458f0684554a86d665240423b236917bcdb313a210c1946d234dd1fe542e742668fd0d64b6ee71070db72111e430e1f27beaba2482951428015889eaad1482b4c2b3157c8eb633ce89bdb8cc75ec48b40e2c50fc5c46e897efa49a7e4b535b16dba729a619462465eef8f964af5497553815acb5545f74d5d677d2c0c1e339416b9c219e50a898ee88e1fb2f1db566e9696f253d79f68772a0aecc07896d2e49332c0f18fd89635440b49b7a80d33da8557759c2fb146fb125ae93087fc2b6749e6a0726f493c7ea11b9d67a1be2dbf04a50105d2b489c75a2efcad8658fb92521580df1b992af777cb0e3ba2c825243eb0e6bdf3d0a6978d1411104b59a46f0bf720a79728ba37648d5d60c06f92608a4dbf1c99fc3e449de7549a7e50762d0232c2b116994593bf466bb0dee85010662193d8ec2fd8a25ecdb2a7b34f7478aed831b3025e984f0ada44ea0333d2d72380d11ea5c1b5db3d182548eb261b77b13181f48514e3f03784963faaaafe860688661a8bbdce565ead9184b182a9802311d19069af44ad2e08496a94d229f869f5a2830c420d4e1bde78c230d8da4384b220c88dc1324a1b82f54e16647c431dd5011a1421c785e130013cfd882192d72f01374b6f2b7f6011bb2194cb772e337033fd01038f1d77810506f0f93aa4eae822649b30fff4c315bcd99b6cb7bc282d60e8aa24fa71bc754482ab58e0d721c3c2ec839f0f8b1c83585fe7ebc00368d3baa4a381440565216c8d2bd04fb96d32311649b8a7a3ca661a0cf53114a8fb32d33cad95318a6154178abc8c06440e21d22e5c70296141521743a8a37855d70b311927b84716de2f8fc092c91eb3a7a1f221f26aea2f88548f3af4b19fc475bcf49786adfc8d7e7349e1693548f512a221f381f9587f1fd3cf3cd069024a1170feafba8229cebb8923a7ab8fbd856196217b589aa128af06c775f25ed9b3aa9bc23803fa5965ee8b7794206585ab63ebc119c919779bcd9b1e024982c6fb199b1679c9af2da8f200348f68ec3b2a00c0f17a15318a649ae59bada674e3a149bb1d6431461411e2df3e2aa1958b722048b16a07dd414de7958c407c3eb8c760779358ec1e2439b58b8d00378bdd2e9e9450de9e777da0eebf79d558d029019a16d1f8c076fa5294863dda329ececee07020721d000c002b15cc3fd3cbf0f0fbc80d75c1bb53ae1b7a244fa507318c57e4c2d6fafb6038ee34355adf14f0363881911843ba3c655934688976f48ac38ca4e162f5b94463b38687726d27320a2d8c97ff9d8a79e81261babee9852ad0958c210d8ae1fe24253e9229b410ba1f11ab4cad40642dd7c818aff33430752c5f36205ef43d3378c9968b0b16a881404aa643c3d555f84b78446cb9bec133cbc10ad00b9207a883ec2d82bad1051a9c39453d1b63188f2c5c052643e597db86bdd1621806a9ef2c04e8cbd9fdaba392d0fc997cf5a49811bb4c8b68f104ccac280541ac123db803c502457797ba6ef0da3b43641d8406b78f1007c09560d45062a65259bc7636f785729b40176ebd0ca1c6f2ffdb9ef2915602c4a6275ac8fa7cbe71adcd397d6043297be672053abf8339f90c137a367ec7d6a782a51b8285f63721916d859797c32299e9413788fc27175800859f9bfc7d3939d4f6b5cc9777b2f198710723aaa5fb5f57450a5ceb88a674796d19ce70fab58e730240326a016922b06a453d8c9f93c4f6a13bb87c227a297ba159e626f5823114a76cd7b0f39410cc25f0afd48083c62151fbaa1853b27d7a17fa1b9e2fa28a284200bf12a6f5a2f550ca3ccff9b6327e4f7d9983a448cae3e7f9ca4e628df133a58dfe58d741b284a4e0b987dcb8dccd1f21874cd434280feb0e942f8f0e5ad8fed96b73bd26f024f4f697877b9a2164985542d2969f52a5b57c433eea4f07a445aa9e833a37f15dc67773cbb58f86cc70a1b5779b019ad98af907b00c0a1fec4492d26e38cd72085f1cba3e5e9c54abcd00c2108dd54aef936879809260609e0787ae4bea1f618a9df278efdd7f15dfe9247dc384fa4f971588fa356b4e67377e8fb6251408f2b82baac18f833a2875d3bc642a5838432ce511b38005fb7024bc01688ef3f670da2fd6a5794ae972da048893816c19549b73421e0d585751496ed222a7cfbca1d415320f214e7cee462d0689ffc31bd05f4c9a5ea3b1791bce9fcbf374d2d14004ca233a4b174ab409e968d6399606527b624923f381eb8c17b2805dfab7cca280308a2b5af4f1aab2d05e78198ee4536f2deebeafec0eebb33df157fdbbace2e747e434240c5cfe49275180859832b2d69923bf08c0d597d9112eeb73568c91fd8ea19778ae26aa6a872c78c89c957d2518154b689bab59b2ffe5bc04361ae131dd276df1a28b2e06a9df883220bcf76424cf289b94d5bd90056ca2a6828f210f1ff74decbe9a8961ee9c5963876aa8face86ca89e9b038fbc5b1ba5bc962c128107f963cd0d439c4fdb465eb7834c943f21c1f3d46a7f057b75b42aac8c472a5c5521abd8d5913f59e4798f9edd0bbe643ab68d2d5f2d4d7b7dba52dd5c8c01fc9c7bdbc80873c54c494f37b6f6fa4536f37b101a16a7da7ac943fe0f666304c7a6659b382bfb94977ea2f22e244f5224369d6025dabac1e08614146ee2501ddaefc72b74b56f7f72ee8d908bc52a354105655e85edb6dc768a83f3dfc0a317c66db9a34532d5f7356579f0741dacf256f0af84798ee17836c4a40fe4b5cc04c199f7039d38a4bc5bc7f2d99fba60a0fdca779b92f02ad5aaf76f1fdefb091381e6eb635e8634516faf93dc50ee8b484c07b917f28d75a657b00a68ba0b71015191755b4d819437281f7565299d9d5ab193750340c3436c4e1ec8af65c201101a107fb877fdcdbd711cc0e888f6a3918bbab8780e9651d6c8bc29d473a25a263d53cc7805cea42498373014e822341492cb0b5846f3651c4de21d6a02b449249f136615c3fa59efaab74793ee99dea1346e28a861afe2f931757642bd3ea028fac43df603f0eef3eb0387cd88048d715e733dc835545af0a970b030f6bcd40739b526796af9c7636fc1e0023beae25886eb1ec9fb69465f36cb8db0143282114a980ff547ceae0ae0328b0a2ff83894cc7efb1d8d3268e623e20257143ddf1690c3f89ba0cea9077e7448601c66a68816c5d7adb596e9df73a9e7d4f3b5151e8e6dba9f96d00681e644aa6cc33f2c88c76c3f204f9e0f4abe5667921cc5dd0a77e105a39ddd0f53525089e44c33468ab32cf7761380760d7c24966908f7291f3cb7b08e1addf167d9a5eb038f1f433e711c6e67adc478606f09c33400928b09658bcc54c224cdca2dae3dba6278e91f8a416474312cd9325be5c38d7f5d7e07f54faf13c87c1b95c0f7f21f9f879644988df52091918a8fb17defcd05035b2c01c5516e3c3a8cb16dbfc84ebf730cc91c289ae1d9a2247ef46867c4c3f8b214c7e231c7382212bcfd3bdfba84e5befd2d04ead43d97823562f066e832f1f31e830d7e9747675bde52ae766e1b6f1fd1868b78f7acd5e595aea09c9dfadbd42088b2218775b734708929cd68d07da0d0544236991c2b7cf3b1c8a535fc2a741e04a56884e7fec5c8b37e770b9ce037d6d9e5963f682452e8d786a57ea1ca4c11dafb71c383f1751378b133a730dff48da6d638942abb532cbcc712975bb260159681bc8d1480de29c8d1791ececbebef1dd47e7055855bd32ab876af784fad1175e04f583e93f827e3336d431ddf5f2a9347290732acb2c1e70b32aa39a1b61535d18522b8e335ee209aef0c81c3ba6c2902fb07d3d35c978a48c6242a5c0a0e5a2a7ab8189202cad4eef209e352db7c4548e813f6479e5ae2cdb3eaf32b601bf6758cf1a0678a0daf9120dc0fa7c4a30f5602f2ae2cd64d49f6cce7de341603a1e9661d5b7553dd96174da8b0763cb968592477ac917adc4dafb94d89522c29bcb39fadde0390e904c2638779567407ab30dabeb7f8beb0b49947dc9e8fe7291197bd5ebbf948c0326263c7cb67a772e3ffefa7d93deb6fe34c83db575bd913e74272a40222380713812899c64497ddd2f0ffa40bd9435ccd8dcf07812318062d0ce0a9887f24c623352f28434512a3f02497d08f70e2acd92c6f9c7db9c70ce84edc6d0b2e6a85061ecbbb6d524d77900e545869d585f02e66c11c5683262a89acb3a1d01fbc647be2e4ff6850475f86dbbf3a5533cddb04f9f759ed3f8c1a58e6111f8ab44f6eb753ce9b76b08ec2c1ca1e8e4a0b12f2468685e97514f80084f9ec72296c13c390174cb7058a1cb652524e152af41bdd9db80f4b26159d019c5915c863e55429c22b5df53f3c2c708d16dcddf9ca6144b3b12c102f6e4726abcb1e662e072858dd31ebcb6fec808ae3818a0e1529bd7f967ae9e4965f942953dd62008a7880ab0f25d1aba340e932e7ca5cfc654d05efae33677e86e73c1e16c255cadb04bfeb1f46d2a57eda2e9e0125c6a25e611177db2f81b52e4ac6270c29e8222702c6a2590dc3853e75a6dc26aad0dc20e13b71d273946564d9d7258d3a80b86cb1a2b655be37f8b0f78265f6bb866571b384a0792cd7ccd6f9f61514364c60b0d46d272ddf70cc26a62f1132e1edd6f617e815dadc8febd9a74e2e645c1d5c5e21b5c8747ef39578966822fb78829299d4ffe3e411f3d3bd5f092e06ad539341a69ee6302e31511830369f8bf22dd7204099269cf871cc0997191f1a2d248d13fcc11672953d9f5ace68497ee899bfb32b4b7bbeb46047e4ef821402516b83cb78caadfadd9fc6c12a398d99f1b878ec66b515e7483a9a0cbccb083041b2aac57d88f01d6d47b3ae84186a84792b52151c25f6587e21f8e6b07b1c0fc000b43896466542644603e14a650e16686d853e62db267e023569d5469c0809a8d114f1007b7827216e65fafee4b603e959641d11636efd348dbd46ed560624ef25c04f501716ef93cee02aad775bd9ee6919852491f3d29b942372e1882085117390b7aeab2e50367937357f59b9f3a24d1c14cc6497dbc0818fbed5041553c7bc5740d0e9aef2bf62243c1ca12f8567c9d3f39a40110770253767fa7c26a871d60e27b75d9e142b1162a4130343e788148124d712988045ef96d48f8920e88ff5c9f60d09d2f77ba9b403bf6c6d0fc0799048710792a96035c73a3e450c283036736b9628210c2497b080c5abc5372666768ca864d18a6f203fed35cf272622ddb9a3970878f471c80de989f90ebd8cea6120f8bd4c593763bdbc5a98058b8395cb3225c7060bb36acc2d22c0338edaac7d75befe39ac4206479c86fa237ab01ca34b0328eb6699049f29188e92e7354e69dd727f960802fefe99c3d80c097dd8728bf5d5825041d67e5ac9858d748bf30271341377176ee8bca796f60e5c92647f6871a1579155741c7b634c268068d9941eb9acd84569018e4de82811c568bf95b24c04cb3cda2a83b14307e668bb54db1a2569360d0caae00498f91e0494092814900d31c78e68f63f06cb09a782d204a10067a78a04801888f8b707e647e4d114ea7c1e7faba4176bd2977b7c1d0e97d6e3ed976c66930ea8d1ea278f3899dc95fad95147a22de703ff82865da597000525a1bd0656d82a84f5d2255bca0b9bef6038b61f0e92a5ba1395707daa095674120eec99fc8ac392eb5a178588131cc52f9e6d45d766712bb3eaf094693a5af7a4f746175bf7aecd09831d846931480245a862576fd3a006b07b1fd9c2db51db74543e275d9e7cc26f2d27452fd95e45041aaedc81d99067f7567db1fe9759e84b4fb2d1bd93bfefdce805a6cabc48654d9d38ebf014ecc33eab6dfe7fbe12b4007cb490b235982a55a611fdeb14cbd17ae02f6dbddc8b4ab0e8209312dfc80292b4c072401ff7336ce8055b3fba6b7058057342f5e55266f9bf87220d9c9ac9fe0853f3d4f4d019d829195d64b5e10165b80751e8ed7945c9a19a7960580b7f3a9d7a6065ce6a26fd3128a6e7e2d8d168db7ce213fc75b4315145a583fdcab1de9a71a41fda973ff1490721ae0f3ee28441b6a46876cebe7b6d692d551bd2746bef1fd28623c1af91c020c7c80ce66224b03e7b9106196f94b8e0c9b5ed67af49449aa45213b412de6e24c842e747291b84fa0553bd0fae951fdf6e70d9412ef0ba752166a5dcf09ecb079b9de21279373de98b9ca059e22817390f90680d8d338d7e35d0dc81751a500d4bd7104c7cc8e52af19d74caa3d6928ce9b0bca085889fbf59a86959c2dcdb13df2f80658bacae156b7f1f4865db24b07fbb6b27942099f9d61e57ae43c3c723bfd52acc8ffaf4fd9cb1147322dc31f7ec5671c5f0ca5c5155ed6d9f2e2413248241722317c262c5bc54875d886f0d90780674e073c5f7f921a6666e3048cd16d5814372e0236fe69a63a4f7118d7eb75bc4465dd01181c9a197ea72f8307c2841f6397a9baab5a97fb04e109006d8127d604f0b7d6736162c40bd8b1c09221e0922d2139987796499a7fb097c9d0a4671b898532936cccadae32376c93dfb059ad2915af4a690d40a516c72d74ce5d4ab9e752f58873ea88227546e021f701702aac2d40191a410dea52f40a4bb996be8002e1c57413e0dea9914098f8a880a8c387b2e3309533a4c07aa51444956ed8fd2a314017814af55da77e40ff7051641fde9c392981a5e7d779529be3e0be0f6890bf19b24f53ebdbde0faf9d69f10e9fe5c469cd99083a9c572eb19b940f9b0e8094a75fc98a7131f2c923408620f3d931493d5a7f759cc6a21edbe9dbe770a109672574d8bf6aacdd48623e833296a76845bc8dc66f9e0bf4d05b889bee67c4c2852750c30d06903783da6ce172c02a8f8653d8211beecc345dc19b6f7cbcc803d66ae2128ba1ba055f761ca3a1aad5843b15c067428741c224242e5c518ffddc45193b3a5ecc922cb13c0d0a72d4130a3f278c1f463f66423e4710027d0b319048abd0a6fbb66c195b9d1452e2e0c7c0e8374b22294a2129630e2cc3dea0b98c2c13758345954fa86eab6ab710a512893425e0268e10b34ee3e2e6a4fb03040687698c97982e30bc2a8a2b2fd2248da56fa8f2105609a497670832678fbaf89a7935cf26768c2c03f443fcc9012eb0427bcaf487189c20e24956f34d23792ad3f62596d3767ac07ae38f3fd4b11324800ac6e2d023729dd5df77dc4e0cd81d0ba8e10e90a266711e69d577bd406b1e218645fa2552bf747d0d1a87fd66c7644155f6f5cba9115d114d7631cec08770d53cead9762e9eb24399c4f97d98fb3c365d158799be00cccd3d20c3b090b431b0c2f7b7c2ef333ec898e469fa101f1adf6f73815f3b09bbdad8349034f1f90f27a8046dca9070e149c1c23150321e612756a0c2c7942d7e30059be4908050ad08455affab49f27dd02ec5169cd976f4567515baecfbadbe97c382d3f1826774b8c096b6862b740081c523d47bd0b9639994b4ec95ab12845086dd5fd482538707df831ef734170cf55d329490aa2e0e49643922241739793a8c75e7386283a026efc405fe0598677d246226a3ece5958e0d48de439e944a05fc643d0641fff61f83de97b677bf4840a977ef5625bc385b7591755fe89ee851ea5d15ebf2655014e914e878ae7c1f8282c6189ecdcfd5110178786f7faa3b05de46b43cf17e113d1492df5303ceba990b322420dc3220d8d4415f89381df54d5ead445821656c02d97585ac6f793d80d33115e53d6415f05f0c5d90c3d77c3d140226be02a3ee5564c70975456bf79d426c8c33efdf706cd178ac3d687e28e4d2204547d0fd5af73db10f93e0b6c523b4ef081426af896697aad46e292ae0c5fab03ec3d0d8dbfff9127ba2e3c4eb3e7a55d92890674bd6132382df800faf6b8b407cb5e2f34f902cc48285bc99e308f2acf715a3b8f884aa21e144ea9fe2a36eadfba592775d95bfd62c6d71c3089734d67d08cb00dd85d23185796cd641089a93e19b12beac08125be0a38ea27cef99c4cdbeddb4b278caa2fb8d47e2745d5c09e83222c0efa0932bba4cb4546e28667c714e5b2b974eabe47fb29b3f78cd5b43742f101e475b51ad373772e93166104a79b4efb175dac3b442b52b9504c88304419102b169b8bacf4d47e97ab2c69e9f5654f5a0cb6f55d8fea831cb665e93bda050b2ad2bee6223c4f9377be451cb1bb4d7d5445b1eb9b58549ec07694f34940216118b0e8add0f6d3ff6199052ea7668d13954c7caa2fe6af1663263c9a6210ae0b01981a9f0fc8d9d2eeb8d92572ad287146f3bf0c20d23de8d08c40c78dad3d061c8102981be8ed68bd6f3b7bf768c40b86a06b6da762153c82d045133d3976a50aa6637a1eec72f4f886a043ee57a4e6ecf52067f7f1dd512d0829b36989687320fec9da648b374ad4e0247d1fa97700c286b7e1103f696941674e6f3a6f9ad4223aab447b6b691951dcceffdcb30f047653433c4f8a1abeab791b5ac76b18502575e60cd921ee2346e0ede35620fb30907dfbfa218913647ad415c9a48ff09305f729f2bf156c6478011766cb094981c086bab98c384f67a7dc579b811ba5c11f607412b5d8cce667aade35ed4efee23bb261c4f278e09b257d502bc61ae48712daae64de5ae2bb6d679b43fd9669b02023aa3eb4d01d10c4603bed9416d06f16bc522446aa35b063e490767fcc90a7bf197281c5c295c1e0415dc27d1e29df06d659418c6c2d19a198517016a3c76ce82fab8d540e656ec7170093c80446c42bb2ab499e9eeed746759a7814701b945e602522926c49aef0d217ba7f3ec0ac1495c4281a7b4a9e1464ce6c97788d617101c912e7918be268957e80dd37fa1c1daef5d845aae5ae93f3d73e13e95b2f974ec218a863270fb89a30f0a81f70f815e9e11d54842d2997758695e9e919c49ee9568970dd985f95ad792c4de69c602ca2a090660e70cff6f75b308d6b58fd3d41bf6c2e1ab5210914a167f161efb208999866e918d0ac040afd7f314e279aea6a9503c0fe69b94c0596ec7204937c282c824f63fa7641a2732762083c6fd099f8538f33fabde31df0ff298e4d691403845eb37769b4a7e325f7b4b90dc138807c7bf8c94b3308c8131021dbc702ec1b0d2773d0d393b5ee72fb1b8c46bf5a2d96e008f0a27bd052c6ce663df466bc10b34b779436e65c9da5839de588d9356cf64f721915fb81cf1107e5861a4fe51ceb29793e3bfd641066d690ab8a27bcd93604040376f886a2bddf62b99aa21012f03a25b1808210494fbfb7c5a6e98c9b0183db9d9366514708d725bd15d6471c37dd3530ee3ab502f0bfaf4639574de4088216596534660c852c04f73e77270a40fd0514c085057ceb30638d46641a2429e8aeb06b89a01c7a19bb9287955c17d5b7abe02aecf3f5e497b8ce13ff4402e42e044c3d270c04db487f5d00f04a0697b0af7a5e27a2a7c04d5bbd73c3e91e2ba020b861cf43676ed66ec9c18f4129399d25127fd3a40f696bb6dbccf3829d8babd3a13e6aec6f0e6bfa632bb90b26c35be6ad3e9fea820c0327735cc17a5244802c9466dd98739a06bb34e742dd044554adfcdbbe8d300cbc39c983ac1a9222513ebf33bd79f429c47d58beece61dd0536dfb22b4ee0b661069eeadf37d8c1456b05f3e19ee3e058c732c8d1ba62a6a39994da45c80490e4a53575e6a739a01d8817ced669ef6dee1dedb34984b2688cd26b1fd6e4ed748d8dba93b6ee4a21493066c1a10f7fa44f50a02206b342a5e15c483ce678c3f87fa37ae6701c4105ea18957e330b13106f6d62f55dd9e05f880741b3c98407fa02b8b956a0b42279f01abf85630fbbe613129d4a710020602b5ce04f6a3eb5c329dc34aa10af6d222c111845bb6016b2cd69f48e4edde14106fe41edd0cc43ad8800ca68c5aa644bdc46f64654b3fa561e10dc84c4612059e79b06da8e2bfb580c268e0c94f02625b1feac968586930f5fa9daa1d52e2166bc02b21f5b5a51eac5219ca1c42b6f563ed338189e34fa6c3e8d5922ca880062f1a75d8d73e3cce28ccd91097acfac61ce220ced87115497eda778f752709011be2b3aec8c33879c1b7d9f041cfea2e9f10ec121a0887e278396eb143953a261cc5d74697fb31f3b525f2129e9dce7542e906372204e07e6d68f59f2bfb9d194e059fc2816cc7b5faab72efde88c1daafb9dce629acf1bdcf7516b7551a8f0d427ae711881bb9dd56f6ddf46d96644fd2e7bd577830779ac1e706b6dc298e0b89cccbea03d22a857589fe4895f822cd5c5fd1634ffe6ef44b7dca09e57cf30126afd120fbdc1cde39aa695bdce2ca770926968c345e801bac05c163e4bbc4279d02daac4bb1a306be1941d646c5e93050adca4277432645be6a4ff50ddf5805d1070e4775d2d6e006453d6b67e718f8289e49ce80b841212e613e505452a827677548ec16fc965456db4e86d45b4d59be76f01e4ba348015b12e75937bf20", - "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441156615ed204aa948509f830e7e8756e609e419f8a6f8561fddd9202f8abcba0101cad4adce90c01d548eb5a88e3935668204c5bddb827b618a40626d8bc1281f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000203219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db70000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "proof_hex": "0x00000000000000000000000000000000000000000000000dfa79688268e94f45000000000000000000000000000000000000000000000003b27d8c4969fe006f000000000000000000000000000000000000000000000008596197ae31284d9a00000000000000000000000000000000000000000000000000025071b1b78e460000000000000000000000000000000000000000000000049f29ba73988453810000000000000000000000000000000000000000000000037166cb36624c1ddc000000000000000000000000000000000000000000000007d050eee5ee699fe8000000000000000000000000000000000000000000000000000258bb7095c7a3000000000000000000000000000000000000000000000005704f0d79a04cd41f000000000000000000000000000000000000000000000001cc8608e7634392ef00000000000000000000000000000000000000000000000af88bb11f4b13a3c200000000000000000000000000000000000000000000000000029db74f7fe7cd00000000000000000000000000000000000000000000000f4a5900047ae9ba6400000000000000000000000000000000000000000000000a2f7b686593ac5c9b000000000000000000000000000000000000000000000006e5e184d039f43481000000000000000000000000000000000000000000000000000265f972d900ce28738b09735682ead7a4c64799135201b3899d799236623c3b56cde6eeffc14c0df0717f0a39df3d76c516e8bf543821b9f4ba63b14188d420b92f5ed32350042061c4c31ac25d95dc3913a7a4720dcbd0d2b502eea4245f0e8e0b648eb3664f0ffcf0587456eae3287e653a00e8edaaebecd3e65d8ec98782517ef25ca5f5ed17e994084f3bba80177c052107cd4673933d4d7d498712c3c1a765d4ddd106cf23121b833a7165f5c9a7cbae738a5033ca28022a37b8399326468eccd785a1650e921736cbaea5f086a1fc0b8d34c9b3cf259d4260e3a0fb734e9ba562371b5d22be915dc76a01693899c6a34254a2ee1d2034d4b4afb734de2afae62fe3949727c3b05c1e3ca04b6abb43df9172b580ce32a1ea52c6a13bdabefe41b291b61b0acf905985d7fe37c2a12230fc1fe3c698d1495d937e0315f8ebc4f08b81f07b054fd658b021f59f1486e8105180cf9ea58448782cea621e76ef6e2b502df53c097f54506c667839a3fd6816ce0201339146d1334deb91f8ea6a14405ad6153a182d352d88c84c0f0d3446535350ae13ab7965e65605009887d7909a2fa1d42e2896551a0829706edd47b1b5786e28188506120cab5c15268750c76c2282e001032b6979a88d90b20a1db9d030107ffc0677ebcb6777c7f4ca2ee0510182362e2657252207babe037b83a8d8b3dc52cc67e771540a593d889433e9cb38eec2d71d52810b29a729959f506e4ee054bd6382f9acfcfa7c288777d3a5f4797e9342229726d66b20423a7f33a255cc294690bea014d9afb0331f91401058a271c34d2ab341191877abb7207f8754970389d7dfcfa00ec4ffaaeb0524dd716cfe7cb11e9223897133507d5227ce3ce11671f837ab1ef85d0aa6e308de0ecae5e49f712bf468ea81ea81e5527ee9e0f1a6128b1d1d32c56b82e3da07269e74c46c9978078a4fc2c3ec815158339b79250151302bb388375cdeada8e2669ddf041f19621eabb305f4d3270b826fa6ed2f25db9ffe39fc47e81839abfbecd91abc210133053d60869e919a115fda8d5046e59bfb2f874261d17b698de9e524a7145be6c521e3e2c29389e805e67940c921c0dd97b619b10e3d3e1822e3b2906d448ec85a031c38b5d1f34c2d4b5b7d5b6360c16fc3f097a28fc83c272b1fce5a6398bbe20a3997e59fc3a0e2317de98fdb917166780523993068ec1cdcd514df1fe9083f1991ee90b63c34c18b2639cc3c3df351ba4b8ee53f5663219c845085116bb81c1639cac4dda73a16cc4d7f9e8e607200c85a8e0fad44becf3891ffe93aa770132a39310b85cbbff14f0bce323cc23f445f6a258707355b3779232a642eff4b1a09e4b99928bfd02b699bf248fd01e881d98aef5772a6043cd5619e1a61af8b3303c7e35dd434b2854019587951ffb7e885f616ef360789979c7851ff5bb479421f42bb812a236b6fca6f7ded6823a28d36810b5eac6732fc2ad4410f715951cb2b5e09eda26e7793afd5c7c865de1570c4e72d9a88ce4b31a88264717a070d802a817a31b2c84d4c1f13a918c3a73c88d8a67f6c81fcf41ecd278894e88485c5062a3ef24ec877338c2cbafd1e61205fa95e2b93c59326cbf8f6468453a1e85e054db79eff791b9a1cb823dd9566f06129dce2b1f1c15e9c6d878629d40f61512eced624da055ff54fd71cf3520e5a759b33d31ce3d711c6e1163e3645a725960c4b1b6a5254cb9b135176e02075b45e9e1ea54e21b1a420b1414abc132d02be133cc2dfd9cdbf2a0a44fd11b51779483b4052c658b345b31ba93b918522167102cd4824015fe51e5b84a6fb335ac4842f9ed11d6f5e69b4d8dd8ba64e0f36270f78b42c71621f1501e1ba49fa4e661de16cb8dd3c698093969b8964809106412790264f0ae9b8007b76649a949b69ac1d6ec2a955902ececb7d33336b485a7c2c3c6a1fadf0fd121f79fface6cdf947dae0f776d069829fa900f514ece4141616bbbedf7de53e30cdfab6d5619028b321d44e93184fdf01e7ab3f5a4424386c23b8e5447413e6639c215e2f7bacbbe08458fe90fcff82f4dc73b1b9fa944e91108a5c28ea9df2a9e1b17874a186d1d5301848073af15ed52a4836a71b9576fb284357773419bdaa332b8130670664dea49b96012f02b091e273421d579b8b7c0db2b2715658dfaf910c32aab84a6eb1daa3f8c4c72cd2b43abc44cdb4aa8a0b0dc67c649a6c3b9cdcbea178401c0abcb272d8d5240a492956cdb2e4a3de78841ec42a7c9a5ab3b10d4264cf887b1c81451ebfb5e4277942e5736a7049bc071c168f11d6111ca6731a245c4f6f0aa9acba6d334d552193f8453f06e454c0f1b30e3264e919b2c667507684454b0045f26da17f27caf045c7b4d2f6be92bfa160277b4cf55287f67b9560a68e53fde3b7b85ee9043123cd7039658e7f874c136d1a2c26f2deaf00a930cd611ae4ca28ec30d65792e9493c2175e557b21e31a5102a8f42f94c87e31eb528d7a5fd4ca83ac3a1b62ed65113bf25e5e0a82dd2cae52cba89c170eaf2134fd4b818630ab330f68c040bca7285e619b2d493d713fbfe079f72b0b80fe7f56ea6eb5b20bf7990fa72a7f26191f159a2eb29d01801330d26bad38bdbd921c0e68d44a56c432329d5477f1e52f1d720e9dfb09f24fcc2f610e4303caced66f68ebcb8d876ec6f7c1904ab11800505a020eb41124069deb92d748417971506e406a675a65eebf63796897742b6080c037c097e742a446ed528783529668433efa5bade2e3f9052c11418f54b8bac5ae047f5fd30ba9e031f2bf38e36125c725b69365847ab2eaffb80c917ac7d3a97a47c1a1a9950db209d0326fe9bb980be5ef2bf21a3e85f236f53aa3843581e6e49d3b4451db82ff50218cdf7411b81f746a1086be6f27cffbf9f2352b4fca25777ae421cb673afe74d276522587e772895b53893a247b5bfb427dacfe13c2992700becb2313d3dc00f1876d430708da7298c907dff0b5984eafba5b26cd6fdfd59363b0bc511769da02db19b422e86e8e4003ad6554001fd10fd87d5f32af8a9d13f23bbe12525038a1a7a3867ea9741941c29e3aaa8491855617b16f140ded2b19a0b03cc4a4cd74c20f4111cdff9aaca53255e23c1c6412be63bccc4930ef87a63fb8e59411f56d4214b5fdb1a07fb3d5e91b25b3df5df862ad9cd72d3a24325c122801358aa149d2c03a7e24a687a2135762b2c1108cf1432e73f5ebb8e20a552ad92a91dbb185f11f9ede94d1ecebb9b30bc4c1a7744e2d121a63bb8fb54c2a83dcb8bb61cd6b600571edfb0c5ae31403c4fdebd9bfba727fe0422077b4bc1b660ad5ec5db84b7279d5845420a92bc08b2e5698b81383cc1490904ea5f20406d04b670ac20b49919e8beffaf81535d507d4ca8b08778bb8b791d016fb0c935e0ad7f1c6146cc4a262ce42077ad7d82e2e3848618c2e9514a3422581329e323cfb5e6153a6131990a4326ca63611c14ab69058cdfe7289463baabde69bfb64c895637ad70f47acb101d099896c7ba7b7aaeb2292c376efdfe9278aeabc23363ec0d2c0fad2cf14325801e832e9d2edeffbe63a053f8d6ac11a13118adbe3cb26f66bdc367bdf2a11bf5271e7b3828c52104b02b5f157695823763e7093e3e9e680921cd0c3dce450f4251845969a5c04cfa21f68c982ad2303130bdb22134d6210746c76817e25a249c64fff8b9d2e3651db73d13eea4360f99ebea5b17fd312fee8b1117e4967004fcf53c8939497fd46ee37dc67a58480fa1d8f2cba62cd1a04755796bdb1dbd0625d390458c05bc57aa6cec0ecf86e5b90d7d7484ce043ba332d42367e4b5310c45f065d59ed77cdf230d709944f6dab4c7782c82a2ce64161caa970c2c071c11e59f3300de1c8e44688c10c9214d8ee5d1402f31710c6c033adcef7c521b550cfbf8b66cb58eaf5b4f600593e7a7337c5b37df382e5df9bb7da69acd0935db2f71443d93c858a05143b20f06298edcc053d6f52755f8791f02c80856e1f55b0eab451543b5001697d60235605a12ca6377956f5161eabb574ea08f2741d0501dc63400f0e57099a68241c1d29056336dd70b0ed371da2615573480f10f933212ec6e0b1f25cbfe5ab5958a232a3c6555bc5d9a88ca2a5433eeb71500a178dc1003e570f070517a79e4ad9d72892bf563aebc21f65a15617fba60ab62749c622bb9822e4621ceeae8fc692ec1384c31b3fa7f85ea545106bbd4f0c8b5b03a6a0f64ca4fc38aaf821910592887b951fe39a88fed773f3c32e9d3afc97ee079d406d44e6772130b54178d8e84cf33390e8b880c554746bf355472185cbff9ba4c218facbf53bb5db501c6c583ac7df90901c1a4c7bfad4dc5a1f811986294c3e30b018f42f8d486433a79cebc05ab5a4861a0a19f413346be6108d93bbb7ab24d0f1e374662c55fbd4000b52009915ae41ace2fd2798513822da5c47b69c627522fa60c93b96255feeb8fead0646f6c03c55bdf0ce8c90d8a4ced28275e6005101dff152a15dedc7a5077b8a6a24fb6ba47511dcf942b097d341439041c53dd82030dff114cb5c1acff5f422b9f9157306540025097b5ca9666848657a1bdd8ac035532d8747b5182f12d2d76caa80b6ef5f2c23ed91c230c03f3c38b667fe41f03c5292df7fcc0485405a81a40666c864a1c0bd0f9797d7f00211a2a4d7073be1a8cc3df21420e1ac68e87a2eb75b32473cae6554a8c5118662b250f3c8e00ae2e2973ca4bf0d376bfeeaabf8f7b5c4eb4761a0b51fc018d7a205f02979d60c2027172019511cbaf761d504bfb9dfc8e01e45cd38b4e10103c13b2146174d8fb073f021f5d8fb8369b690f7a5df4044a2acc9e308e6165e6f7f5ea5d0d5f695a201986328ac16e02384a0f49de5929baa1956458ee19a901e8fbe31ecfa803bd2954fe80592a60132ae23e7c8d4d79dca4d60db2dbfe343b01cbab95a814deef0d2f09686caba0a5e8714860f809bff73ea57ed27ff26c921247633ff0f53d010898444c0522085bf95583c6bc1ea11245794f6442c79c3467afd6de0e938b9905fee8793edd702dfee158d66580b78e7124a0aea44968f9ded2dd0500d8263218735ffa49cc44890afd2777727aa4f9895a7039122d6e333b3520dde3f6096c29ec16859e98a504c88d771cc47aec7ff40a9e4f201ca83dfc7574e01261a9ea214114b3db1469a1cf55002bbd38d0ea429b1e24004d7677a57f16b4b0cbc25803108c1d04f5c0c3ef669689f62188b71909f1c11d95d514ca3a78edc8a7976422a8c196a42444ac4076ff06e369f839e38244111f04d4f74cc3ca2d635bc3001c60ee36b09471a5ed2d5db3a067183c50ddd40f2d74469507e949541d101d7e16c41645a3fc37a00b4708cb588611fe15d807d9861ea110e6883f4df31cc8ec278d447019f5d65f772020851c65d6a10ea601c7c4bcf78e58fc905b2c664f0d2c457a65f6424d6739ccaefc361f1e700d1735c61328bc29e75cb0d76b1c013910c82a1c8b34214adff97e9d94943f069509a46742bcd835da11ebb9b440dd3624c70366a5708a3a10b9688401e4250bf48266aa77d0ec6e5403d5db41f718f30f947098f457716160288bdb4721cea1adc69d2745d7aefc57eafbd2e901013b2ccf7ff182845d214e0fbe248a08364934d0ff522a9fd3005df960972ab255052930025839cab3bfbb81d5127ddf6fa01a61a613a6e8f128a85004743292f3cd2c1792d9ba72f886ed7a121297461743136ce348913ca557297019e2a3aec0a51922836c33d87bb152b06b9b9f3bbd144c703eb94cdf020568660d841a255e5d276bde9c1bf661ff908ef89874dde149fc4dceb010e3a6a382e292716cb4b8d916263774fee4ab4ba83a3ebf0b1064ebd75b9ae887644471f86a6bf8221107cc078182f2a821d52e0cfec07bc6657e50526ef9fd0048ec552d0808a742742aa625f90291e0ca4e5a4bd0c2588f4f2072da4cbc09e48791ccc16cea22ca882cd00d0381fb3133577f3d82a0a0bdcb0db0e88fe939063377ee25026eaabd38be1902111b320f710bb3503857b61c13fed36475db6ed1080063626c619d22f9b0932aa34375d85de0439ab7c194f504bc2523abd9627a8eb0c3ddfd751df66f5c95293d54b5e457bb7a9f8362a8f0e2a8acc4586c5f9109067fce81c82242a2eb5f2558d88d1bb575b0651061ce1f9bc8c75a95c5f785ef7933948632c1cb5b43592f88a62189b6ddad9274e56b188dcf13db455a4801c175f2bf802dd46ce5aae405421fc32aa47ef04f6c1ae84584ad7f02e065e6a7cfe8d1854a0f5431c7dadb0437a9c689c31a4cea1d48dc8bc6b635382ab3f7dcab912b6169fa9550900047047ef7b1b8393d511c82c6551d90fecf2662f336597b24113124e3d13b21b27b05f81ed1c2b356defe173c7cb7e4a5d33e4dda4cf7020e7fb85bf2893696a1a3238660d480aafbb0c4271397203e1a80122314f7b9ad807960830b0cacf78e1b1d45f76d3dce3e1db3071e9055eddca41a84da428fd19241adbc656e5cf7255b0cf5ad55a164b6805f639c3f7202975845aaa64ec03b57fa721daf278099b20c04630ee5a1d2cf8aa318da7097dfc780e843e1e2b8d7a550db5cad5d2ad4cfbf2e115682cc648ca983330ffb7283318b6311873be9977637d3acc6b2eb932bd00f387b1c9aed7bf928c15e9af4b7c165e4b59cc38d8e190b8b3a81d1c6d9f83725e0695fb46317bebde0aebedd01b2ed491ce402d501aefc8f4c1c293705be6b000354686877258d5ec4bec33fe416c64ce5925bc9d9a537b439250967bf458702d23d65decbeb6752b51e297d25b2432a6f5b64c0773b205c4e1446b087a44324cce538d0ae9959129c92b2240f863c773941aa0d1c503d20b91f430a467b4f2bbe0a36f9facb42624703f09f4288e1c7b74a9cbc5b2bdaf212a49f219b618c2580560061039f9eb6c52b7688ff624844a0a4acda0f1db128eef1bd0259ac3c176b1db37e377cb9d25a85c75ba3643e894de5bd3e998a4160837cd75f1cdc723038cec04a4853a6ba6c62cd4918f1632ac30de6ed5c0f8b0a68398ee741e60f184ea704315635056068c59f3feb2e28bba86ca05e77abe071bf4d179a0e9e2d0d2bcc51f8249afca59bf04cfb916937a0183917178db300a3d477e6c83f018f0db99b774c888c7019932c91882095d48b2c84a5004642e7ab200a22e90de77515c4e35e9d6ec6d71aba421ab36b30e7328fa15dd936f1c740838181ff349e122ffeb6ee1157415c7f104ac0f38ed2cfad62acb25a58a89eea6a5f66b4bf392520de5b7a89e66f24a828b7141b01fa5c1067327831d040d0e7a07f565528f2ef250121b6f9948bb2f3f2cb4099853f11073ea5173ed10bf2cd22f90108fc7c4c231b03d6f484e3bf256fd3d4f82388d90090764a9b6eaf6cb2cc2806c5fff469294e11a6fafce22457c6817315bc429ad19853b7957af2af6c3389e10c5a105a2e8d982fe73afb4addc3aa9b344fabc343c6438c8a59098f5936add0947217cc2ab165ac1555e0264108944578a3738595d56b7e274644af28a52c992a33209c05dfa9b8864f3155f77a4b18eb1eb793f4721180a337c7fb5a0b499ea96afd5d00044ba5da625f9a36bc38107cbedf12e0a51a8a2f59f2096e0d20e065018da92bc0a7112a7e48a4444a728d936338120a122db00a096cb486e3b67164120ed11205e12b3245fff17ccc63ec28b2e2a1f3d2bc7c8e7403e0c9c5d5a1514a2b900797eb3f3ea1748dfe9e23cad65e839d8e3074d0fd24a1bec13252b57f821f9d068c1cc3c26382875bc0d27da9d3bed3fdfed96ce2b7ddd3446e35d91b31d301164e3aaaaa7534f8ad4eb17b0621e6e5c876d84fa1937a023d2c29e37bb14c9202c71cc7c96f699ecaacae99aa36e15dd8055793bc6276958cbcad551d2448d1199499f2720dc367e892cbec806b3c9459f49f22dfa2b990fc8282a4ce499ba20799ba426355a8ef8dd0fd899bcfc06372d212c6ac1f63c8bd5e6914b18cbcb61704504f2e1e2ed6d86e2da36bbac86aeca425a6720cb4facfb7fd429b85ad57032d86246b281117624b1b92e7da1c0d27bbbff6a32918fc2f5945cd0b4a0ae312ce4799fc5d07c7180005bab2956d23025adfa9e3e37b7a6166084eaec7740518fa072d7ef56b4c1f8aa21142872240e2dbebec78db08384dac3cf7c36628851830f724379349291aedfc0f9cf05c92d4af5be0a50f586929489f98bc520eb906de5f1f41ebe26c58492fcf53552fa0d1df87ab01ecf27efd93652d85bf06180c0bd83850c4ddf904a68bb0f3a24d6703fbb5e7e3e3d58561e1f21783729acc1c3d2d9b96213fba91b08d5a06eca9adb713d1636c1c20ee1c6ff40a786694870e24656dcaccb56da1ff15761c4128774105f4869db44cd54a07414e76bae9ab2bd6f76e121840d8e8f87364deaa979ff118965f2ccb1ef97b3e45187af7eee1034b6d88504c0eb3f27f35f0f36cced25475b2f62df8cceedd3f4a9c7808fe41219bca2c439d0b29739bea7622a1d7c44d8a1de6d59c63b7ab55283f5df05cb70692e71c660ed45d49f1fb0790bdf274bb6cfadb9fe7d0c436f8f784478cc8df189e594ea67b7432713bf22c1199d90e0043695858aa46cccc397e528741c6b52e19c9ff45986020241cec343c8d8f74989c21f2b86e94a704335942c967bc9c032ae6b105131dbd3e550889cd96d3577f80542ab10e53487ebad39ca428ecbb236b4ac29357495fdbcd24b194b37aef7798539cb7407fc2d16cc02647616fda1bcd71bbaf8633ca0fcd9bb267a051933c14313c8a09c665da7ab26b142e9d811d717384396cecc500f378df1db9683fda74d5bc2c4e78fa1a89f7cf4975ad69066156264ceee9b8b8926b5a7105c90889998882ac9420f532112a6f1f2f2b9c023a3ed64af572f19d017aa3ef6afaab087d3bd768155bd3df0fc9f7f822ca88009d54f9ab76967e873ce437bd0f7e3195cb48599df46f54ef9d2e424a93f59213e02a423870816fe39839111cf60a4d2ec4acd8e43863cecead8f660361b8a903bb39e0d785dcdfdbe89b85c713b3355eee749fb6027ef71e9984d38806510f18a4b230924b0b848a291f8e62922077c1034005c5ee611f550a746bba75289e04ea00ca60efb7b8587281ce5223eaaf8a07771df77a7dfee0d61b4d1e01602517cdae4f6c4ad7205b5c2d781c36bb7f9c36d3a1db2c4eec78e001dc931594700617d097a075cf9b4e688aff67aeef2b5befdca4f21e388b8c655c2b55c24e511251c2d400d40a3946224c052f1ce75a4442306569e701bcc086439a62f9e04c0758fd7bda12e1ce40b209d30d67f2f003fea544afaa1d0420f6608116269508081983a5d8a574b216c19749a1472029898399220ee4a6506f95e7c5787f5b9925e200ee2c2cf08cf40b446659aa9b72d867e89de012b1336c390f8884c2087e09f19183af33cab63051be64938e007258d7bc38158dc0e80b4f2b76d13813ba2926c0c2da99395ffbf9e8cd65c95721cffa67de1b3aacb1e40f9a75ae46d9a11e06d148dfe7adc51debf3a5ed2958ac53f09e30b368648762c53d629ea154aa10cfdd10faa8de5faa738ed3d7bded2740c0187ffd6fb2f51ae27931572d853d27b75276de25a8deb23b075f1581f71d8b45f9525f54c924a3057476123f900f1f8fc748b50883c13789486e4a0750c4c2b32d747542761d6b41b5afdb17086b17b7f3f2125e5df91bd8ff04ec54b3b732214ab81bf6e21560db4780f1f0ce7329d6540a217743efe23cd1c6694b52623718e1478973ba5f76afd37d376b8930082c5adf2d53ad44dd629106b3c3b3ef24829f1570d6fe0e6bc673a33d3f233406fbe881c13361f5495c94f2d43887657f474a5ca6ebdad16ee92ebf3755c619252bb90cee7c61ef1b3729012c54101ff03af47b6444e81ace561d759d309b050a82f6e71cfd7854a68ef7452aa7e48f7c5ae0d48b5f2d54902687a8f0bb78852bbcb6b17cc2f8cac0ec1526e2a60015d3efd9a0426d82aeee4260b71813bde80392ede8d86bf0d16af0977963ce5a573f7d561fcd20ab05e2db8ea7ccb334ab0307670beb2978093fdf7001199dd0d72b0b7752ecfb91da30847c8243072a7c2f199d811b6a6c1635c6ec835b05fd77235cb3d8451194f699293e70133d756f2c9881849ce8eae584597a83c53a47450a578d88f75f6982d17ddea04e9b9ed5095939009049cfc7cd6cf9f412a3cde99720adb91ee077da2aeafbc7a033044a0b672f1ad786fbd543528c38703fb4a37c1db9a2674feabf00ff33a5ceb01bab1aa064e846cd5d748df1714875b6a62c9dfe562519ab164540c0d7530589c288064e7b496b7184387d1d4686c18f22110364c55e53f3a70d016832be570218a012f6b252d06f73d254937d9062a293346adc20823419633ffed17822bc3259dc061a1a8863d10da15f11186f71f04b20e0d152385bc108ff740a68bf824f890f05b422bc8f53d3255aff1e028a79f6da0e0e24e931497d03ca96b04e687a6f6300ef2bf5af84353c1e1a3aec79fe45be15ff7c3791aa7dbb919da84d1106515f2d5ecbc9c4928ef292fc4de434d4b92ac996d21ebf2d7d0b9d99a295622cf2ed2ef5cbf883993dd846bae8f4fdbae671e7338c6e1743fb26ecfd0e40e409c60b03445ba5b1bad93b6d8fd88b0dfb82ea5a9a01db23cf5f74ec68b4ea42a309c624208abd552ce7d9b316865cbfad7d0c232c8f3589cc58f93168ad5fef7c3843002e357ed1e5708133f433b4e0976a4b1d8f75d99556678833e17699e399f9970d0053375c14a0ab5cd8135fe265e537ae1d98e32f64258458b7ca404128db1e2c187a91f43be9f07bbdf161b002391f1b31d31a2c8f62d7dab2f8d7c4e618a71a943d0f30fbce765f0a81a0b86f000a9edca80be34d9fb22fd5959a52dff8b214d45dd690880833365f782eaa2bbdba3cc6758d345dc129399b5ad29e5d8b1f25d06a5eade8a0ef42d3759d662b6c3b27d9ca7f5804c2b3e92f1cbf128efb05252410af5cc57c287a8f8c6c3e7e83ac898b59003c3c39da20e238659b09f1df157216dafe77fb079590574e4b4123bf304f18960ac407b2405de4825cc00c35061d04805f2451cfe3e026bb617a8e284ae1bb816526a9c506a33186bdfacbd016102199b0ef23d253849057f884b691e22de105d33dd87777305d5ea3c564ff00af3dfa4db7f4b2aa305bda33a2476a6b05cce69d61d9f75f986dfc4527af3f19102cb5b69b2842d6d7e9e90e8d575adbc16ad8a3003209e911b2a11d4e200225ec90847799d4821848766737493f708ece7a692e4885692d011ceade273fc4041c5d41854376102a27aceaa0aaa4c3257eb59982599d817fb2605623931306009cb304bbce9135174946a02bb039b7995536a8c4dbb218259ddb2c1c5b9dd411f093e4e518d590f06f8c106fa0f4df4b40f10db27b63d53eb4decb2481d15a1b1f9a4dcf66168ae5f6d7c79354ec366e79b5875482aed5d9a686fdb62b17630dc56a8b87bc1dcb6329bf2d19a56110dcc82f939acb1a6e70e994bb94ce7ff31a3b1db0cf696f5c842eabdc0a6e9d5372ecb94426fc8faef668ab3d9576705e304a945cf241ce3038a11c6f5622a3422ca25d6d0040b99e5cc4e4b39843b7d72534843b4222447511a5174d7c860e10896b36b505a0e16e37cdf8ac5691664e1e5ea49b6f6f35384f56d9faa8b6aa800fd2444e741c31814b3bb2c8c6cdf828187c46187808eac8eed732b528bd82ac8f43e6db3dcd19ed12205172f578245a1589aff49acc083e14f1caa589eabd4d490f6940acbabb055c05319dcded45bf21f0d43708de5ca2383859008ca641deed357917f5ec7ba58101d82a5cc8a6f524f19284b599173697a880f26ba158d39dde2cf107c3dec0a9723aa76b6bad28134544a94eff974c94c041ba956834fb7b8a20cb3f9594b54e896704c00828401eb747c909f8e2fd22eab075a9078c84b13b6bbac635ae9abaadb151c6e827b606742f6ff2939ada26729759830191df4708924fea7ebfebcff8f927d22df05724b550de94617b485e6049826fe78c7dcef0a4b2d23fcfd60d744b89dd19180f1b06d00b6b4c79b71bd446267e49ceaf11951b2d9082b09d0e3489fe070a744a0e64fa7d24d7703e2e82a7f26381ca659b1f66255b7efd0df075b6ba4de7a085030738dcb43875953999c2f7d5392df24b864833ccc9bca50062a633f8e7b8150bb74b7a7c537b12c72b109f8c212bdc542940fcbe580040f301baf107ae48ae17da9f15e0d3439be0bd2a45788973bf8745d03428478327de779fb78c055f53138a8e8df3e15405872ddae7b1ce4515871a20b0787503e861c20abb64c517e0042a2680e7a04527301326182626e560ba34cbcd567a6fbb797077ae12ee618312c49cbfef179c6440930137664d6cc87902a61de833c0aed0a616790b8a9ff71c492e8944bc3f60fe2de37788fef01f939351f4b1fc27098590ebadd75746f60b012641c5ef934924a686fb002c329d97277967b2da3706e342c7418340cef72d0392b4fae0d4ac069893efedb6739f3bf6c4ccc98c201a908dd8f2c46ec94720c00cce419319dfc91c3b842b3e8591e284dca480d39268d31117cdd8efc4e520f283358f61913978ac3430c515e7517268d57226dfab2e09755fd0fbb8654723c336ff3932cd6cd57377fc84ad99e65e92e3e62a10cd8cb84d1eabe63874b70602ec92c43565c29787cfbf0eb1066ce59023d4ae6b066217bdc050dfad86e31c4e357566f631a0ec0d3fa61c328756f7e8e9d5b3b7c8f86cbc08daabc2e8f31bf8eb84ff8a4a6db3643f1495b21c73cad93e3e2fd220aaf09a29cf4c9c5864053a1331b441aa1c585625e656e3e58df740cf3d457c40b0429e10e67b7544310643409645badd52389b0023568f354686018d5cc617ca0be53ea64144ab52b5109a28e74e789766193593c8bad70d10b403c06dfd7ca3b97079f9a4974f563a19019c8c895f9372f50226c3b0976ba2dcba703af39b1c50c7a46b720ba7d6491ee9143c7b653930901b4617eac146fee04757443f36c7156af58c8bb33670bf2928276bea49e7849cc27cafdf183902bfbed16820c68c2238e877290b90a118068947b5a8977360e5a952e0036257dee5e0443433bc39b931f3a78a42a124210a51c58cfd80c56b67a52a3238b4a47524f9e269369e91ec03c1b7ec246c04420d0035d930d1a4936dae183715bee51356873764905f7e7ca33c3f31a56996e22caba046602b6b24130d134eccc1cfaa4eeb4a5eba6fa0cbc022057243d8d478035a50d38b9c15b98af87ef36ccfcb1a41265398b117976d06a7b604b0945f6724c34befafe430b6e687635eb05e98b27b9e57fc05ceac658bbf43be2b055ceb12385938b72f3e4e0ec92cbec13b6b816fa60b5404b418c33fe661142a616b6e24e8f9c3bb35d37e457d1dac5b9c74f471beaf7f8f4d26f608f520ccf0e113801460fb5f0d9b7c6ec1f81756e4486d34752010a0dfd19ff23b9bab9cdcfb1df1251615cb508e4922ecfab788decf45b7e877c73e46391f8e7368dbc5f351ebce144bd31203ce49b741425627c097ec248008f704ab6321f4c59e6e6c1adcf21d255b9c0abc5e5d1e913335b2f5c18fed758628396b06073450bdc8e51b9ac17a15988467eb7f3ec60395c779f28a2a1d9998f24515ca5b47eb5cc29f875c9d1a1165b3fa07fd3b99b18269fa72901035818a9bd02031ad308ff76ede118c97350024db3130d1c0b83bc7b65c3bb1f886c3996c4cd8939139aeb8e749c34ff131274570245f1e762ee28f9876c9e240e56dbafeda6fe7047f8f56148b0440f23f0d011a69b14d6dc35825881a3eba8c695d89526348a2e783135364552adcb2de2bd4bb42f48491930f07c20e89c9f87dc463d93e72a7162f518cab3474af3cd60888cd45bad31620195330ad1fa68c7b800b83761b351b440ee1542ebddff7fc14b018c913564c935e83398d0e28e5cbfd160707ca15b6e4efde70def302103524f2d9162a684c86e6dd17b74948e34b7523839b5557457dae8b84d9679010b82b4f9b6ccffc1777904eda4e4583e195476f62b6b2fc96fa400281d935327130216f637efce4bd7967925161f603ef63854cd24c1637de8a8fb2fcc7031bfba6108270c3dcf4e240a99c15115a88522efafbcb2905c304d35cc0db64799797a10e49bd25c35c762064bf13db5ed47baaf7dd7c0f4a4e768926eb2b5f9f2b7e9b0780258805e32665ef178dd88e89fbeb7c2dbdc7f4c7672d6cfa8a46075a304407aba54c51707cf93558bf6f2bc15e138ce94d38ef015c8abdb37dc627159b601389b40547fdd18c07caa2e8c156ac50719ee2e1e57d111bd79ae6d03a1297a40c36bfcb7110608d12d503545f26013b67f6883ade09afc1a9ec2287c5e0b4fc18961675c195b7025239a4f728b6354262a3b333a9f49a39f5f740652ce6fb271e03230bc5559de174f64dd0d90f02b5f2a2eaf004278215a9d856042f48cb3e2028a458428b511f716a00e9432a28ba15a6eb8cfd6a26c33641dcf788c1f6a71cfdd7f6043c8cf84ada544f719aad323ec1d2ee9f5a4888114e008cf4c467cd2b509709b141b7d822abeb2f1122d0735485f29454e0077ef21016ddcd68fbe9", + "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441156615ed204aa948509f830e7e8756e609e419f8a6f8561fddd9202f8abcba01000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7001cad4adce90c01d548eb5a88e3935668204c5bddb827b618a40626d8bc1281f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000203219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } } diff --git a/circuits/benchmarks/results_insecure/report.md b/circuits/benchmarks/results_insecure/report.md index d32a04903f..38cac38db8 100644 --- a/circuits/benchmarks/results_insecure/report.md +++ b/circuits/benchmarks/results_insecure/report.md @@ -1,9 +1,9 @@ # Enclave ZK Circuit Benchmarks -**Generated:** 2026-05-18 13:44:31 UTC +**Generated:** 2026-05-21 08:52:11 UTC -**Git Branch:** `feat/1524` -**Git Commit:** `7df3cad298ea4d0194af1dcea8afc397a7c0540e` +**Git Branch:** `feat/1525` +**Git Commit:** `a6455239f48858b46d3a55562def9147c130c18d` **Committee Size:** `H=3`, `N=3`, `T=1` @@ -15,36 +15,36 @@ | Circuit | Constraints | Prove time (s) | Verify time (ms) | Proof size (KB) | | -------------------- | ----------- | -------------- | ---------------- | --------------- | -| C0 | 6847 | 0.12 | 26.98 | 15.88 | -| C1 | 57818 | 0.33 | 25.28 | 15.88 | -| C2a | 142625 | 0.77 | 25.29 | 15.88 | -| C2b | 198355 | 0.83 | 25.44 | 15.88 | -| C3a | 132633 | 0.79 | 26.15 | 15.88 | -| C3b | 132633 | 0.79 | 26.15 | 15.88 | -| C4a | 92515 | 0.49 | 25.59 | 15.88 | -| C4b | 92515 | 0.49 | 25.59 | 15.88 | -| C5 | 151717 | 0.79 | 25.38 | 15.88 | -| user_data_encryption | 53732 | 0.32 | 24.95 | 15.88 | -| C6 | 86927 | 0.50 | 24.76 | 15.88 | -| C7 | 104273 | 0.48 | 26.30 | 15.88 | +| C0 | 6847 | 0.13 | 25.55 | 15.88 | +| C1 | 57818 | 0.35 | 26.34 | 15.88 | +| C2a | 142625 | 0.82 | 25.47 | 15.88 | +| C2b | 198355 | 0.91 | 26.32 | 15.88 | +| C3a | 132633 | 0.90 | 27.00 | 15.88 | +| C3b | 132633 | 0.90 | 27.00 | 15.88 | +| C4a | 92515 | 0.52 | 26.04 | 15.88 | +| C4b | 92515 | 0.52 | 26.04 | 15.88 | +| C5 | 151717 | 0.80 | 25.86 | 15.88 | +| user_data_encryption | 53732 | 0.33 | 34.30 | 15.88 | +| C6 | 86927 | 0.52 | 26.58 | 15.88 | +| C7 | 104273 | 0.56 | 28.38 | 15.88 | ### Artifacts | Artifact | Proof size | Public input size | Verify gas | Calldata gas | Total gas | | -------- | ---------- | ----------------- | ---------- | ------------ | --------- | -| Π_DKG | 10.69 KB | 0.41 KB | 3037910 | 175424 | 3213334 | -| Π_user | 15.88 KB | 0.12 KB | 2972965 | 170200 | 3143165 | -| Π_dec | 10.69 KB | 3.41 KB | 3549222 | 186764 | 3735986 | +| Π_DKG | 10.69 KB | 0.47 KB | 3042430 | 176112 | 3218542 | +| Π_user | 15.88 KB | 0.12 KB | 2972893 | 170308 | 3143201 | +| Π_dec | 10.69 KB | 3.47 KB | 3553544 | 187152 | 3740696 | ### Role / Phase / Activity | Role | Phase | Activity | Prove time | Proof size | Bandwidth | | --------------- | ----- | -------------------------------- | ---------- | ---------- | --------- | -| Each ciphernode | P1 | one-time DKG participation | 304.50 s | 127.00 KB | 128.19 KB | -| Aggregator | P2 | combine folds + C5 | 0.79 s | 10.69 KB | 11.09 KB | -| User | P3 | per user input | 0.64 s | 15.88 KB | 16.00 KB | -| Each ciphernode | P4 | per computation output (C6) | 0.50 s | 15.88 KB | 16.00 KB | -| Aggregator | P4 | per computation output (C7+fold) | 79.27 s | 10.69 KB | 14.09 KB | +| Each ciphernode | P1 | one-time DKG participation | 304.14 s | 127.00 KB | 128.19 KB | +| Aggregator | P2 | combine folds + C5 | 0.80 s | 10.69 KB | 11.16 KB | +| User | P3 | per user input | 0.66 s | 15.88 KB | 16.00 KB | +| Each ciphernode | P4 | per computation output (C6) | 0.52 s | 15.88 KB | 16.00 KB | +| Aggregator | P4 | per computation output (C7+fold) | 79.88 s | 10.69 KB | 14.16 KB | ## Integration test (`test_trbfv_actor`) @@ -53,15 +53,15 @@ | Phase | Duration (s) | | ------------------------------------------- | ------------ | | Starting trbfv actor test | 0.00 | -| Setup completed | 3.04 | -| Committee Setup Completed | 20.24 | +| Setup completed | 3.07 | +| Committee Setup Completed | 20.23 | | Committee Finalization Complete | 0.01 | -| ThresholdShares -> PublicKeyAggregated | 304.50 | -| E3Request -> PublicKeyAggregated | 307.02 | -| Application CT Gen | 0.32 | +| ThresholdShares -> PublicKeyAggregated | 304.14 | +| E3Request -> PublicKeyAggregated | 306.70 | +| Application CT Gen | 0.31 | | Running FHE Application | 0.00 | -| Ciphertext published -> PlaintextAggregated | 79.27 | -| Entire Test | 409.92 | +| Ciphertext published -> PlaintextAggregated | 79.88 | +| Entire Test | 410.21 | ### Thread pool (same process as integration test) @@ -75,26 +75,26 @@ | Name | Avg (s) | Runs | Total (s) | | ----------------------------- | ------- | ---- | --------- | -| CalculateDecryptionKey | 0.12 | 3 | 0.35 | +| CalculateDecryptionKey | 0.11 | 3 | 0.33 | | CalculateDecryptionShare | 0.61 | 3 | 1.83 | -| CalculateThresholdDecryption | 0.58 | 1 | 0.58 | +| CalculateThresholdDecryption | 0.56 | 1 | 0.56 | | GenEsiSss | 0.12 | 3 | 0.37 | -| GenPkShareAndSkSss | 0.22 | 3 | 0.67 | -| ZkDecryptedSharesAggregation | 8.57 | 1 | 8.57 | -| ZkDecryptionAggregation | 49.05 | 1 | 49.05 | -| ZkDkgAggregation | 20.15 | 1 | 20.15 | -| ZkDkgShareDecryption | 1.50 | 6 | 9.03 | -| ZkNodeDkgFold | 62.89 | 3 | 188.67 | -| ZkPkAggregation | 2.16 | 1 | 2.16 | -| ZkPkBfv | 0.33 | 3 | 0.99 | -| ZkPkGeneration | 1.33 | 3 | 3.99 | -| ZkShareComputation | 2.69 | 6 | 16.16 | -| ZkShareEncryption | 2.49 | 24 | 59.76 | -| ZkThresholdShareDecryption | 6.05 | 3 | 18.14 | -| ZkVerifyShareDecryptionProofs | 0.10 | 3 | 0.29 | -| ZkVerifyShareProofs | 0.23 | 5 | 1.13 | - -Sum of tracked operation wall time: **381.88 s** (often much larger than end-to-end wall clock +| GenPkShareAndSkSss | 0.23 | 3 | 0.68 | +| ZkDecryptedSharesAggregation | 8.50 | 1 | 8.50 | +| ZkDecryptionAggregation | 49.37 | 1 | 49.37 | +| ZkDkgAggregation | 21.12 | 1 | 21.12 | +| ZkDkgShareDecryption | 1.47 | 6 | 8.80 | +| ZkNodeDkgFold | 62.33 | 3 | 186.98 | +| ZkPkAggregation | 2.20 | 1 | 2.20 | +| ZkPkBfv | 0.34 | 3 | 1.01 | +| ZkPkGeneration | 1.35 | 3 | 4.05 | +| ZkShareComputation | 2.68 | 6 | 16.09 | +| ZkShareEncryption | 2.51 | 24 | 60.15 | +| ZkThresholdShareDecryption | 6.18 | 3 | 18.53 | +| ZkVerifyShareDecryptionProofs | 0.10 | 3 | 0.30 | +| ZkVerifyShareProofs | 0.22 | 5 | 1.11 | + +Sum of tracked operation wall time: **381.99 s** (often much larger than end-to-end wall clock because work runs in parallel). ## Raw circuit benchmark JSON (Nargo) diff --git a/circuits/benchmarks/results_secure/crisp_verify_gas.json b/circuits/benchmarks/results_secure/crisp_verify_gas.json index cf6816e9dc..143ef26204 100644 --- a/circuits/benchmarks/results_secure/crisp_verify_gas.json +++ b/circuits/benchmarks/results_secure/crisp_verify_gas.json @@ -1,82 +1,82 @@ { "verify_gas": { - "dkg": 3037922, - "user": 2972869, - "dec": 3549077 + "dkg": 3042688, + "user": 2972893, + "dec": 3553795 }, "source": "folded_proof_export_plus_crisp_verify_test", "artifact_sizes_bytes": { "dkg": { "proof": 10944, - "public_inputs": 416 + "public_inputs": 480 }, "dec": { "proof": 10944, - "public_inputs": 3488 + "public_inputs": 3552 } }, "calldata_gas": { "dkg": { - "proof": 170028, - "public_inputs": 5528, - "total": 175556 + "proof": 169992, + "public_inputs": 6168, + "total": 176160 }, "dec": { - "proof": 170088, - "public_inputs": 16676, - "total": 186764 + "proof": 169944, + "public_inputs": 17316, + "total": 187260 } }, "integration_summary": { "integration_test": "test_trbfv_actor", "multithread": { "rayon_threads": 13, "max_simultaneous_rayon_tasks": 1, "cores_available": 14 }, "operation_timings": [ - { "name": "CalculateDecryptionKey", "avg_seconds": 0.599410291, "runs": 3, "total_seconds": 1.798230875 }, - { "name": "CalculateDecryptionShare", "avg_seconds": 2.123328597, "runs": 3, "total_seconds": 6.369985792 }, - { "name": "CalculateThresholdDecryption", "avg_seconds": 1.93815725, "runs": 1, "total_seconds": 1.93815725 }, - { "name": "GenEsiSss", "avg_seconds": 0.755760708, "runs": 3, "total_seconds": 2.267282126 }, - { "name": "GenPkShareAndSkSss", "avg_seconds": 1.230714874, "runs": 3, "total_seconds": 3.692144624 }, - { "name": "ZkDecryptedSharesAggregation", "avg_seconds": 18.895682083, "runs": 1, "total_seconds": 18.895682083 }, - { "name": "ZkDecryptionAggregation", "avg_seconds": 48.057542125, "runs": 1, "total_seconds": 48.057542125 }, - { "name": "ZkDkgAggregation", "avg_seconds": 20.904339167, "runs": 1, "total_seconds": 20.904339167 }, - { "name": "ZkDkgShareDecryption", "avg_seconds": 30.160204763, "runs": 6, "total_seconds": 180.961228582 }, - { "name": "ZkNodeDkgFold", "avg_seconds": 102.337581166, "runs": 3, "total_seconds": 307.0127435 }, - { "name": "ZkPkAggregation", "avg_seconds": 49.016015041, "runs": 1, "total_seconds": 49.016015041 }, - { "name": "ZkPkBfv", "avg_seconds": 3.839788277, "runs": 3, "total_seconds": 11.519364833 }, - { "name": "ZkPkGeneration", "avg_seconds": 65.134843083, "runs": 3, "total_seconds": 195.40452925 }, - { "name": "ZkShareComputation", "avg_seconds": 52.426543555, "runs": 6, "total_seconds": 314.559261334 }, - { "name": "ZkShareEncryption", "avg_seconds": 112.963847905, "runs": 54, "total_seconds": 6100.047786911 }, - { "name": "ZkThresholdShareDecryption", "avg_seconds": 244.367978902, "runs": 3, "total_seconds": 733.103936707 }, - { "name": "ZkVerifyShareDecryptionProofs", "avg_seconds": 0.092927916, "runs": 3, "total_seconds": 0.27878375 }, - { "name": "ZkVerifyShareProofs", "avg_seconds": 0.266464458, "runs": 5, "total_seconds": 1.332322292 } + { "name": "CalculateDecryptionKey", "avg_seconds": 0.614281708, "runs": 3, "total_seconds": 1.842845126 }, + { "name": "CalculateDecryptionShare", "avg_seconds": 2.121472944, "runs": 3, "total_seconds": 6.364418832 }, + { "name": "CalculateThresholdDecryption", "avg_seconds": 1.95707425, "runs": 1, "total_seconds": 1.95707425 }, + { "name": "GenEsiSss", "avg_seconds": 0.758238652, "runs": 3, "total_seconds": 2.274715957 }, + { "name": "GenPkShareAndSkSss", "avg_seconds": 1.242666944, "runs": 3, "total_seconds": 3.728000834 }, + { "name": "ZkDecryptedSharesAggregation", "avg_seconds": 18.979502958, "runs": 1, "total_seconds": 18.979502958 }, + { "name": "ZkDecryptionAggregation", "avg_seconds": 48.341644417, "runs": 1, "total_seconds": 48.341644417 }, + { "name": "ZkDkgAggregation", "avg_seconds": 20.006914333, "runs": 1, "total_seconds": 20.006914333 }, + { "name": "ZkDkgShareDecryption", "avg_seconds": 30.277848645, "runs": 6, "total_seconds": 181.667091874 }, + { "name": "ZkNodeDkgFold", "avg_seconds": 78.310650236, "runs": 3, "total_seconds": 234.931950708 }, + { "name": "ZkPkAggregation", "avg_seconds": 49.050973916, "runs": 1, "total_seconds": 49.050973916 }, + { "name": "ZkPkBfv", "avg_seconds": 3.850818819, "runs": 3, "total_seconds": 11.552456458 }, + { "name": "ZkPkGeneration", "avg_seconds": 66.056590278, "runs": 3, "total_seconds": 198.169770834 }, + { "name": "ZkShareComputation", "avg_seconds": 52.534038875, "runs": 6, "total_seconds": 315.204233251 }, + { "name": "ZkShareEncryption", "avg_seconds": 114.608395854, "runs": 36, "total_seconds": 4125.90225075 }, + { "name": "ZkThresholdShareDecryption", "avg_seconds": 251.230740403, "runs": 3, "total_seconds": 753.69222121 }, + { "name": "ZkVerifyShareDecryptionProofs", "avg_seconds": 0.093863888, "runs": 3, "total_seconds": 0.281591666 }, + { "name": "ZkVerifyShareProofs", "avg_seconds": 0.264344016, "runs": 5, "total_seconds": 1.321720083 } ], - "operation_timings_total_seconds": 7997.159336242, + "operation_timings_total_seconds": 5975.269377457, "timings_seconds": [ { "label": "Starting trbfv actor test", "seconds": 0e-9 }, - { "label": "Setup completed", "seconds": 3.274390084 }, - { "label": "Committee Setup Completed", "seconds": 20.259594916 }, - { "label": "Committee Finalization Complete", "seconds": 0.005869333 }, - { "label": "ThresholdShares -> PublicKeyAggregated", "seconds": 7204.022842209 }, - { "label": "E3Request -> PublicKeyAggregated", "seconds": 7211.068496417 }, - { "label": "Application CT Gen", "seconds": 7.746761542 }, - { "label": "Running FHE Application", "seconds": 0.088362083 }, - { "label": "Ciphertext published -> PlaintextAggregated", "seconds": 814.168040875 }, - { "label": "Entire Test", "seconds": 8056.619484583 } + { "label": "Setup completed", "seconds": 3.273315 }, + { "label": "Committee Setup Completed", "seconds": 20.279577333 }, + { "label": "Committee Finalization Complete", "seconds": 0.007173125 }, + { "label": "ThresholdShares -> PublicKeyAggregated", "seconds": 5158.12970425 }, + { "label": "E3Request -> PublicKeyAggregated", "seconds": 5165.210807791 }, + { "label": "Application CT Gen", "seconds": 7.707659625 }, + { "label": "Running FHE Application", "seconds": 0.0710595 }, + { "label": "Ciphertext published -> PlaintextAggregated", "seconds": 835.140242834 }, + { "label": "Entire Test", "seconds": 6031.697821958 } ], "folded_artifacts": { "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000830d9d4344316b026000000000000000000000000000000000000000000000001d383081c39dbc5a000000000000000000000000000000000000000000000000ac70e435f22d64fb500000000000000000000000000000000000000000000000000005bbc150f125200000000000000000000000000000000000000000000000a8a546866290bb770000000000000000000000000000000000000000000000001fd3f2400d703cfb700000000000000000000000000000000000000000000000b9038d2ae3e79290b0000000000000000000000000000000000000000000000000001e3d48d51e5500000000000000000000000000000000000000000000000067a0471dd42faa6b0000000000000000000000000000000000000000000000000e9084f4ea2d5e512000000000000000000000000000000000000000000000008a356e94c183365dc000000000000000000000000000000000000000000000000000254af5f427efd00000000000000000000000000000000000000000000000238e18ad2a5a9480f00000000000000000000000000000000000000000000000bd3b65543dd7dc02f00000000000000000000000000000000000000000000000759321a99ec5a19300000000000000000000000000000000000000000000000000002a525effa8d9000ee44df0d016c13539e3e1de25cb3283bfa0110644e6c3060b51acf455c43f02d5202ac66917f20fae1a39f8cf51134df47884f67caecca680f87bdfdd85ccf0315bef50348a88d4c79a1b50bdc50c9882a2946c73cf72c563058759727f8a009db15cdba20a346d9491fdfdff4ddaf05c2474d9c1f2c4821a5e2e101b7b8e82e181958e78629f078e836c725ba08236958e3445a0dc31fc4c2202707b61c7d0ac53aa35319f776db882a6acee6b04a492720c30b527f6a209efbfb4b22975403a5568ec8e19525b52dfe82dfd9aaab141462570f5c39f9a42f13700ff87603118b076682b92bee70ee8f9b972b8cdeb9ff1fbd603352f945f2c95fd35184f70f989616eff536ee31d0349dc97067aa11f2ab4c8782c4d19a4b89968e13f69f208509774cc987cc232b93c9c49974be00e3ee21c6d743b80d823f9eb1ee13be236cf0e7b7aa0a5a5f4207edc057a37096d17a63c48f2866132c681a904108c02045139ff715913e4d22a696f788d1cb2424d855ef9bfe36f67721de67235cab0e4f4cce9ff0f3588aca137e0740c7dac2a980816ddc38f10be0dd37f01028891d4476773d637a1bee280492d73d68838af602126de7b85d767e835f1ec2f5f7015609620fb34c0980312b5b7f67ba6ad756f683152cd1a95e9e4c9a8fd58bbd1c0b2d262ca7d1cfbfc729424917aa0bccc6e667b7d4e4293e56552cb688b8320ec6d51d706a3d0b516eeac14f7b49e736cb687e82d64d239005709ea7a22af41daaba74d8165e869cf52616a224d38bf14b43f9365e25bdb8f5e3088158cc3e2ec485c6affc47a2b1a4a1d0b691d81aa7efeb0d4f243c3f9862a9b376e7648a2a1f40a23824acd2860b8fd4464a89ad9da06c090a2dc69564011c9749dde2ed15a551e0c27cb57298106bdf016afc08b87f0ac06032ee6860c10be94821fde507c4f9ccbfd67261a4729466f98ee1db61592af1fc7b39e2181034e27abc492409e069c23c577f4749acd5236e349f1c92837155ab5553d1ce276d8aba649f661e4ae3dcd8f73ba139ca807d90d6dec1a9b860762731186ba09357343823fd671a0a8440d758f2714b07ce0b6d8ee3e072af2f999efd2b2f4bd29a0b7e4ee2fb03969abdb773917cdfc033166bdd42ee8c0f0de8fdc1f0b959ffd56c806c06ea1137b28ee248c3176911c6a89f3ac4fbe9294fd2c25740790a660a831c1fb96109efa0ff705b5c893a9243584fbbbef285f05ca9370a3a352ff33e3fbb4ce74222a57e9df2068cf76844517674c6e6a188fa7158768ee6fb34da4c185fb830a8030b0eff418ff974072732b830d30df3199387ea05c52692283f7bcce83b46392ff77a2391ee371a20d92c00b3e9ce77fdd50918e3ca550e914a7a53ee6f8b7709d5a71495d8ed3e4500f7d429da6dc0ce8b1e10e8153d28ed7b0454f33cecd924540395148ae0936911fd4c376a78890ebe5d7fb220351c257b7bd4569d752023276726c1d48dc36a0147a3db2a69a24b00b54e87d42177e95503de125797ab2420f3fa31bbd5c0e70f3038b55ad7e40fbd4380e86fdc7fe89164eb0aacd59012dfde37496f6116d41ff33c74efb86de3dfa2d24cefc0b63c89d79e133cc29905efb2920c4f7da9c8b961871dd18fd44999a25e5dcccc9ccab601a2e675373e100c397861eb058b5755e03a51eae9d52c2e4d4995ae4ca18e4dc2233d7d7aef09e64d43b4813625ee86b3dde7f88897786e1416eddb163c124b159785245e69114691c2e2133c527da43f96a3ce84e6dd4ca5565323c6c315ad829d67ffe1c404621eb8bf726f2e29a09c7859bed166cb8ba83b62b89937330ba87944cfa8ca0ca6890ea5b94cf33b92150635f7eaaa4f6ba748de2c1511f5951f64b2020cc62dd083cfc17c88a46303505006aba555321be0a57109e342280647134ce385c5299579a2c5323a9de3f476deb15b2bef26ae534a4cc8ef85736d2e278da053c606e1876d5599770ec050ca34a7586b97509498768869afbcce36fa99b3bea7e2190eff69b5e545803434ea8ad62014852a371430a727701311a6f04fa47cb2cd08ca37d24e1311f454ce5d64f1be459f3f63bd3c2c5d2d8b894886deb7403c1915a57f7b0dc00c079803ca7502bfe4818087b1bee5e5ef561924cb46df8ee9af2f4791d0d4821ba79925efd25af9808cbb8277cd45e6c8b1c435290fc3a81816113cd7b0348fa54da05b8a621dc0216d78be0a5d5e1a910fdc581e4d05f27a011ecc21fad91def43ccce7539527630fe9efe81a8af34587cb9fee87f922e63d01377a702022f407844e60f563192d097fc190d4b9423e4e7b237edbe025c47b910c6da28d26c5f25a5025265d2a204a519b833f8e64d2a3a4c0f00c1c39ce69e1d0b89313a4d0a35ddcdf13ffeaf15535473b98771e39baf7e4aa6f927264e6119206d1b024b808af816db984825a1ab0c4ec9df14120dbabdcdf4b0bb4445ac022d4f53f6757cec1a02719b166bc272aa26fd3d5a19f053e13fbd00b5d67ada109d29051cd5ec728a99bc53a016164989493cef0a3fcd26825ad0673bf2fd9a17788433a5a33f5dfa3d26c5afbc72d8154c7ef45b0321decf426bc6f37e7b0e0493ee9e522db3775ec83b6d4c69585fa5023553e5d477f6e1ac2a80b4f0477a0f18b2c4014e7596d55b3e6cc268d4b3f0d265cf823feb97355ad804bb1510c5021956e6865c693615eccaa18c8dfd10fd643ae26d30bd4fd07af6309c8385af2ae91ffade4e050bb2a85681ec5eee4e55168bf626743731018ec69c8ff8574700456dc0c1b55946cfd78d2350072c21be9d3081f24bb64349c2dd8f63fee8440c5a2c18c8332898034b2f6b5c774f71d8a436168330e2a43d1501d35bf7264307009ae8c13c7f98a61e2b6294ebd04b54eb61cd67c868e5a70b247a82c56b5000773850ad4fec37329ce608029bf0091939a6a1b6b9f426f2042c0717b61dae1a416763e0be43ca69a9f855685aa38ca1de9230cc19b7a4defaa050052549512770183df9e2acc5a1723ce3d73b96b32c41adfafe5cee370a1e678fa79ea3722461dfd9aeb45139569f0e6f7a3c3d7f60013fa59ec8b7345fa311351a12d2140d8e6ed91a51176926a8dba35e2c65d4ac7320103427b36f20f3411ba8f04ee614427ff6b94415c230ed5f49545dd15a4e1df3fed50437b81ddfac5cf1165e6116e3e7fec6439f5f56494929c6fa96e7e6a49d999026d174126e0deb9eb11aa01cd1e0dca8ffee2d57bbb6a22e1393f6ebd5392244b30634971e9f38de5aa999134af1bc04a03e028bd552b71f42a2b798e649db9214c69412e408467037b7de1f4fd334f1c9f9c7bf1050182d4cb55bfa65f679a1c01e10cce60b0ba019b0a7211b9f3e4e5cf04297d83eeb51a0d4582534a00decceea4c163271f2696053e8164d2dad9506d5bfcb921ae50e0d91b96b81d4c3a805116e90e9c4f6becf24e42fa10833dbf0f0713f1b46fe67f689ec0b3d6e6ae54838dc2b20549c9fead4f317fa104e25740c58fa1089a411c6fe1140e07cd5e859dc3f4b10cad565cd35c21eb743d7d066b0216ef1222ed15d5d2b19901623f0ed9ade841181ef7384ed412f47fbb67ab1620be7c439652920a57f0e24e0489622a90ba284b0f15d8708f105dd4dbc8cedd61f619f19696f3d65d947ac5a37117e42234a0b1ac09891a97d2045fe954f13a507dc665b6f4dc1af44dca049b48f50601239d54963830057c21fea7fbc790dba2a482930e983d06cf20e52f841048ea23fd9becae3c6c56dea16d3627053072fd2eb637138bb5af7f1574e5ea375e8d147294672d93b1ab92a2e625c96a55982d59f2908793089c5d675fb63e56ccdcd0872735cc0c45351970c34f093e20663390986b19081d84681c360a40344a48044e228a23139c07de62bc0d25c0f844edddb2e17b82340e9d73f228772ee64c59f9746aa416f1405860bc6bfd996c2e61c9bc823024de7bdf863bc5133fd6ab0805c4c88ebbd3fcbb12d0f7308c4c486a20860283e6e2320e198f6a2d085cc8980e26f2e51a550933928e561229bfb72912cc955aabeea11b030d1c17551eccda5bb5f5bff83fbbd5013563d0f8a86a2d65ad84d5c95ce6c5a2b656b3b578b73f21d02ba88fe8a9d712e2afeeb9d7e0eb9c1a541f91ade3049ca1f51897a474235342a9a6f88fb499428e9770a22b2dd768a096dc5616a65630e49d6805da5c884ae7e0312ccf8feec24843bd69da995e08aeebb8e5a4c54b61d70edb1c5e62db5e3ff429ae5cafff81dd26c2cb92f24909acd104662f7d74d54466c57386cb437cda86fdbfa342f3011ac3251f702fb97585a11f54408b29243d4eae98f77a096a0ea94e624d152b8267e3d7dfeac3d7df0e8224a2f2d99102031ad8a74dfd347c88c55de823733b90632ec5a50f12be845c37ae121d1b0d662cf8961ca1227bef498feb4928655861f5672914a9fb0b568580a74142716cd5ebb0ce51c1c8d072f6dd5c981ca3ed106bef9c00c32e0246166d0d789aec5041f57d670fb2f0fbb4aa87335a7ef7a512cd1a8bb26b2d343de10f1b05957a69cb3e99e955b9aec21c4fbf7a4b5453c421bc106f05c610f438528f8e733d48e402f42600c1ae3b74318c41b722dd5cc6925154ed14a9928b5a96e2e4b4efe986e226c755e98e61ea76ec944eb78a3d69201231ee7b8063640dd0cd244ae2e598bded49282ed4d79c0f890c098432a534708246110b4e213240c5bf0026fd920a4bb45e2c574295ba581b644d13d762cfd0d43d638af1e48c7e08246e03fed8b6dc6c09ab358b627fc13faff5add1d19751abbdb7ea60b18e3f2b102fc3d30167795ea71badf50e36e7ae300dbcabd1216048274a5622365a76c5e7a50d353fb8e9a1094f8deb532f930fea082eeb6a4b31c1bb329608eefae298673490756fa62d97ca75d15f4441f1e6018de13991f3816bc02756edccbeaf4300ebffada8d6b6c943cae931a17f6a89a5e2b232117c0075f297211fe6a9cfdd0a4f32127175b900f81e70ef7e79e1d1e51e7afebd95a0c91f87a48820ad1236710841d0f4cad093f3173a2d3060d59d33d2de467f0072a5a51e107eb89a2b8dc2ecd12d77db3ec7513ac16154c2f1ce91861514e615724f19f85a4c2c2b99629eff7eb549565ad3f5217d6ed6b00eb83c75e170215ea04b957bb50d43308a0e5993d64b0341182bf7e615835b8a971f1d37d18630b46287d062a775a49374c26263f01e4062cfdc3b934fd8c22029a3d44d0760c116a242d2751cff8a77d499e4b9ba267e85143e5f1a59195d98cc13ff0a4fb3ad7c90907b712c497a116fc6f365a7f4f4285f7f5926487491a9cbed80268203b5e53074c7c275265fea6cbd5555f42dc8f8f45122a9f1a64120f0ed5f2243f410041026d88d6e4179b61e5d74d705240cd0d43730cf5cd444824aa68219d38dce9192f1023376a1d43ccf70c0b7382b4253eecb6aa387b83120cdfe6d02788ae70b3303be8647e4498ca34cae02c5fff879a7d4106c8ece7153abc8db46c12dcb49a23c6dd66ef69852617850c188eb1e9f6051bf69841624f9b98c909b54559b1e42f85ee41dfc9ad92b00495f0fcad184d54f6b3d5bc239541e0a4a1b13750efd50ea8779427d2fcc35a52cf61a4786f9ed6f69c9c842dbb60436c1c8fe999c51e2ace7522b27e4b3b8caff8e1a4ee75455e869e24333e541db868e616d6bcc60720e529e44071d6f59aabbc1921a7a28a662cf5756a53fa23bf56fec80b6ed6b90a65fc7af3019b9a937f10a38e6e9f505a5560cd594fa6c42b52db56befdb9160be7f0de83d3abcab2d9efddec09d43cb6da76a733ffc61bf9db3281f3bb6c3a27bcb2167b53f38d25f1e1b85e1a55f53dbaa39ed09dd99da47dc62ac3e8676d2179043618a209e0cf54b7c1d85281897b86b7fc4d2a03faf6272d30339c9d2029841ba7c096a9f52c3ffd13d354f06ca15bc394b99de23492f7da1757e3769419ed503135e7736210e1f37ddc3bcfb9b7627354bd38b55f3f3d326f2e8a761a17da2abd212372bfc5fe8f07033d8bda07733512982a3092153286ef6f95e4df1cf934d31d0566f00c1b1f1186bb66a3b3083c285f7c08b21eee1d2733784d442063bd18b682dd4e90921766318cb642e3789a1cc4a6a191643c49a9b5be21fa004f66731f08c82f2d433f0ea3a5ce0d4fa2ebe5ece4545d4bf75eef7387c3622006f028a52b5bdafd3a058c16068a4d331df9ad12888e64e8b52b12a514c0e51dc2c154263d1399b3108002ff047d94c86256d801891f8c3d0cac48d7d5503f2bb7074d74e23b2bc7056963f5897a95d9dc32006c6a259166474287b15063b900bc8f035a99d7cf793ef4d706050388921536d3b3bac47fdff272b1f34f94800f0b6de358640c1f7f50cd197faaea1afa3dd005abe027f5406a1d43b4fa753e1bf29ad3b1ddb946fc5ad5aab9c781f13a9bd7fbb4024fc769271c1617b160b62821f77d6b20c09b826540204521241540181ff1156eba68f62c3807d74fb6b82a26ed573505f10bbe1afabf79d4d85accfdde58bacf25838f0fa93d87c276d72f7af912395093ae881e3be578d3dfde5675a7df316907ef4e349b8e0c493c481c7a29583b0eaa6ef46c964cc64dac3aad7c065a79ba92687ce0a98ee8cdb6361a14fce6daec621048466b4a6bbff5176467f07e6a2b69d5a59ce0127c77c05912d44efb3fa2a2d643dd0631c0c420303970e67d144185aab38122ee4d89a180002c26533406e07c05fbbfbbb148d6212908b6368226ea7c7d5b3e839910389e0099bc3354cb8d84d8a9effe2cd41ef669540fa409d96d787b622cbb530f643b09aab6a03e9b83f0a22202c68286417e48731d44a2eb367308d472ab2d860c8803db08bfa695f3f2930a8c664374b927c41dcc3c9c2fcf71e1c3efb95fd866102947e9746b2cf78aa01b14cb5db1b082a352f58fa64c4506028b405e82ed6ebd0826c6541fa085bc93ac86d87386c2042f07b045d93f017366d6c1d93ebcedd014e278d3835050677c5d46e7378734d23c51e67f1fcaebaf567698e4eda0f70e15dd2e99d51ae126ad71067d10cab934a9f0d0f88b6b004e1e1e1092b7cd460f1a170e7efb388dd92ff079c964f5f0191a51b99ba304b159294220629427c66322d192e3cb8014a8e42c965e9f09703949fda898bf106f70e3200faaae85c86e10f790ade8f2875364d93992679319355f0415beb31b498a59f932bcabf37de62a6e3e2cc8ead181b76d7f2f81c89665e5991486881ed6e85957f55d87c4de2f0bb2af449984fad5b85aa1fc465a345e5c098635d36cd5df525866c9925158c120366487c32261f99551943f7bd9b828fd0f805c91af36923afb9a1035a976cf29d7efe8355bfc2823d0d9d26252bcf99df9af15ffa66a2a57d675b8cf6494e20615cc6f195c46ac770f1fe2cbb8f966071ea08c126a5993126a291ee908a96a2214f44d6e3bab7a1f8cc9a535d86930423ab2be7b7f50ab026ae178a7464df6002c08e6f95f946dec9d918fa7c701979e5e7277efd92c2e0391bbcdfba23e102c2d4162f5812fac7806769430c50cf13d041229d170f339e9fb0765ea57b5a90afcb342c8d26ea08634abbcfae382a9292252b2722c90071257e8b6a3542a7d1b202c88abbb094b7a2f6be1d22ea647347d0f43ab767873da3d12382713ae0b132942d7950c80d15ea5a933684f30593ed3517517987dcf7b800fb8eb8dc64b07bc25686cc77bfc09b2d71f441bcff96a0a7c7bb947c6079080f694243530d600844e32e68804d47077fed9246ee42860b7d03ba6cccb59b539553e212fad1304214624e71fa2f1496d36e6ace06ace6f520af8bc12fa6907234b65d64d3a81300ed8c5074835551bc7cbbef0b6dec93fa8eac69ceb2b6fa787ed2b21cd15851840cbc48395ffe7276e88100c327fbf0d4b7ca7d9e7a4a1f17ad4e214a4fac82a7bab24a3c7a0e15438197bad66ca888729446d342811f1aa9a76c4452531e605e7fe0f6cf94dfd74cc7bec4fdcca0269fe0f2356608838073b1a2bcbb0bd130f19d0156490dc9d40165ca992696c5108931f1a0735fcb95193f56f5af1c4a70125c502bd7355b66681cb150761c244f8f1c12b1700a4aa873545c8d44f1dbd2c27884cbc54e96cd0cb82a908f5cb4f98ca4848fd7d6607c7c376fa5fbaf5b80634c59c38c194fa0c158398b64ef453fa5d1d0eecd13fb4c47d1452ed75bebf1874785457afda78924f0f4f191a26da477702053e6b4ea9a9158aeb8be5cba01eed0bea52ba039d30db1021cf35d604bafe3e53e81d7d7a2f54cdcb1a07a1de113f1b5a613d9e4b57b599353128a4e4fd25b865767590ed535d0f8b64a5ba6f1b2ccd91bb5128694deb43752b489f8ef72aa7850b83c921f56b27dcbcd801d8293d9bd61050e6ac52b47d25c4ba3eb7c3268719971b9c5f6b6285e7de73ab861c8a071a0b61d854c12f15e8bccbdb3948f41330dab8f1e1b46401fe630cd9590cbeedb644bca3ab31753ce8759476832ed9eb828375fa41106cbb8812a4ab3f2d2917d97686724f15012e3aa224edbfa79b5703723b9f1da9d8f298e7a424e717c15f97c6bf2975729f8056bec981a39d6c055d27c0b46166a6ada05e93d96d21e8b83dd54e3cb2488d3e4750dc0cc64a5a3f5ecd99eb8598c57f36b698f19105f585c424c2f0c2a8bdb04498b691ae1c26302705c2fcdbb7ac34181f65900108f4a30fa53778b73db14e6d881314fee1b43d119dc7500b68eff4b24650bb7510e8c3728a3ca4e710c32347395b4b203884db0191c4ee2039e21aed587ec1760ca67d37030c26656ebac257d53dd24515d20dd84a5ef465978759d706139a0c259dd389daef6ffa3c56f3052ba2da2a49996bd9e3ceebb79d7338319a51569811ea7cdd52331d67c99185bcad199e61682a180a6f16c021229de73dee8e9eae0e057f1a75896831b980d2376c6baa22430d90781298cd2c76a3f5a5832360d30c6d8c121ced3ea63e682940893df32891a0f20fe3771ac18e8895421c624da426b14707eea022d5814f3d774ecc970a9b1ff47bae53a335b230c2f29334f279215860b96d5c4e332dc5d521628505256bc95ffcaf7e6af856188f82b31088981c8aa702e18474e5df8f3ecac017929b8ac9a6a8f475ddd59c408014b4c8129001e5d9a9a60c8c13482d0837da1dd4b39c69b31f0d514838b6fae82c89e06c572d35b1b48563839c0992ce91307b4d837ed609baf6afb38d48e7972b8b5b99f91fdeca4c830613e7f9b72bd083efe820181fc523820f15ed63fb0822b9230c570859aab904fd73648275e5373ff1af6f61712b1c54db6d978406694e9b6038650f79671116f91705532e3dc721ae876dfb1bd00480f5eb58caac1171e79fc9652aa650cf76380bb290d6cd3732a2d080cc997d2da545fde1027339d4646c4dec09214ce863c782bd94e0a31b28b4752f7941d3a92401bfa4e37d81c61fe0f75e02162aaa21eb2c66e4dcfa0bef894309aebf66b8962fa9e8afaeafba81a283d0125ca9f4cfef741def31d6098c96fbe5bcb15fdaf3385c768f2f8cfc183ef6662a46f7b706b2bea3d914c8e070012297473589bf3e9669b9b4767073c80f7a7626f3ca968a920ce519da4e4f48f62a480065c015d4865430ca207d6582947f7403bc218272d157440faaa13a39e22f45866cad2e2dfdd09b7f7a79b1b21e0dfc0bc45b781f6950f78d4631281d285180ddc7579f12d53da5254468947f88c64d2404ca4392d6b9483901ca83f488b0eb99c6d9e61855f940e349618bb4cdda120cb9fdabf9a482fe39eabdaa2b4f8698a1085a949dc6ee0fc4da4baeb3270e7a153fc2f4912de3780b345be03f1e15bb753897c2a0c7b00b7e6a618c7b3c20e10439bcc07d2377b5dc924375ced34e7d7cc8ba6a0d1fa6697a457dc6e612bccd0964a3ac2316c29aecd74957ea9bcb5f4a70a655a1999fafbd95380d763c261813f0c6ded6f4acdb425e3047a64f187e195afb7aa9399bd775e29d3578af140b224bc801d54c95d3790079c8393ed98a7bc3e5acad2cbea47887b0163c1544a40966e04884b239de2dac9e8aeed580e5f956f8a8e1fb671e75d34e5fbf0054ad0a974b331ccbb54c8e8585d5eb41a5ce017860bb71135724903392d6b2f0017819c9ff87ff6948eba679e1bc202394505e6d368ee5be6dd25b4439c7f75a96501ee54142e584831644a3e8241064c3eed654b6207aad54cd6d499674b43450d811025dac2d3557cb347773d2bd3295ee079df0f1b3efc2fa0a9d82cd1ed20bde2bd6e34585718101ac22e513c10675f3aa2f9bac70f9f870566b54d8ce8a3efd2b60b63b6b6e16f8dd1c78424aef184ffff1a53ad572390d8edd42e12c6e5e9d01c2c362010c018763f2154e1c0a5a03fa54832572603c918595c280962a7d2c01d9259c30854eae881636f2256369627f6f380217b7aa0801cb8f5d486fff811a30fbd4048a0c81d9560ad1462dc5981aa2d8e1fa9c90f2de629b8503a127900b2fa796825e2c150ac4fd3bd7d195cb67af638e3c488b981e0312ca79e038041e241d9cf8886003759b85cd3c669ae378e8ba9422ffc09858b4f2176bd9d5b722c3f11e8c8f7cb8a3d231024e60f79258315938b9f8ab8974c1f0221e8571e00c98ddbea1a84f571064b2477455777ffd10e902a33dccf434232a62c946e557076ff7bc613e5111167319e1b3d2234b3da40a8b4d49e00b4a5d23d953bf2fce089f706c73c7b0e82c212743ece53b7c96cbd5445865fe705539dc7dd0ef0fb60fc255d83f113467e1d8eb4da93dad481732cbe0d4b4a9769deaa83b6abbfc84149e3502435b22304a721cea21100cad0220b078d0f93800b8032d73e592f88e2e3aeda6320f26cd7c4ef4299193396343c12bdbbd9a87cb52b18f2e08027716008ccf50ef396033799f9fffbe9d32766e7d9d3f4d32e6ea7ccb08cec6f2d97227954aef0752083f3ca2d5dc02994622d1e06dfdc7f043b4e947b6ce3e217b7d27b0d8db69361d9a78937e99143d81fc0990dc4dc46583f3cf73db704c2cca2927400622e6bda6427adaa4183ce35abcc598c5526a69e26a3c6dc4af36eb6c160ab48cc09ca6961d808bec4d6084741b1b2f33534553e7d24f630f0bb640c118062730001bebb4e5702ce2fa779104caaa107e1f1899fec2374a7f27764f7ede21a5e12cdb37b4ca76b6951212562a105f92a315b950d8f434ff416b1b9a1b2422542f057fe7d51597880e645ab1714fc229f68002b3d1e269ceeb32969b353e11ac49ca87ea7f88875de12309ddfe3f6cf4501522e68ecc199db40b4001867c123a1e6a293a691d8151ad766f0130fa0bd970aae5ac366b886257423afdd0761a28cd4a57083ebc02a3dabd01693859a12b9cacda074fbe5ccd2ab834b15d65093c17d5ee31d0c180f8c74b42e91330ff9a9de6c39f23c4e7533fb63f284c63304f216f7c4ae3f54a9c627b8d0c4630fa6bfdd917830ed5d3c0235a6e418692237fdcdeb42e7ed028fd7f95aca773bd7573c654e6856604ee0d9d7fa25f6cc91b0021a21d95c9e2ed43c38e92cc99d0858f791f33c7c4096b4073a50a605af92e9a31efb3fa1054ae2b053573c05cf80189cf9cb1eeaa65561a54f721df77ee2ddf01652c0435eb7597ea08e0664181b3f679113845f0e03ed829431541f05d203def0f84f22abe9fec00c6052b290ecd0db4797466aff18461037e202ee54806e756fbd0e3076fbdfc66fe4193483139f60f235dc8f5cddfe98439288a7753155bd0112d2d9810e489a5d98f38170d50ef95978af50b478fcc04ecc50779f40050c9dd0f00897baf1d4d1b06c9aac43016048cfffa660bab245fdada960e4f041af6a74318a9dfea942ab43a0f96759c9202cfac134071297e13a8d2f85ef508175c4f36719cc2a3a4d21955a3402abaf3320f83fede6a173c7414b5883a8f13d47610689ec9fc2ee58b124fa5bf5a35545d41457c16b009cd2a3eb7e109f71ebc8c881ab00c42acab3415b19b798ebc498b1c3082f4569d01e3de6a0508cf2ba3949cf042821c3acf2cb6db150a88b36f7ba6684d39fbfcda0e807dac34871ae08b9eac0b61e5a37433aced9f98b6561b794309d4baa95ded5888f022a8eb1d9f79b2d8e5956fbf4990d68c906bd82638d806a842a601783e4d4597765a60252c2c6119bd618c2ba6d69d08fd192f4a3fd2c3b4c7f010d53cd6e2a7423ad008ec05208111a54223a5273410057b8981019bf1811b991bcc366049469605b42fd28cd0b86bde221037d2b8fd45cb0c9b27e48386a963a84f61dcc58440ca032597de6c3507f1e648311c5525fd00378d3432955cfdf7eb87fd3832624d912a2696d383a5f0090b5ae652a07570818d0455a505c3655c003e79ed841cd1a02119556b5f142928ab98a491ca0b486300c0e126bf9308797faf4d6d4f096c8fed301fa9aff821908059e36c2a2ff6e783796e33140ff21e46a3e19320a162c0a80b574fa11c5610721789046457a8e122dbbc31f9db8e9d60eea6fdb78fb62e002942999bb7ee575ebf42514a77595e1177199575464f7cc47e535f0d0c564a3a1b2e5e37b1d9f7eb0404df692657f7d4d5aa7ac1418d3bb1c0055afda07e6b1e1b6bc8f49f0e6255250aec766ba36d26c78a34c64c379689c4bc13302fc0a2e90923bf1e1915ed0ca385aba72da2f48566569f21a88069fa4600df845309ef7b137e09f44bc8215c0b31d1191797b2a789fcdc460bdce0b58eef3ec23e7f46ee09257488dd2f164e17a31fed823468e23e7791d0897daf3f937ffe7d05bb55511e1c417c6f2fb6fceea5ebfcd854a23ab5ca8fdc7c04908d8b81e436207dbb1f18da479741bd2883269c262a870a23bfc99ca1a714ddcdb769d695aa747bf726173a91cf40d052149374a8809cb89c2ccc1751c07e2b2bc4e286774bbfe4b1712d38e2106b4546a9af90a3008d709994d0adaee76450273eb6715ccb2ed12824070533ab886efef8291c861e327d1198221667f380dd075a86fcd21d5f7c3ff7032d213496e23fc2845413df185d31f73a6198904c94ddccb0fefa0f250b599b0223370e91052e2b4b71b6133793f6f6c9a5f313efb18f2e88001e561b480c7f128af589420a68ab0dabbf4118cad6fe88586d6759c1395cb199cf6590a1d4fd052eb2aab72f8746d2147262fc3c1a64235a45ae1d171c31a917208adc36b84013fe1e6b33fdad0187aaee03b96a3626e4d5006bb0ffcc91d1d57239ce89461e0570641c01456e1c92e19a0054d9c812de26ed8cefee8f1e29903867aca772a11cabe48a842659044e170f37774282a95dca132c110aacc8354be42019156dd92a790c670bcf81ab066867a237e984e6e51b28f0b9be32323a1b76eef7d25c4d0e2079053cbc8ba35f2b1823b437a526f482d892c240f8e8258eb73f29d77f700fa00cfa645e659a661969d96c5d93a03239997e24f2a3d551f74804e235bbc12117b470959358f27fc14086c9d9494b8f6074e98cf99ba4d98607f8054e01c30dd270176d233a81f079282ac2d90d61e6278c0bc08fbff1914b49e432e0039b2b9d3af036e3554540363571f6cf94384af6a31647e2416da794a816dcca9e930ddff997ba2d5d6ca43b8b27ce0e5ef64097365087bba89d904ed998f250f93f134d50ffec261e5d928b0e7ea27594f54febe371db232923a7dd799d8de591cf005909f50abfb4f11d0af2edb4899ca7bd57cf2ab1b8172af3d1cdb4b32072121ba1274c502ba63577953f92f9dd4f715fa87411d6501435ef42d64c3b9941c11c5104477a3a7c216138f889ebe0cbe7ad8687c9cc998c83a0a5d64cd37b08a80411ea0f65a76c75969c095f9103dc1d950454549f95eb2b4139617dcb0c7d9e21ff3f9786b19ff2456a4c77191118917a82179807d42e4b6a03ea7ccc6ce3462f124adb34301fe90c49423e41e8a0f135b76d6653a107f8f91c9d8a3fe14874283fd2c7d4173367a0a729b8c378f396ee73c3310dd807b80a12c3e1f50e76bc235179e6eade026a5b94aeee06760fe269c187c0ca04cd22f8a6933f617ef55221d07bbd98ac54cd8d7e4b63980dadb35296060af0bab5cc9969a7042cf6c8b0000ddd081697143999fb6c1e12bc4134602fdae6180e5a69a1b54d203a0e086b272e29940a796957ac570af02ccaf8e1cbd94013607d2f7bd4be7c466986d14d15b90f5f649d3da06cf9a2d20d684075971fc6589466ec9560f78f95d63af4500e621998656153ca8ba44402b31b19cf7eb932adafb783547e2e019e152fe3361b7e76c63017866dd5eeee8c7ee7c569a1dee58a78b8c3ccb250600c9aab1cd706a210f1d7c892ccf6b68f6dc42c86f8993a9634952c4c9cc3ee0184a64a28a60afcd2605a76a47a34885bf7cb398e70dfba201aff2221f55345464ec01bb36a2ca81d2a0e0e09280964d5c06671235fb5d3976aa2c31f8bc74c0e3f6f9fba500e7650be7a2791e8f7bc78c1033f6e3e829af8f5664e7703f0b48ad9d3e1de8a15f7812ec86a5d13fd88077241559c19a4cc7c174741c6f091405081a809562b1d7b74b4b4c7fe9d36b5d542c28135a6072ffc5ca0d746fb98588ad7d35df9e618b80609be85aec7266ff9bcca42c3714c9f9f2724fef38f698e63d3139c29a6", - "public_inputs_hex": "0x1d420eaa08a65528f470fd3e2a802913b611527f41fca008a0ad4e97475078032a555ccad424037773cae7569cd26f46467d9bd96c32334af741c911096761830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000022197e95de61c6c2844727c848aa819fe89bff180954ba01135f7e3d285aa3d8e240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f2a318f2fc85748ea90c49625631654288c77791d8dd0792e201c748ca9863ac417b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e2bad40c7a2fc975f2e4811607e4d5fb72361dd1af1bb2364be799270aab5c6f623db21355d312ad82ff6334e39518d7aec226005c56d124daf506a44749cf370" + "proof_hex": "0x00000000000000000000000000000000000000000000000821730b5f6c7306ca00000000000000000000000000000000000000000000000027d5a4288c59517c0000000000000000000000000000000000000000000000061a32d74244b4e4cd0000000000000000000000000000000000000000000000000002752ab748caed000000000000000000000000000000000000000000000005a4f0140d4a1c7f7300000000000000000000000000000000000000000000000512ac80c5fa266d0800000000000000000000000000000000000000000000000d400822869689e0ec0000000000000000000000000000000000000000000000000000a3ecc527c1e200000000000000000000000000000000000000000000000564b7881fe1989f5500000000000000000000000000000000000000000000000674ecde0680d8bf4900000000000000000000000000000000000000000000000584cd67f303aef6c30000000000000000000000000000000000000000000000000000623ff53a7e1000000000000000000000000000000000000000000000000b27d89433be674a5400000000000000000000000000000000000000000000000d03b476bc4cac62c900000000000000000000000000000000000000000000000d562dd63dce28dce600000000000000000000000000000000000000000000000000007014317d4d7c2bdca3a8f64dcf8eb8b35863e69e18fd4f152ed73eba57c25990e80b7c74b79013d6c8d4d7310cd110d6e43bb18fc56336d2e4da3740b50e8523d5f9594bcdd812036507369a09143ca35760ebd0173b2c22e17b4dc2980119e4fbf1ed9cf2a9021fe43ba1b07e24480cdba82eac2af02f2e755eb1b42e866b12ef874db8f56729f0b56939196bb391b63f552db3f3c7ec39a1d778f2686df8f01eacb03019c80d8bbf928d3be121e24970b738be38dd033d077d66095a42d4f1494b44eb7df0074e45e1376a363bcf636637b442460155ece719bb40d1fc476322ceb66ab5261818431b676c3ee34900e20139f2ce04bedc6ee159747b931b42f2b22b3d7198079fe5ff134d61e1d32094cc83972db87162171f68aff7e77845fde2854f3b9a0d21b74b20d8c2ec809d9db9e189051c0dd8557ec1661fa1a1b0ce322590aecc23e610a0c95bf8e2f1ec67fad3b50a0d2e04a267e7844e7e78b710b17602724a2b1fd0daf5aaae67ae6e02faeb646dbe547f0c699e2cb1379f50d28f36ba218a1b615a728d5b46c9da5f17803b7b0ddfaa6af8a8d6d945602cfcfdb1a8c2845e10ef52b08e4afe6f9717aa1865a5df615627ece311d2bfccb7831e0631a7271a08ce5712e16458da4091348c134bbbc0f6c546f14c8d9c231ab7975bccb9e02e0c991572aba8f415ac14e2e466eb01533edbb3a35795beea6327e635c6b103740f2b82ceef34e542ab504d3202e68b230920bc61d94d1cf18cde724d06e23a482b31011ca389f49559a044f8bc99e2eceffadc140cae4937d763106987d7fe30299aea525ef4ba58a7d10fddd62430590152bdd9c1fe3f5dd865bb2ce4e22a65086dd1e3b14c653011e7a3c89c4abaa1ed50be316fd87f42661de510e98dc9bf0dddcf46263bc755e1f5bad01ba6f03708b0bb47ea5aad02d6a9052b1fce2f05226a3e2e74566f10fe938081e85af521d530facec93e917a64abe8a781e246752f984676b56b5a9c17fb37ec862c78c596c128c75422712251c9e25f0fa4352a2a7bf93147adfa3937ec9733a4e035e4a297fbb1e9599d1de9a59b617dc808f117e08e894d7ebdc106e7f065fa3a096cecca51bf047ded0439a19e86d1f4a358099e717b59523313b12586636c72a0028ee88c7cbf053fbe465dc0d546b698cf132800fbde649562ed1d1c65b70ad4ba7497d90bbaa8dab5316435f6473614f501bf945798b6e787cba40d1202870cc74db20387287ff9fffb4cdf7a0160ea04251adcb89e4bed874a70342a96386f8ab23147019c7e3dc8a6f2d0f6ee77ea1b1683337f4dbdcb041c320a5df0f41519161ce81427ee42e7e55b381564cef1ff1036c245bd9b7f0292937e19a58c6f917d8bc00ffb2c098590ffa91e35aa88bf0f29c027c75a7685fecf83028b01891bf2582da15f30dbdadf169772056758b112d80f494136784c5e55d2ffd210cab43b12b3b22efff7fcd159f532727da6ec05f1b98a8978a14a941d2489d0948799285fecc08732988a56e66e352362a6be2cc8b3127ad5279b02a55f57f785b7e1db4de806714cb6cfc421b1af185f408d2beec04fcf9b045a9fe4911bab199445b8cabc822f63eda13db7ea709458a02c27135db9d0e4ba34442524e335b54395b3c5d1d19d856c4a813e0fc2303a45b50eb4e75e5e2bb32813c7346b9c9c1c0ef2b8cccfde4c1c8f4370c89efceb6be328a05d97d39aed2e4cc7d7536b34af28247ede4000fcc7b428147375abfdfb5516e986f5197eb977a865b855e9772fff94c52ffdf99286ee66fc4bd6ff9fa6540e0da9efe06b9e2cb8c70f7bed562275ad9485849152717537abaa41b09aef482b701578723527aa01c63295dddd454473177bfd0415c06d3d4e1848d50a58252bf4553e8afc869321e3d7796ba736c8b389b852bfec26444709e9d423192bd117d4a7cb64bb293e7c7033de3dc675267289c8ba6fcc0ca6ce0b9050e79e4e2d12956851fb28b58225eb8c0ebc9a45158c59a5655fdde45136ce3888dd460ddb15888a69073d825555fcd88eb1a3d7f67a4ebd571c54d2d1274518f65805c2382c12086776a4e11771b7d00b480fb1c5a78c300cd815f8039dc45ea68e61c51e130a50b94972ea631e451d8eb55ce9868d50b4e67952699e020fe4a972b44a36115a8998e760ca80bfb4b64576d97e16bf0d1c9b703a106482cf6872973e94520ce2037c03b5c1cf4892fe2c779650c50d7b88b19a1f6f4be7f5c78fb11783571256a19df3f4b96c9fce648218195e60d1c2e4c662d66ccb18a71bd0a9fb8a8b23c3faf51f7aef24669b70e1a4274abc0f66b911c67f15fd970be027f76d1aab14d557ba7d4f268f95afb5068341ba0900e85cc7d322674c057004d6fa17189123eae8a63d39bfc00d3630a696781bc7ecdc4a6b1d7677ca60c64c32d111d3c10f75c8f14135d4faacb046778787802723936036487091e65721e7feaf94a87d10cac1095e8bd1785f16c5e7f0f5fb9fbfb5faa9918ce2a047c7c0debec9fd5f2c41c01fe8b3062e6fb6e6961c09ab4db1da10ab612f4c5a7328a5209dba00950b62695a4af7c7304b3eacd7d23b4de36c705a55605659d07d7bf79a382923d82ab46fbaff077b68f5b592be6cac56d52f95b7f67123c6ef30cce46bb673b92b0ad6bccfde38ae2deb094a64332f2645f4cde17c0a64aa6cf9b79a7ed828fee42cca7f36d7f6b946dfd1e01db6832cb6f4eab7ea793718651913922d4f360d4b21f257a41c05813fdec7e7d01cd94552d86eae1bced28135690ba7c02f94c4102e5902efa5fcb489bba7b608b977362ed8ef889df360bb12d3f6fa737cc23ea410e2c92ffcb685b442e3884384753e48b3af21056bb1eb92dd975c59aa54ed01161b2d1f8b8e48050ebebc4226dad4c4efd3ccba5c481e80a25e903ed9bdd7992355c18cd5fab093b281f89fbcf4c49a728b3339e0a50b7c8f3eaf38c0a45a241cd2d8c6780c99d0506d6db1d8b009aac9b761cb438e732bebc6c473618f58a526589895742bb0bc9bf2157b0ac83056acd061226b5155c952999f617205e6231dd54dfe603fac9886d0279e7a02a79d39fc16d9590496af4854499544f0d61623b4c14179daa63917368e6315d7c8044998be25f1fff60ff99cebeaf702094322d12ecbd646a3e725894e99bfa905064f065a4bb9ecf069150adf4f6f234c7203c810c6f79c786b859baf6db1ce8395ded182bfce2fd1385b1fae68ce21305026844979fc3f6f15e3f01a641e070dac977d4c4e8251de5b25aeba717b43bcd322a34d4d3c3c7f307f3cbea1f6c4ff7736b1fcbca1b856a1d39a1de2a09e2ff306d5df092ac06ba92c3a7a18fa39a0a90e5b2c1d4d8645f0ffca3717f752afc42eb754439548876e6b43c3a5d94e1bf5abf0e7f9b5a6686050cbba01a352ecc21598da0ad02780190cf24cdcbc430d5aedfc4770abe9c6863cfeef593d95d28b1b050913d0e34830cae0602973282d94fec6205ec8756b4d696623c67d33e55e05d1cce77fdac4c7fdcfaee946a7baed22eb73fb1af5cea27644c13e2e249b6a0fce2f7340ef3aa4e2fa39063e6c8ed748a9d29f33a38f4b50e12d60c03433b81a80e41a565ac3c7013a1e851151847f3bb22ebefd9ff335ff703efe6189df8611dd23fff4444e25494a43eddb53fd61199cd4c1c04def81d6f77187f8f5e3da1a1129ba1faa492ccfa688a8fab7566278f412deabe1f69458de9a4991000314172a67e9eec385ebcc15e24e8cd28e117a2e885e418a5eff75fa6e0af53d4782282f17a9691bb7192b5b670ab7a577b331366962dd0a36346f28b8f56ec241ea0b6552eb0d11d855088e95a118fd271c8a3a1922ea0bfaf0afe9ea5c758e20492391a1721c25d590aeee4199f47b8e5c32ffea485cde82f7392674c9de1aeb3c183f9916e9789575f1b0b461ed9905831051ce8b19952d6c331efbf48b7dbf4614a5b15d0e87af9e76b285fd9ecce3107a983c726ae5d3d6ec6e2baeb34a9e390ee6e7510fc9579db80f9d8ac57e1cc886eaa4d2e4afe8430ff03b6c6f3aec5b2ebfab036e1b2efe026beca2aaeca416a017afbbf80ccbb2e72791f9cdc6f6b505b1dae159a08ee04351f5f2f240edbe45973e734d98f6f4cc9e2b7da8da6a110f7e97eed170300d1f8541ad1e1cb3bf6b3863a4cb490cb5c39e6d4faae2f6ea0082ec6630d36696ea41f90d0d64da3c8ff4facd1cec120e8736509315d426770883f14157bd101f004e3e63407103842843b512eeef44a77743bcefe483286303ab560fa84c14a40002cd93f22ece518b999cb3121c7e1df64eca2069230193028e8d3507fd7d7be0e586300d994405ce6dd9895c747b49f51f20d494c916c808ec85a1e118a4ba5f6448c66d7ebbbe036e81080e7fb9d38cd1ac591d5667dd060cdc04db6517473b7814ad9d757fca4904ebcbc818ca1f22ecf674dcc0c8ec1bb2763dba05f118fcf7500e370108e9004dc46a567294751b7ca51e51229b22220d0d21392e57177d6e2671cf3e954eceaca2cf87918287bfc1f6bf533708943011f277db9e4f9d9ce32ae3f3a1a3343d87d3f95b52d768e4848a92aff7dfed1aead60fddbfb11590d84445c4e75305bb2313c20df2f95eab7e64eb085ee372282e3acefad52cb23bf8855d760a5ded264e7cf806f650248c6db9c54b48e80709642a094184762433ca772b01c277a6fbf700c2046fac1e7c45852dc4c127ec0307dde473f72467a910331f49b44d665488a4c88895342608a78ef07cead2c305ad0fb767e03b49b8e665584ecbb8651dcafc1b5c116b33ba927fa8d15b98f5214a6f4c52b2e56646a8d9cefa2258846c3de653e2297a4051385c199d278a5926a6a8f3f0356900b0f226530e88bb4714c63d444b3dd57e11227770c75d1d2f225236f50e50cf07d29626531dcab3db32b7c1a3af3e43febe274500247334660014e70f3347b1f65c35c55630d4db54848774e2c140eb7c7dcba10652028cc818c7a328564594c77c3ca4d6cf9b0ce46a65cd4cf70a6820eabf65f863291f0f0c89ae9929974dae20ebeb9d518dd20b2795765cf0b0addfc027806a744965d41d9fe3385a89d328e2f8a5dd616160cda986b7d7ab9ec9543d99fd0f70ca38771d00e76228c39527af15a012f227bff39d231a2682a9bd9c4b45ca1fc2b260aa250577f8fa880edd4a07dd8115511301135921bbc68b53bd2375c7635fd9dee70dfc0e14e099d417eb4d6035da9ff7a9f647f84df2437aa344deb5737717058d0fff3c23d38e8d2548ee3ca6dfb23b0c4dfd22cc50c86134291cda45e0131e1917765092935098bb1a016aad380ecf5edc52dd0f95e566d538900955bcacc4342d16f512ab3e6aac573cb9a03082605ae8a4850e455b5d1641c03a37b0cf6ff90215793fd21ee0fc330133beaa6de3b5d59c40755ce8d0cd2c434b9a228fb79815ac089a2735a487f497d5758fa303de789f3ae7a09298147bea45a9c69ce19e2d058fefcd8ca169e2ba7760c96e7af51de2a28cde2d2174ad0a910dbb954f6e2fab7246831353872aec29ee4df899bca2eb5001464c97b1cce8c138fcc94ec40c8e76d15d58b5353e6b3f9ffc5b871ea1d2cc1fc1ab411671eb7d4f80c28b051dc71f34aaceee78f29a56e4529ca51c856472af3c41d587c25a3bb5ddd190062840ac3eb0fe54d3b1f28f63b89977405cd88ca9c73df613c7aaadc6965661c70747b5fc78ce643b6811e78b86b7f68736e2b356a934001d2ea264a89cfbe99a12dc049b6f9ec05d04083fd34b5647bd585f1be04af90aec97ea1e1ee9d42b841d7f31c6fd3853b6c12510c173a710adacac5b23fee0d5586900c83d9711955a1d5d41d21d27fee28b4989409d645d05feda97d3b12b1bcf31e156c75bed1d3d299392602de76f62b9103cce850a2b5a875ef961bd2f58321bb605928c80a122147f4095ff4fc0c4772cc9eb0052f677550724a61d0bf0d328fc6116e13e20ba1a7ab9f9f8506aaf4d953b7c13ada2220f7f6f4695fffeb8a712b5cac9f185ad15a710203071669acc41cfcb817ac9aa6d2ed7c763d9de8b8c7ac7374b0896db120a5f2e718e228bd07965ea30f302417d9f9ab3e01991d4090fd2b0920194ab038128867db1f90f4a79b4586f7602b80324cbacb580b34263c724430b9b91632d8d497956dc8231e14a4d8a202676f3b8a272bb1e26122f025c4f8f78d5c72c21b998aebd00ed34be2d76e4a43006fe81588d6b23eb5bf4c3367285c9a9ef2927a7877682d3af2d5e33c05808479f4521b3a17168e6c97bdbddb7770f93d2f01b08b7b99d331e78b71e84cb19252fb9f9f1ac65e844728db5722e55ab95b9f41edcecb4f31deb949896cd3db5cd0dc2ef15e4ba0eadb9bbe2657b321e467ae20c88064c8c15e19067e28939f8ee13304d7283a98fb49625609483ae02f2a30d160db7d5914120348062db5917327da32d027a758811aa7fd1c21b6a1dd8c75e09d22df3f7027626e95fcb651e8b7559471fcb5ffb9162d550aa82338c51cb0f02c653bb8a2b59c2959f293a4973748870484c05d4ff511fa666604692f73cbe282d4e0e243d6d9ba21e950ac205857f6d41ba6073034f315ef27929d5dba83205f192e83a1e5003de8d1c38c6dcfa2593bba4898090ff610b0890515f9bd44d06d0e8c2d93df6d36626472b3ceba0994cc76cafb660d6a692e7bf0559db1ed02fc0cb1865d7d25f89fb247bfa0e1a3fdae33f97abf5ae7d9e35033050445f73244d228055862735caebee5db8a119a9d8d11a7035555ada83e299f3387abf5f0000dea04c2732cab2470e3e04688d9f1dedd763e036634d28ba9f8e2c5240ca271898be20fb585b49b60139770919a34305e52be70f0d50192770fc02517f652e1e7ce1906dc26a8fbde6939f69b2c0645b8cb4a3954ad2b43918305a27046603a85deac0c770c7e523137f35e3000a0bf96b8c329525f65957437b757c262a2bc6a9c8527c1359d8e598afc781fc2e7ed7501a730554c58d2a552329f99d5c2635fd5fa08d5535ca03c6ea08662a9c52fbc5959b1a998374ed3f624bab2b5b2c33c8f5aeb856586abd239d13286104a2e90e79983c92ed579bfd5576668f7214523b4f53f4bee84986ad86798ec100d603f863f155fdfd2fd2cd72f5676a852c49103b1c0c67f55c4af21fafed6d1d9ed79f863c9807eb055b1777945f8d4f1e0db4f8234739e50bb75bc8fde5af7ab0688ff97d67209fce8a9b39e7b4d05d25548e0d72bccaffb3b604d3b33ce22039ed319792b1fa674d396a6c9786dcac294231be2234a234be2524f2f7dae91c55e58074b0503b24530a0c6e6297f19b0e695dacbd609ce9ca7cc5b2511ba837f4eca002f7102967d35389efb30000cb181f2a3daffd5d7f9915bf8dd1de5d4e7659638e9584d13714469a9ba5d37d7313784f05375e9c5e34ef8219292be23da93ad73869d0bc71516e4393f5a782062975871276d39f2f41d36b81ebbc221648befd2dd8b9ae5610fabeaf54f1947f17dbe4490a05d99f3ac74e0d537673afb9d993294d2aed3e7e293ea0d280ceb019e6f0704f9b34dd1a8da3dc616c365e09b09075d2fef5b1ede4a3bba6df095b1390ce5a31053ffdb83cb05b9209d37592156cb464012744e90748e708378d9c04416b2fd032528cc00e516f1fa6bb6bead7b0d0a69d97e0a14e3b40ada5065b101efc0f1f4cd612b723e18127513fa2b82d5f5cdeea70c60581191b3c7cd81f1cf121cc958060e951b4e6c76f2d557bdddd63f9f51676352d04e0174aa85a900b4a92fc1ddfd06e8006f1d78401e5f7390ace2e425bed97aec36ff7e00d2f6525871edfb56c38063860c618feb09c8748f76f88ea04b6ed77e5421025254d1b2ed05884ee40dd3e9536f678676913dc230188ced021bcb986b6b18b475fe0ff25ca62e1660243f9d9b164881c2398ee00b789bc8c4444d3682420cb869165b30e224323381cb5cc73620a7a96119458441256a6229f2bd621cb86ecc29165db17aeae0846231e6b67942cec4406b326de3bf6da88d906298be18f50763420171db37eb6250875d716390e1399175ee4eec8b0bd26efb179532d87783746b5521a5304ec07e9daa765361558c3187a2073c503c3981ea7992d9c60bcf15ed2832f492d65ba407662a090ab3ef91cfcdf450a588b143f4cbf6fa16010ea41310c305c41056c1e5d407b1eeff592b7fd4f7321aa7e2be12587c37faba2dae3b5050e6c1530a67f22db6c8febe5f34295ef550fc8bbc338a40623dc6065c708338604f699048cd976fdb44878c7b1059cd85f4b91b964b8df3bf9c70f3c2befd9322551cd9f2b50fe2d058916efe06f883fde51721cc8523939a3350133f533f1810524dd023854b3ae2592e3c34de948a860ca68eab2e7515f901ba4ef130450802767ddf18f04412c57ea96eb43689d7148daf50f18621a2a2f4aa76ff98011bb12d62e69c1c4d4a8baae33a8117b84857e317f8562da97c5769136574dccc90706388d13056cff5c7444a3beacfb4110d60cb4a41e70cfcc8de69c72a693c3c22cc4374fcd2cdef089cdfe6a0c2a0e8f8acf27d8e36b650e13a8d51308a25a6829c36bb3cf8ad207df79717b3a3fc45a0dd3b5db984b8293dbaf91f785fe0fcc0c2b38ec1232d147cc42ac3808a34322fbb5f8306303cffb36614394275526e41f473251fd02c680ab57b99de93a2ef421ab91e4426b4c99f3c6d03504de269b275d2cf9faa91d300dc7bbdb3dda6da71347133816be7b051d48a33903efbf4407f90419f1332cc03e9fd8c41e24a26c8f42481b2e9fed3327ce1798263434e51fb358e785403ba67331bfb0f3133ead7225bd117acbf86d18a8703e1d3ebaef2281f87c90eee0cdd19c503c9e39020cf0a6f0793d93dfc23d0167592855aa6516320c766eb5089fe5089ff9c2a5f43622cca3fa745cf3e61a9ace7b7e1c1efe1bdee1c9bf8561b342a2cacb2584c6ae87cbc23ca7f21561483dc48e65ed74d70e36d273946c8af8fbfac07b8067c7537725fb15dd74d6fd8e06d9560d04fe9e0bb9cc66a552723894d500bcc67d9dbbbb2f7def521d214cde49257da5ebba58127ac3ddcf681962da25f22c4452c92bb8643d2d51cd72af07b36ec40933aded2a7ca13c7f42fad892ec2a215c0b050a497585d5acbef59321362e9ebc54f7d7299414c10a9a83fc9beb917a3272cbfffa4e7da3fe84a0f10dabec1f7e5a897e0962a0e842037b4604c054cd61aac3a07fc1c81f3a72e51e2ec990d4db00b9eb14f32933b1cbd476385d2d315eb05da63cf9aa7392e86f8789f1eecdc9aae8fc14541b5d0cf84ceb4c04ef83b692a470b986b75ae8fbd52ed926f7c50a3f0a5c0025385e05933854303b5fdd3eb968d912173130bf0b081ba8ac3f93cdefc9a8143fa61d6377db816b1367c023307d2fab251d5ca6e846a272a4577a7fc82d0901acf57ea102113af63c159c1f5d0d91078ffe6f22541bdec846436cb3729c8126556cf495ef535047d5bdf6cdb5aff1c08ace3e8ba81eecaaee4bf99b80bf98026d93bd1b87cf7eb21a4085647627e2b0b2504884d459721c7b979153b14d161ecf00bf75bf12b4c944c0096897bc8c53526c746135500931ec160fb77114a317c0ab237646eff1345dd26ad855f8d7f7228ad671ffa4793f582b208bcd2dbb018fafa828663cf93e8ebac379ed326fcd502f1b27bffe1912716dec34b4189d2949271b39f8384eaaa45e64fcc800b5f805dcfe8e9986c26d7541bf962d1166044483913e751c75bae08db36edb57973712fba0c80d6813f1e051c2af60ef6e117a84999eb5ede01635927eed50f201635f19e297f45c406e75470fbfe8a40f0db953affc8f61b592b5b0bbf515eede750bc8a0593edcaf5959a5445a1ae0c1130526a514a02445e3a6978f1849f50a7c23db9340d42577892f4d385814e49b151466ff20534e74439acf791d130b0f765f9c9b2ab66fda9098c7771834d71e0ddad7d678af5183635414a7ee104cf52afc1dd2ce8fdff5ba21534f4d73667501ddc7df289a79ef1a336f930cdbe947883fab991b26adf61eb7837d582b8e9d15ec335ab0809126826fb09abb2da87e9aedca01dcf1a662b74cc555fab8b65c013fbe0dff90977f2a74360eb7fb0e75c59408389757e17ad071d76c112ffbc4014b0ca129f864a2489339ed260cf0796380943a2618f3b13e66649fb04104ff15197fafa3b047eff947a782bea063ee95bc5b8cddbc7db60661db0e6a47be4619fe21e5918752a3f48836a6630ac27392a10fe2b6a6b292903709ee2f82c75e0d667d9b51d5ce9ff23fd6c7f2c5a87f087748824f9bb170c33a51a704be5f042a94345fd5fa26e80dcc485aa26fa6c6061d6cafe422caf1eac52f8405a6c0aa2bff08666e2efbca4f1baed7f5532cb579708baeb3555ae6b984fab00610901e1ba452a848424b71e55829122932331f5306b62a5beb24c70237eb9c0e0207591d783524c1a28c1fe61f050b6bc6c300011f151959e387c0125b787cdbd2c7241f837fb79f84889b30cc8e5e84cb49a895585e78ca301052c5df2a4fc873db770367667202002946d7dfbf953f113a006ad4837ea696baa9272c58c9af1d6d8e1f0f21da94147cbaf178fb414d0a77e22c33c3fda3d0be7ebcfb9d95daed750008c9a1d8ddc601df5867b8277024e8c2f447a739164cc63ea44c03ad55282f181cf08f3933494d3938e6937267d1f54289a4e1f19d16abd449ee8372fce0834b212bfd7c33276b09f5ad9221383f3bea85ff25427d5deb17e7a510d4104e32aa160ae05861837210115dca42c986c81002ca19b8d3645d1b473134a160d34ee3261287fd51ed3dd9518c3ca8a42d99bc095a056a3a51411fe822eed25ac7b9392e319e63cfbdfa8c25b357407e9f6e2e249f9a75b5fc17b8940b10c7a8bdc0c80ce7c78c5a7da26bef638318da682b033778c232ce708d33e025782dd268861c06d6ea5cd80d15066128b7b0b5d5b6f51f240ea176d0580ef7b02eee47a5cce712042e07964c9c052cedc831ad39cb143a888041c8aeca71ddda00e103d609160b7ed571aa0f7dc432de1024a9572b2f46029fe8563ff2fe6046cfbc4589099a139ce636ae588318153e65aeb57232762e7be53e82ec3c6f46ee4f923625378f183f5c778c1d9420a1523b518c7b970ba291de12f4ee0d3abc0daa36f7faf05901731bb21c7b0c1e3fa46a76e005632f8eba62e811233000cd2539f44b06619c0391e67d0b33b06bdfc98775458a4293c9515b87e5c25f6cb6d29918837096890ed9428f0cbbdcb8eb0edc385318bb3e61aebb5774cb91852ccceceae70c38cc2056a75e1d63ae67c774a818ad111bf39acba607cbe4864fe74d45aaee92912e237f27cb4f8d40f7029eca2bae4caef946b9549348e37161a6e56168328e03490e955c18c7bf6cb2ed0f8a4c94bc635ba90724e62b29de6d7fcb2249d3951b32012abdacd304147bf0b87a684c56a84e4654a1fdb1c2109d4210f7e9031f3ff9280148dad4fe9dac49cc6815a9d2910e9676cb332990e6564537f5a787e126bb154cfff073cfacd39e74a57c4d0d382155eea6093b96ee0e0bc1d204f58742131e755596903ab9eeb3e947677bf81b62c73f504acb1adc7e4dee30c034ab75790ebae3861e8c094437ac0d5cfefa3b3b0dd75c18b443e46060bb69f122660a7f0d8147ccd093f2aa6b1ad705f3791229891faa6f27122529f42e149eae990fde118d8dd0656f0fa9f5267beb6ccc40fdbbcbf34de723c173979387831ba95cc811e1c79446cb200b31e31f3200a287f582be616f920f3b24590529f1abea7c180a6ce5ab8515f5498960440ddf5000079fa233245d1df8fd688ade85739eda4906703d70e7215b65746facfcfe1aa1ab8c7c817b137661d535ba08aa63aaf44f2b87690dc15322b2c5cb26d729a557bf30748c7dc60c36a9610c9e758330ee4e1efec3393675cfce7c64da0c1fda8ecd235b8c76e3681cff99daf8473c686d1f0bf6aabadc7acc20b88f11869b498b3d839f679d443073ce6ef84512ebed8821286504bf8db57ddaa7f07b0ef748604de3498c5a8be6c3b5b8121515bb8306782ca30bf541db60bd1eaa09ed005970e3c80a2c7c143f6504d10b208ca352b8880e915045e50f5ae5d45f7401b0f70076e20ca6635e89bd950b832ff0aaf0236e206fc268a7f893c058c73030c70f4c7deb51ed388a3bee3aa16534d5319836be14f0addc9788e212172376c5f8cfae54ee2cd8792ae628061ce47cc1a22869761305fc7a5369bbe86b6aacfeb72427f397e40e8b901f5b3e292d7d29160a11bb05979b806f46ca206ada7f1ac05c54c4f49cfadcc39cba3e49e3ccc263ff77c319ceb2c976e8f0ed37f6a73c371cfd76d1b82af0a1e58a6f8e6c0068076db9c229f59e929d9547d2de2db72aa9b89fd37dc41561ab1809614d396d06eb5689f00b058cb17c2b3cf46fc636066b4632a5023dc55731dcc76db3dc1a0a0ec84c900a469a7d17720805a3c2bc7ff493a2df926d49a394a7a0c45c7620f051b2ef14160d19492657bb67d1bef596d29b79d29a4babaa5428795879ef66d3aa7dfd7807592edaf9d568afc173e452e112179d987725eeb41f1182a9f2bf32db42b63b1898abae8d596b33efe7b6607af0079dac5d356bd7cf13d10d0a4e0768f2114c25ce2889ce6c34db05ff06fbfa4b955b018546e27cd0bbfb2bc0cffa0792cb5823bab8a977dfd68e70f068ad03ee38aae0e7d49a8957c3878d643e6d0f65fcec272c725699c16e846c8638f5cec0fa2d981165b3bcaa7602938f4a2149ed71e10cc23a9c5e7d0a3f5461709b23cca9f4eef68bfd06a6fd5e505e756ab4c40a8e2859e0f20337582b5f4556a47c503934f1b8ce4ba7b27a31560d3809029ea2d2067381928499d6943b040cef2cfc40f7025ab51d66d46db1eaf2dba55ffb9d472f04933ae5c2edea96a0468675bdd6c86d3446009068ea089303a1b9d053a8841d98c5b5a491cc1f8e8e260a3655fd3a6b3dbc20beb8e874272a67260b49afb0213e712579743fb62f8ac169ab6500175cc164c2a5caccaa675159759f708016141c4e101152c0e8e55842f9bad78fa3d8c4ed129f91d6450d6c06e85338347f0f6a91a32ba22a390cff1ceb374f5e2b6745e8905f0866029a4c2f9ea7299cf31ea5b0b47ee4d6329b1ba0f1ed46fb0be938a45a2db24560edd0dafb2f1d5526073075b6b2bb62555d44907340a599754fb868566a768b458d6f6b038866a2512c37b7d743fe40490af6e2267fa03f03e2a8f9b6d95650221eaf0b4c87ccf6d505125e1dcd88c3be809632f750178fb8b6bae40b12c686a256feeb481b20ec7a2024b45fd5c00f5608c9cca96508b2425fa584455c1c79dea9c947c13e54f2bd0b77f70ae6e1aadb54cd3af5dcbd773c96a36c60a6e94d41f051284397b36e4102431a5c1227d7a2e5eb432dcc11f0fd5884c17eecfe66a1ce2a22b0419b751d117401dabda490ef21888c13c136e09941774ff0b070e9b24e762ea7ff7684822e8d26105cc2ca0b833708f06574954f6b582e8053824a60dbf179e50db6f55c069244550b03c11e5cd22653891fe5064198a330115698a1d852f57c32eb855423c9db7c5aa271f155577ae09f6e5a7e32c2aff1f5150feba43b795cc2584c07001cb655353eec53d999060ef4380640747f65e57196198444330db72f8081f5202a4f8e4f598610629f96fdfd5734ff55a7f4031c8538f9fe80d1dfb973e8d61beb98f1f854d9783b319368ae6f9a015484bbad829d30cca00981f840ec563a2e24c11cfd9977d1f787fb0a395ba4b1acfdbf6f2bafee57074e5328affeb76204ba93ee5b82ed1dded622a843db90a4d19c0b4ef46867161b3f6525493b3a3e285408073fd97e2f53fdb86c06e9845e8d410462857a2b9243b348ad17b662cf06686483db4b559d400f33726b232420a522d3a4a63376d60b56f5ee7cac6688203272656b35c2a109ed301e8a298fb397d7b66d22b4867b9806269b28a5c16d2c366e20f6c78ecef995bf41e82d6fc7cc578e293bd917b60d9bd6d1dedd21bd12b872b9d3e443055b534b753d81d39377c29f810995cf6238b69779a358fb6208eadcd48848b22b262ad65f2682172834b865f293d2fc5cc95538f242b21cd12261023dcc253992cbc1c548d996c675b14dac9b530fcc0bf78fb90bad6027e52502201fd2f781fa9dcf4da5c91b6706f2eda965b330521737df12d13d350c2506a779924f2bfd8c634cd73c84811da8534e0b14ee42996d6ed01f879d4d858605adbb356eec9115a7e0a689e0de4c27be333631fcfa9fec8d02744e206dde6110f97142186a44a6f4f220b1295b4e1b0385b0826984a145ac28bcf89a9c3627084ef803b0cae77c7eb29fe2d6ff15e3762928f2f1100f4a8b59adeb81a445e70c54d7b8453eb39ec2e05e612d1c0884eab9b6d8792606e5ae8627d0f4d44beb2d4306f31b6cdc617da0f5374ae79900cd9b9f693debb14d59889d5b802fb8471c0a414faa8abb86d379cf24a883de065656be4205dd39718b1dab3ef93ba2e5107d2c79ae5b564bdaf2971a6ea04febbcf5e2c7b3e3743d8b37631ed2ebfc2a116cc9f8b27037cb4d7bd4078692ed74caa2a1ae3458d1eaef27cf48870bd95a", + "public_inputs_hex": "0x1d420eaa08a65528f470fd3e2a802913b611527f41fca008a0ad4e97475078032a555ccad424037773cae7569cd26f46467d9bd96c32334af741c91109676183000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008f26088c208eab68279f6f45f234d271000000000000000000000000000000008ec0f15e98d9058c0e708be73acd2b9d2197e95de61c6c2844727c848aa819fe89bff180954ba01135f7e3d285aa3d8e240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f2a318f2fc85748ea90c49625631654288c77791d8dd0792e201c748ca9863ac417b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e2bad40c7a2fc975f2e4811607e4d5fb72361dd1af1bb2364be799270aab5c6f623db21355d312ad82ff6334e39518d7aec226005c56d124daf506a44749cf370" }, "decryption_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000d6343409c0afb816a000000000000000000000000000000000000000000000000e0e3142188542d9d000000000000000000000000000000000000000000000004bdda217c121af9d500000000000000000000000000000000000000000000000000014a5db1afe856000000000000000000000000000000000000000000000000ee178f82f74d1cab000000000000000000000000000000000000000000000002e8d0a46d30478dfe00000000000000000000000000000000000000000000000207560c01e3450dbc00000000000000000000000000000000000000000000000000022788c7db5ddc0000000000000000000000000000000000000000000000099ba154d1691f0c0c0000000000000000000000000000000000000000000000077a57fa84b59575440000000000000000000000000000000000000000000000052b18c02725e6860800000000000000000000000000000000000000000000000000017e9657c0fc1c000000000000000000000000000000000000000000000002b224b4548754d742000000000000000000000000000000000000000000000009134fbdf2459e11e8000000000000000000000000000000000000000000000007ae759187042674660000000000000000000000000000000000000000000000000001b7072ac05fcc10fd82a9f5e13726dda894346515567a79c225b241a718f1b252ee23cfcb8dfc134749cb199d7dfa121b0233c0bca54919eea35871367be619fab7d4acde565f21f7d05e4d6075633ee1781849710d0cc9f901e277b8147885e33549518fe8c9235394cb328d148824ef86c283f67c33bd9d74125ce290de790d17252755f12a2c575b654f3c0128b45fc00733497bedb1ab89208d38b1062fbdcd9874d1a1102203a3af11c6d2beeefa926f37841cf1766ee9c1fd8fb937fd7ca88bcf091a3b0d693f463de1bc4d89d66c527f61a537f8c5e09d43384776febd12c1a0b160192419f01ad42306732827a9e2b737e59e99429dafabbc4b63fd1eac9ac2d8f50324e028c3bfc9cb7efabedc43d2c85fd8454cb2ac6edb769ec5aaa71a6813ed252ea7767466292e673a4791482b20189da899063637b2fb233fe7413ebe14ab48172ebbec7b1577ece1ca982dfe9bc31189268e16381b3452830ad955c85334f723b7cd29f8459a2bdce9108984d2445710388a4ec18f02e22446ef9281b115a80a16fb591cb108f0398b7bdd4b096354d07245988cde80562a2e3997dc8d77ac05bada7a25ab6675abb5c42348a44a313a519ade461c43aa3993e73cfc06472e252e3d75992b831f25d123331077a32c38e1377c7e7e41f360cc4f9cb84e70fc047c37bac2870a10065df9c6c9405302c93374fecd0753fc9874bb9889e7e2d8056c734dfc773c2d255b48cb1ba153afd8e628b1a7fcb0ca36233ed95a92e6960811d86a8a694956d28b0187c66038d4aaccb51e0a164bd42d83fc40fb48b8a61af5e281d9149910f3494c80f943107661e722113d7b9a6c0c1deab0beae72c60ec45189b66a1679eca9165ebc7a629d2e71e0a594277d0fbbb1379fa345c9a61c5b614ff22f7abbde64cb1c7c49431e04559ba35828a18bfdba63c1169090a409a9f16759479cadbd816a6eb1116a9a4d0c3ad1b5f36f304a97c7e87643778f0c38118f46b63bbd48cf9b4e18bd76663b71ad6b8312ad607a4664b2f47259ed009c81da4d44d2d89b736a3ca86649ec926b8d9f5ce807ea302b1ecbc0349ba0010534881c9a4b14b496d7dd5146e97bff9978f74eb7cd73dfdde685be41267606e74867136658c65220b3f1515fad8fc3d291f636b9ba4a03f4e288464e246a17c606205cb08af4feda633d7e7358b8a8c1e3a9bb7cc3e0089717bdc29914ea0b923cfac7c47dc0b8d04a4ee9071fc9317c266eec4ccab59ffae46a9cee283d05e0a63d50303298db10d4af510792f740a8bbd35be7057bf1cee727e79394c22a8e2545755f8a0599a1e150671f54850bfbd1743210499c84c3b77b4d1f66431069cb273078a2e10f1f015ccc54118eae036e1947b49f63342d2e5cc69ac3db0e6346f2648d7fec2da28cbec5afb3314ceda07cc2c3ef10078c086658fdb63229c49d8545542435bd4d3b1696c001df587e38707a12cf521214825cac7af47d227e93ed63f59ed33ce031cd61931a57bf28f14f457a815be7267cc3c210ed870dcb1324eecc54a3357207d5d9d2c42815d5e7b2a65b4c9d5f1e208a9ed0a6b4235e122935a8843159470d69ebec0a3383369dee35693d475148f18247247c071a06a44e4197aa7a02bc80ff31e3209552172b66163935d82fd56dc4a6a730ff173fc70ce51c6c9dd197840a1e873489010c6750c0f7c05ba0de148c871f50570359ebea3159661fd9333c2db2b4f5041249f8dd96ad6ecd2623078086bdb0e51b67b47a31148be3689e5bc49025c1182f1ea881ed3c65e72c2944f0928668171ec2d7741c74f5047a6b13a71eb54058979c872ce634aa6b5dc6e060dcc85d1002cd3cbd4ab0b1076ff2360427b4157bf24c8d965d6c836962a84ec8315cc713080b314982a7345e5a38ed87768e95095ab5b39c8736cef5710baa273277ac2e17f55debdc276dc29eb726c7a938b352124bbfb0a07c26605f144d404bbd2bdf149594defc22c1a6717c5147d2f36dd017d5524107ce84c6e97b7a143e29d52f25022de025b573b9eb662e6c3d09660e4d0b423a16661e9cf66f44eaf21945692150a6292c541bb691e59f8ff4fb579f797bc5d89b3138d8a7aeccedb49729c724beb14ae3f33d99876f08496a48a22de7c436ec88364ba02e10bf3c52236ea913e8426d7cc3e2d38c861f8981014f91432d53089ac70e114b86d4a60d150e51107bdebe9f1e40b98059a4313e5bff2e5b3200c6ca3a0545a8f115bde4fb7d7107b2010c1aa5c9d5ae36db4f703cce98712fac6a633da3874a71943809c40cd7260a628aede79ffe3799bbe5d49288b947d1d067f4ba336f26bd7862510ffb4328331991a2f89b9f53a3620b32bc7bb50f76eb9cde2cb2f9cf42c4a22df0c0e20331793e2f642f142bae542cb7e2f0fd200db0b710d3fd3c0f4d37afa38b8d501fc34640655f2776937aefd2c0c15fa5dc91fa5de878ed805b700436d8ea62ec2061cc0c19517812cd43acb92e01018dd857565ff19d40bb8f09a5f2753b26900f1ee465a4bded176bdb8c4cd3589184c8c80c0b95cfa3484ae2655c46508c4b1e06aa30e32f43f454846e4dfea668903fed3bf23762dabf7b4d7fdc33590fa3010b8aa4bdf244b628b32e4468ad96056a848209a65f1c42dca8318754332aa109bbfe7a82cd199fc831c48b5439c09209b31247b258bb665d2190407ba46dad014ed3c854628e09e8ba9da2c4e2b1e658a6b56fc772a101531810ba1efd61040ede249e8bbacc5b7f064e3a0a89f98d64bccfa1d47c52bafc19f615c4df0fcd059b763205544ba63668706829151458142db92203b996a171fdbd9dc8016f54105b72228df5503f7a4484b4e99320c03d7d8d384e83ad9cf5b9ab322a9f81582f48298a3a781a02a0fb4e6a7b116dc94f11cd919b909ae8fef369dd4a7498252a0c3cbf87c8e91ac7e56d9bcf6ddfec337df1e6f2caff2fd04489a0e15f51c00c8bab2bf1e204b2516dde8c6212fbc5d519398e1d7ffb0d3ced8ccad27638a0183755e45c97ed7e8496714a425b0683362ef4cefaa0acb128464c50054393010a3916f001a49abadfaa9c44052829ab1373491eb5afc19c448cc2ec2384cff003b6ef542acbc10237a0355395a4828bf9c356e66a92f998a9860477393e2ecc09d9a7501d79a694699ccd39b0fc5f7518b6ef187bea3938e24ac1e649107ae7134b4819e221010ff3ea8ca2aae7cfd8c913d727339e5e90d8bf9af431f2767f229d00d4bc9a9ab2708b1a268395b66e88603b50f8ec614b1ee8f042247191be099258078233ddbe8699093187d4b87238b8503be1b3a992a66efeb3c15bf46e114045770bc9dea0af8d1b3b9e7f89ad0f0f7b5cb58347f9bc31a1f5b749125503095d5ea015e6af870476964d02d0836687d9e205ff986efa3fa05eaf42567813be91e7d92751fe7dddce9055502b2beab3e4e3b9987491834fe202b41a16142628026d775db7141e97e2d4144abfd41e23c68dac14669bde63aafd40d4a8002c28aa160a0b5b1f57bcf17e056e62e9a6a792e75c194faecf8edf72ab65904b061cfd14a239bc808454c33b080a44af18784da9335cf5d3de85828c5b2a91d113bf19bc7ab5f87b921f7b88712ef3895fbee836d87dd311efc22d394dcb758321c9d1a26147d519764b79da0bc929d245fed23e95e58281d43dc93a611641ad104e9bb58a706ac4f9212e22869a7d7d816c3afc5f2b9275babbc2353dc59c332db15dde7753b62322c8bcf8d41b72e3bbe6ff0a2c61eb466e5512bf1a8be499301fe18941e16b2122f0fc390e191cf3a4532c849b39956f3e318c907163810611034a1a296a7bbe66780ca88c6f599ca09c82d83d70e1bfa4473776b5c068221194dc907822535370338f889825f36a24db7a3b42168201e5e80264e41e7569162cb3669ee45cf5c0810dda88651c91cc32fb2aae51c18f55174129409892050248d04cd731434d63434389f80310114dc92993c9b39e42550954633cf31d241754f6dc46a21f7be676f914feecb63bcfa9d839638e8fd140acbbe7e494540a1da5b4f31a302ecde922b1a10aff437aa96759c3059fa958a3a6e2c50361306d1c4a7b7f63a4abe9b13738ccde8195d2cc4fb4c3c85ad53c78dc8496283d0cc601396dd75bfacebad9ded60880f37b46bc61c87724c7b8c0513f1783675e4d5018f7f30a9115e2b95cbb5052e03b3111d90798ce5272e2c6228c165fce6c347c27711e7de6d91d0b6bdf34677334c6e8ca47a60e0b7bbb5a0f01a6724174d0cf0f38bdebf434e84d92160285043af5227e5f628012786f658f53dca24e3d3cda0841e6a5b1c9be5b9b898e5e71a0eac8825cf7d8b4f38fb0138dfda4cb5a9e5b0cc2d6ad4868dfa422efff32fb32a6535891e60413f524f001d727d786f2970e04e0809642af932031d727274d05962dab59cf469ab5d400f6291950cf78382218b051a65adfd64e4e81a5e31bc3dc22dfe95a810750fbfb0e9bb9e230aec7a3227e15527102ce7d9462df9e992926f691c129f6e38371aa044411006660b45b22ed9c9c0335ccaa9a3771614eda0ee18a5b1293cb713f3e4cf32209bf2b2be91b52a3e0461b00b50bc24212e7a0a168cd4a5670eed7735141ffbb2530bb11151d70bfc2ddd7bf86ec678546a0ba985b6152c5b427e31c612f298280263c0f312db2b751667a6b85ba0fac6656417340203010f463292039979dfe7bc30897160e633531a0d52f9a326a3aee24c35fbccdaa387a801db8f6d9ca2cf6b6641eae06aac300aea7c12bf9a28f3b667beb873af6f9caceec3fc3f0616dc7f4bd22f4146614c7ed9acb39a3915b92ac5b7787a877f46033e414b721b49d8d27e5ab892415cd864a75ef2e316f4ba10efa47a4559fcaa336afc1d9414c0204b98cc0a70626f89136564bfec778ef9807939900337c2616739d4a50f3be2c71830968412b0790e7e1110b375a19e3f5ffc7b3a605e187f41bff4a6283828996fd3f26a213a28f6e3ad328976ed2b72d62ad54cf51d8215f993325d697137dc2a4c1e3c80f6462158846588d3f5b8cfdafa9b1018b7b1348b150b76bcdd0640f57fd2d862dda4449740d5cb065e00bc50146bc70b3dac6a6e9103d0863af505eaab860361ed7accae9e15089da9d1d801ae35817a5f67a28a604771cbf3be04ebc9c20e51368750ba4cdee1f00fa042d805ab474446a90cfbf3fc97a20fe1ca5e4a6d588266864684004140b5150b5cdca08014cec724f1aef668d2ba67254a53f2c59d50ea76d17c1e2160bcab9fa7540b366abfaf5f8413244eaf950547f7571cc057729ea749b5fbf56ab428aab3ed476cd4f68b3f41eac270bd6b29fcda4f75626071b1a20be49701c43b4b16437ccc9fdf48a62fe1a2663a68c352e147f4ae8844c2807157c23509fbd64ac8ef2db22655f9745461382cf08b2d3cfdbf28081198a21ed719565dc566fb084e14c45856676c2a3a981576fad4bad652a20e85092a128f13027717bcd2bfaade88737b4ace18b183076e1876c817935ef5d7ba8b0622f6b2441c65d5d4c293d3a0506639a43c5d085c2df2b838a27263902349be4951f7f12272801748a9b3d4245de5e60f77cbeb1454b069a9f476e59bf36245722244ac46a6da45d3406581f44125c5661200e0d92ebdaaa3d14e973d2618ffc9b2081a5ce7bd73efba7488ec506c08e8100329c8a9f4db5d1d94165c5e0a21f202a8aee42247f7d031bffb09f2d852246350848d82a5c139169e8c8d39e6178bb264a9dd76aea3c0ee71750c7a9287741eeca96cc3e2418426d0e24d5665a4dc22cf017f7fec4b71e1e288e9efff6882b3fe1b39b4a527403b8d87a77b1f7b92511ef72f0386ad6da5c92005b739f5bb3c6aa212453e8e6d343ade9cc24a752631e63d16b0a0d0f0013302d8a6b592cac45f107cbd67975e6c4bccbb48572b6290fdbf02aee0467e7e24d7274351a3fd001627678697c6d18fb80fcc5cdb2b79e294219cb7224ebc6a5ae6ec05376afda73fd323e700aea6553a139f1bfaef34111e8014ae15ce5ddc2568eac8f8621f643468697c0f957c13d13de82457e4310297c09ac3934c2a272a10621472fe0deb9eb13dad684b66f5b19a420d8c010a82fc2de64ae10f7ed94fe5a610ae0f8889fe1d94f92544858c65ec64b95055ac11c4652efe064f85ac337332ad95955bb6db02f2d11040cffb5d6a8f9e632a93b14045aabcba545e42a03bbdb72421e4e08644e587725d0bf29d3c8a235bab183158dc24705ff40a5f24f8a0ea39f30aef722faf69af92a500abef9e2f26a2b642d76adb78616af6e74608fd27de1c8ce87a090d832f57e13ec2534abf164ba0b2be6d35cbaefe0366ab88d79d0f152a4cbff4a40a4dd1585cd47f7c6d39492721b4819f391ffe75d71858e5e7f3b7040d6d363761eb4b596aedbba067d8c4add0183eb7e4c92d2f449f9287ff1c0a8062ca1d719ef98e276c98ed954559047ec1aac319dd0d0e925fd34e61f3b450c6dc69cd7f50d4df31733d0652aef9d20d91b5aa21fe2b9a3c6915f614a7f1616959cc3fc32c5187f0dd24b0f51b32272ea072d7e084d62c3324dabd4f1985dc2c0aa88915960a5c1785ca8683207dbe4792d9d900add917b458ae42c0c8f66b9c414c484644e56fb083a7731d336d210060d5bf4c1b5f807c4692ca713632bd87b26ead2b7182937890b091a15f42d6ca2011026280c64f222ffd8629a17136b4c7a6fada3e2742fe377434073a9cee2bb03246938701a602957d1bb0abfd402035df562b6ac784c99647ac645c7958366136f0024347b1fd8bf330b4d697b97838393c0c91b82582343eb58e2f9d6b9c82b1387eed1f819c4d9a45a7e4d1ec5f2d2f0a8fe5aa96705c2058e1f62b5b2d5254c98a089c8f5eab8617604beb94022770aa9c76fab0cca170d5fdc2dbd40e628da831293d1c24273d9523a420bc585f93d4baa497e68f258121f9647fb2ef90bbad294f96003a9069d13d95465fbfb65362e6c70e61b6056e5b7053477fa0b17f609298e716d5fe9e20b2e49d5779a225f535ffa20c88bdc387a1ea66864d62571705f8745c3d21e0b714826d23644b10d5f3c166f1bd704291c20e7f685e8245e007dd62da8e45374824a7d819c48aeae8cc9beb2988bd8cb3cf074c7af0f2ec4fde771894a79f484ddee1e2af510dc80843c64f2dd12b7fb36d69a4b323b1d0aa5f93a2ea384df044c2132470d4c5aefe263fcdf47e68e9d26e63c81dcd32a389e21e2d56d771c823017fe31533809c3b5d3016afd6f95329ed4db23daf0106cd2e9f2addd7e0f013c1a32c3d5eaff36d796800acb744179cbd788a15a3c037261f29e401178fecd97f8fa01daf54700ce5982b1d58e025ed6ecbd300e7107afb7af7e7ebb538d40acad316ad54db0bab5ada811e395e0ebe6cf74ad149629c2fd131d0ef7d2faa4fbb177351dd1e68135f5ad97bfd6651a2c98ca8ef85926aef7180b5d563c5ad7df270d921a79feafa12e533cd9b8d602fea0ae16899729fc9de73eda204ba93c5c60ec0420cc4bc9d06b189045d9c12c71bd79e673c40c7ccd521d3ff61c7eceb8e965c00de62c8a32acfd1f121c0ee841fa2f756f0618f2d4d6ac96d7bd74f67427e347e2e760446958f9115ad9a35b530e801071be246e5576bd91e99ade8d75b12fbd1a43dd83960b318f970045dd374984b535e72bd2ba51ecd03b9396ad32e9fc4a8fcc22b203b32a45263a795786f4fbdc459b0659c4f1cc8261dfa55ea5ab693197366697b6ade5d4340c8192fceead82ace629a7472f3b13c28a954d467990509f4ce8ca0d37464673ad92a13c2715b7db55250d67b3a7e4d9a735099f8aee1544d0e6fd73f0cfad9c3aa5e40b0e2b8962561ec35f1ad2b11aff259d79d1baaba2fba96eb834e76a9c80b364e97b24307a281424aa2fa30be62314f75d116f5c131ec32bbd3d548ac60e287531ee45b88a9911e2292468a9077985e7f9bf3b9d7c9c7f4f4d58a034168a0846edc8fd6e821919bc426b90b9d31fd35ea2b87b4ae485c0684ab37528cb0f6319003a27dcf72e1bc9e5dc54f4a62cae86cedff569653518ce21fdcc660bbd5e7be989b268663728da72800734456991bb11783aa00a75d9d3e930bc9355f763b4c3d040e1dcf01955668b29288a41828a44bfcce4f3d3d409fd71f61b6a69b12757debf0d01692551a363188bca817da75832de2a3115a69e2cb747b0cb16ae52e6ee572c5de717941f01982ec1c364c7cd5d4d6eff0e3b03c68e7dca325c1e804b2e0abfbfeb1c9c593a923554ecd202ce87adc8dd2f5c4866d494f148edbbd7496abe6faf5023d53378720ce63e06078b8d9e84ca9a1d2a65616bd2def3a8bef72908acca0a10543ea597c8d6d636236f8faaea56d55a20c9142f080147a46a88648bd9dc11017aa88cf3adb1e5c174be8ce4b43d33da7b54a2d92514e12b6b768ec63bf0c31f2a9605389352931a3b69a1f26ac4c2163544780d60fcc85795256c6afa280027b06fcce4b557599d94a87b5c481d9a34c331c396df9656fa89ba922dae138408bffe3ac2706d43bd7fb1c8e56f3718bc24cd0b9e9b0ebe94080cb5eecce6480f8c185f442142926ca3172b2e19c03c0722752911cc8a6c7206f3c2912787122662900584b849d650e0c4eedfaf8187238a97f307266eed20d6e0b6ba01b9f20046fd636ffc52fc2d5daf18ebb043f41bfece62514c98854a64ebc2fdfeaf7c1cec169dd44365b740df2819d9ad1aadd76bdf6033173f06ac4d778fa9d4855822dba8778bcec03e6fe23987933ac5841cbc60c642f2aa3f59f1eca01f7802481358b76b89c085167d1b82e5e893efb5c368bdabf60c4d65c8b526e791bc70fe24da05333484e79a43adf9468afc8a513e75578bc37681732417d87d3d1a1e5a1d7680fc28c20793b079d2fbf91f06483f9faf0d3ed1f7e0c3414ca35b2f25e7277eda67942f851dff283b7a1776dff8760a130b2e4a95fa7a494e866404815d1f8313141a02a6fd2aaf2204dbf452587087026b47df4bde2c459632697f3909173803e820b6a810ead209db8c49720978493b40daa7651c88244627d27ae18420957e21543565fbd8367917180042e123042789206e7a0f382f05630a7233ce23870618eb29d57048ea6baa35a13e7775ea499b77fa2b2939a21948c33c49b80eb128ad72c44ec6b2c43ebc0ebed56c4d357759a372cb724cded062b46bd9a7242e8783d21021596916098b8ba9210ef0df0b8f5065757dfd22b3564c2cf1c62776f8659e98c20f45088864e86e85b8e61803d2e2e8db08c5597633e2884b1312f78654b323134010efe0a5a22f96ff83ab4e467746b698b8d2d68d2937d3132e98b53f62eb12c772cf6b86924ea8990b7fe9f6ca76e36ec6bb71334d5fe7ac0ff44d2a4c39e0447d41ee9144c125ae86e1696d83894163c929b99d5657682c0ccc8739c3c024b7d3b35be279dec63ccbd81e8c0d6e63debbcea29386640dd127985d1724b1ef912fa749d00325fd280af6eef3c77346dd5e2022dd02963caf2169bc8168aa63972cd3c404977532baec258ca30873d54b585b7de7de78081313ad920afd58a88ed6de63c31e93a3c05693b27665cfb4daddccb2d584b0c71f0577d99ae959e0d3295f3b009a1bc1b357cdbd35bd564a90c10c57a52c4d5c9e175b5bf6cda85e75a362d53be71619e033f18a912ac2bb171a8650b6494f385c23cfb56b3e56656966c1c3ad6aa4ff5fe93108e3aa5f266feb88c3654015fee429eeee7128c5e0b683bf8670ef76f2064c82e33acfa4b98fb010516c9758c24c08287df25152362f76b084441cecf158a6a03c74473f7ded3f9a280283f3a94306a6b182ca1c741819fa8676d33f15534ac596a39d184f208664084e86f69f491355d22dec6c7fdd47db8991f40363b46b90b495a01bb12e79bdfc17c015222c072641d13506921a872ac44c9cc8d108225e2aaf54c7d51d7a2b05ef429931aa01430a19e1d3fff8f96d9abb6c0e0cb3f645c059329e2c08162c99890102ba0d05634e00f98c8be1b71cb16bb2844c4cdcd67eea6259c5a9d668c058afd5889e27f0261c1586d2b4cbc5948a248e38240aaf1b6ee10801c93b9f6bc130cb04460efbe72cb208793fce34c92d5cf696958d7d560e5ff6847c635498a769eae2392b0e3ef9384f3ed5a8fc649537d71b6c540bcdbc695313c2d581d999edcbb7992ee1be226490863613c815b8677279673ed4659589212807f82da56e940e674601240ccf06909e2191a4d52f09a513a0acd557e70ee7bb5df0179cd2659547b10fa1792b0ccca44cd07e4b82df1a2c5e017d2f8a32c0842937f182a9f354a63516308aae017cf8a00e316b678fd379054cacb79841e0801c32e8d34e5b52ea8b0c8cd36caf58534592739dbb0ab2de7572923ec1622a98428768e440b38d4ace26bfbe8863b8dca57239ebb222338467db5400732d172f716e449e63c92fadb419e5644af6620b3258e48e198f2ef956a6856143b35a756ac2e35cfcb6eecc7d178c6515c496180fef749ac8e977fa63a28fe6dcfbc73ddb360ed5709fc9b0fe026c4635a79e7f4caefe5299dd7cf4b0210925079bae38b94a1cfd393c36b5730d3b39ddecf9213ed09c1760211d7c8299f793f875acc0e8a1e444a7c8009d5d0df95cf94b07d8ddea9e064bb63e544b266a94c00d0c91b75697c7164fea0f912983f360a60797fda997f5f370162ef1847ae23ebfff5e72a8e8c719631b7f8e24c08cedaad805e39e5373db066ee5705cf40a4641472965ec2e8165fea29ab119fb1fb534d5183820622a1d4500fceb3ae14eac2b420e084526dab4088f174c03abd7cdf5e33ecbcb6c6b1f09875a347c283cb0920de180cb615648c29c203f0ecd1b1a3b9d78569171956034619df0c3f6bce2442e302b4a7a0d6c321313491247bf62042d00eeb61610243fc11ad0d517806fb5f9ae448e7facf517db96571a6a1af751ac14a6383f96870460481013a08d296259a69405f1b94b9c50af4e262e4a32bde88f8a1c7abf78808893ed9a0b293eece0feb9e5fb3c86cd4f874b0a8851b7ec202d182ce02749dba88d816f94c2304cda0c56573114472ae4789903a9782552283c2c2b88ed75ae3a610b32844cbe7e7f7c74f5216fb6cb6615cc2797978cef7d47016bee6da4c77e9f60453cc17e44724812dc958172c38e98ba2407ea8b08e0f194575cee3effe062c4926bce85ba7e338a9a3fce58d4e021650d19a35f54d83ecaef10cbe01579973ff5bb6c07b29feb89ee137864ad11a2a70cb411e2a5b220b3fe8a74bb8d9bc4b624dc5914e52b9ace98e7671e0cf5e92b19536b803836dde90b9e384ffa4d590e141d96cd7944b79c6fb3d80992fc108702956f27608a987c9947ce3fdd637773787e0f976bee528e7ff57a7fb94fb361268bd81710fe3a615437e23e557ea5c485b4a6dbcd89e24eae87ebb9ae61eace002385c62bc8c9c1925ad79428be87cbc883c29c2bd9bfca108086de9053dd5a27999b28a3b0a8e41cf1fe430c3a035940be16521438e35fe5bbd212b8d0bcfb0135f7b015e51ad8ec8fa8df12cd077ad2bcf7a705889b9aa6674aa84c0428eb1ce7c1fa8d1b1adec22d51cc8a501c42b95c783dc1320c9b4d0fcb6f5dd4506b206f292e5d06fa78f52666675fde9819ce5dba63fa92ea8a6463422461f58e622d8937aae3718f509e1cecb3c95c9c82ae33ad610f692d7df28bffb8ffd4b3e4039e63003aa372590c543591e7d89ccbae71b74aa468a70da3db0e3ca463b15f0e6f4cdeb5bbf5ec3d736f1505610aff03ab11756a701f5b77578daf8989bc322dd5c44335a39dae704ad3f23389a598b98b69642f6cd7fa1830b998d64dc6a3250d7e6609e26e1725a4f6255ffe0e73e002b4aad16a1ab58b3fdcb8a26958830810ead864d8a658780beb619fab6c34e15199c1197968c99b38a5bf174478d413830e0056c5c2f967af9b3d26fb050519d4800bfaec15e7f13a94dcf2c5a2bd1c524d5ae0d73b30261003402d404f8e596ef73e98c0c4a6acb82456870f58671d138fdfb25ca284ec0793739a7cee577e6d3ba319efff2cf9f22b90f604e4f7014c701b5b3651d06ef3f3c3d566842801f26b1a8cffa425ec7aeffe6c1205932807754ec92ab14d58fff617ef19940a7e40c95ba9414628d59e6ea2fa9cc1140dd37f315857802b79f5d1b31c3b076de22ae95fdbbf2850886a0c671a67666a0b789aaeb6190fea5776179f028c774445d9c61c76dfe1a263c30a0ce5880bbf04378426e45dced169fdf580d0927fe256cc195db8122edb0732eed159a32cc72cd17f0ff0775670ed47492ab73e9bdb1646d1ddf6fac59a2f1698dbc00da9fa24dc2ab6ee98dcbd0682385e98342ffc86fc964c46b89ccbc2e990c68a761169037021867fd84d7db8c3a74c2a31bea5676045a5d33c4f525d51c11e01f58d200f0fa35b54f19c81087074ca714fed679d10f181f9cc2dfdc8cb1ebd703ac7200150fdd527067f0bc99b5b785afcb640874b3f62159de99771e6a86310818e5f2fb0169c55188588154761e71ffe774e208c335942d4dbe4aadf295d59297039066fe4bd1064d8ad040ada4cbf1f5cbe7b80e29396dccc2e0c93e4c1e0f373db107e57b560504f1e1bafce78380cd492758e1616d3076b68ada6dd12ed8adbdd14e14ff30a2ac375956f6087d8a68b13539c5a45d2b3de89d08a7db022f688050ff38bc3ad29e40c07a6159f119da20b870054811250aeb41f835d074b948a6b0f6f2f89422d726d91317c14441ccda2e382d0cf289c03d98aff6b3d34934bee232323cdc38dbb69f1c9092ada5e3a9cf8aa6e130203f1dadcac0ab7066a3de015dec2ab95501c4ce019c7cf444beb5d20d0e31b74e319c170c52acc6feae34009bdff8a7a5e189aba127f8d488ecec7bfee67c0e4da40da08e1d216c95e4e531569adc78433ec670379654df38bd2ba311657bd0273f3f945c45f7c9883e9042040c5b6cf63fb1069b8e0046174d371d03eb6cdd9029575e42b419a8b72380122ed3efddc9233f58b6c2dbc2a694d2b79011a794943f1a99e6603632ec4085927adb6976fb676e768d1ddb26b2c88158e8cba7b666ab6a20b030432ca67c8eb29c3b535066e0f779fef60ecba39001047452fe610643fb4491c13b86dbef2f409b504bb782009166f4d3069566271c6cc026ef64cee56c321be4aef2e665d47030a7fcc5527f2235722880893ad58c7dcc873095fa719bfbd937803dcc2788302a5ff8a658c1426defc4915c2e49e49ac66eb4e661d97eb9bc1c19d03228a58003a38e29ad1f40ecef9edefa3c9d86d6fa481d8bcdffdf1de0e419883f488bf2684050e1b465beca794930b7de04f78f0001bb18b954352807a99200f935f08133200c22324dff58e9f920bb0e54c8781c29ff6466cd26ada6ce05255248138001cd0f79242fd0768675144caacff113ce2d470a5d98f9ea44b6fd446e8511c1bd7c61a3d26af3415eb3532dc9b7b243b34752c63ba0bc2e81bd6000af3ee3e2f9409ffd485289bfb3e1ff44d8b181e081f9f948aac37c0d7d535cbef1a42501a0050b1ace19cc1779e23acc5aee850bdca8fd5591bbaa08e5b94d30df3f6b32a05139aad16899b7620a46d0be03c740e38704090e4d3d584aec4eb2d56f39a1573706fe29dae924284cffb950843d5e3090b3b59c9ea76a1a2215bbcd869712c7129bccf788ff4ccf5d9f28673b69788488553de67c648560a49f98c9054a30968dd170b7f9ccdc98147a7b6b0552bad5bb39a2eea0dfd942b320ddcac5e382ee141dd1b89eb46cb5e9da7537f63b77523abab01e9574ad161a911a896b867123735ad4c98de40f373bfd62165b0c737953c8c816c27142cd245917969bce31163936dd6680031e303c4086e9c8a6de7195c51fcdafaa9626f4691f201eb851e943c2dcf5a5e90005783bba67b6478fd637e43b5dfefac385e32f640c2e3fe298873ade499d92cca544769a88ccbaedb5cd4eb5e8e7a431a7b10cb0dce44f411aa3a22be6af7f1ef5b93f96b39c28a818225c7961dc5879318e9be4af78d59150260b3b712c8c4c615e4f0558d5d7abb9935a34b4e8dc050990c4ccf01a0432e2397266aaa7a635fbf97199e3dd6cb8ab9ceee4d1843f01e42df99b7b94179272eefb5e7453450e17b2efe24e3b585fe8707101d3d26e7d169e7e083538693066a2cf45e25626f4766328ebeb180f4c9a80d5264794e3395ce216080940d8b2f6709d618e173e4c91acbf76be013ec184526dd9d99b2149c441cf1ec1c7daf170670d5df092b15e582daecf85d140daa23aeaa5008183d5ddf926b0c8ae0ca22a9c8e4093ad0df5874c69c34b912671057b6afeda2fd41e0e223710ba8eb4d28afe45de7a7bfdf7a5d6443da901e2c2c966ef093056c4f62c820c8a0bd8c9c28344c664db4ae049971d8f089bffc11fd4535874c046cef36fa7a398b3ee6410b62b59f2b7c91d2a1d851e94ed0af4367f3a9aad84e12d9fff68aac9fde91bf2223dee4ea05d3500dfaab6f91203b3ed3f2346f1462240763462d1db99e8bd205ee3afb116f9fa13790c13011b967994cda0d7d65a4aefd076870bece6b2b3f2ab8907218701ef6694146c2c0ea8b1d7f40e95f744b957dfc325397e7ef1382", - "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441124e9634ac86d5322a89fe272dd95ec8f0910e46f753f89c72c622ae351ae9ed29012c2b59ed2e47dbf67687e99852bec5d63ca1680e3ad65cb5c747a9c37eb900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f17b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "proof_hex": "0x000000000000000000000000000000000000000000000006443e4dd7cafbc6fc000000000000000000000000000000000000000000000009a5b11556957a2fac00000000000000000000000000000000000000000000000481d8c87ec8d9e44400000000000000000000000000000000000000000000000000027e3c69ce5a8800000000000000000000000000000000000000000000000c89919183396d2ee500000000000000000000000000000000000000000000000156b5f6351b4e1677000000000000000000000000000000000000000000000003fa278d2c3f3cc83b000000000000000000000000000000000000000000000000000257547a6577fe00000000000000000000000000000000000000000000000a7acecc082a3669e1000000000000000000000000000000000000000000000004e4ee60a9610ccb0100000000000000000000000000000000000000000000000139a7b0dc64569eb80000000000000000000000000000000000000000000000000002797aa349525b000000000000000000000000000000000000000000000000e4efb10408e5e22300000000000000000000000000000000000000000000000565dff2497b05203c00000000000000000000000000000000000000000000000c3ee606bf31b8fa98000000000000000000000000000000000000000000000000000144da9a140bb701dfc1ca1fdf6f4d4992fcf7bebfab3317fc2caf844b02fb8ac4436d5adea45f18531115019e88ab0ae6f13233c1014519feb8d5364b2b488e9d836182eba9d800f3b9f16b517a82e074902c3c99bf34e7be3eafddb913ebb2c8d05595a159bb2a543541d15947ed4f1c1620e84108ea3ec32503ad7d073162c30b94474e387c0cdcb845177847e28da58f2486d85540c5484ae86f2294cb46b4cb84d0aa3609083d483a8b920f898636ed7798e980729ee4ba163dbecdce8b02670604ec9b920e6c4aa8dca3ce558f7cec8fb7f4bfa1b0d4371b18bc835220613a1409fa080f120c539f947fdfeabe4f2a16449a964098c614d6fc20e3e80d0403f0241f5d8a13147d749da88cd2a0d8266d4380e5070e0fcf87e2e312a3cdb01409afb8ce082549d88678d5f866e68a4d0281b41a6b539a157e18a18aa47a9d801ba82c15b4285ed10e2b52a839fd1fb5a55f8de22855f4af96518bcaccc2dbce494a296ebe26360d30cd1d486f49978b029766d49825f3c54d91bd255e22e279a69caf0742070495855195395e1742793b60d1378c09dc9c7053216512cbd2452209ec4be4071c5a521b696e975b1060278c4f77f59bb6ef505a7223d5245c2faccf2d7a7b17bc6a08396d8036223bd5f0ae7ed2f2891a3c4e8846b79bd36ade7b09fd6627114aa182ae1731eb6b9cf19b8b841c3c2b6d8056888915d6f3833646d375991e22759e6ca02fd6241ed37565eeabe5d1c1ed7734680293580c5485cae983d60911a42e17e7646d7d5bf1b3633d1bf857ea6d0d6dd6ac3947070d93be4e391a921af9366211aa3384aeeca7a871208ff44293b9bc62fc7a31c346b3bc0a41d8ec2faba055c65299d4680c399879ad3b09b91ca75c154614e7c2365c05d9e1e1bf0312970f67ebf20490f3b18aa7c84bfbf44044a62091158a689ffb7eff443a0d006f17dce991bb9008594904f9599b39252e57e6a7ab50656c9e5a8df72b58d51b7c9f4435e6f52a478dad1fa0f66a4117c91477773fef118f1a5b2e2246a83126b004cc496b97eaeb0939d7fe1fe9df4c45268c13f7acd87f8d7a7251397537066d564a275044ff3e9013c7416550403fd3b89f31931a1c9bc4c78890d6039319c12ba5bf473841715e3058c08b58f6c885980ccb7196c78fbab8bfc448f50b23e59de65950bb9e7523d7c99364b96ea7e2b23207d02a56f9a6ba47ffe607b0110784790f007d11c1a16dfc27e06e1ca443bf4740ab87fe60bd2e4719005c8706dac42041fbc232faedc6e10c6a6f75b3fbc206b8f7c1648c1104fa3deecec91ef7ed44600c3779a8af114f9e25af821788f45bd741c89b36e53c6e5e6e983e23f372c640298eb2ca3865a651b2add2714020d6de218a78a66e53d5eb9c037921c9f13da3795f03f8a780a09119c28b795e6e6b97d67250bc77c40a81ca7253285c8d29c99aecf5b4aec5316f45c7934a7c13e79ba5f526153174eac6f0fa7f1d5423429dd2204d5a0749d4f1d72ded1463077de54e2914170e854d559814782791a449f5831160a02643aab224d9ccadbd7c12366cbe5895233711003e08701b69ae17495eb9c96cb4741fa95d3a2342926bdd5a796de050b055178f9e91ba2582ad1dda122e9168349f910fba42f2389be4035b6a4a0776ec380eab4a7e1818da3933777a20728cd32e8aeb3f6dc1c954b5e7ee588996ffb14ff769561b1427200b52b53eb0c2aeeed7d7ddea931eb9dcd23c5652b768cf3fbefce53500b8030754c5c1ca1108f3ed46afb942bfc01b032b26a8ba44e62c0365ca4033b1b219a80f8a2ca3ff9ad952bbfb2493969d7eaa90cc4aadbcbf36dc76a0c848bbed2978369892c56259b660b0a07ee28fba8b592f129d029bb31b80535d8003742403319cbb781f5e4270e2aac914ced8a3fbbaaa3d9f1e834bad9b9f07b44814681c3e7cf0859f312e121eee65169a441b1dadc576870842c917a36a744b4f4da91c33208fd45e9c462ef67ea2f432b555a46ded01dc8ac89fafc61142efa714650817710edcc68e99b475b7ab403a6de405f94656a27d39fe369e561b26a5457c2921ad7d3ef554ad5330d553e322f95d5c40c50efce4a009493e71875eb2182d0f82765a780330127718248a51508491c0d2bd80766fc4007dc818073c337f882d78d25f805d23f12d1db526fca5ffb5be0e54a6ec25e46bbda65b6bf5aec648184761fa18ff033b31c97d42fd3a43ff3f7ecaea4d304d336e0e917a0d2e4425050be6d7fb830cf4562eb87b213a5d6a0dfe7b3d63f8e11e3b1efa9411183811071ad9e3d533211eb93739574879ef787af1314cbf7fb4e874c3ce87ebf8c3f60f93f0b8ef56a6f27811b193c26971d3e773e76e68c5daf56140ba20f67be6242773bd78452b12738a0ec3b6204e93c9377acc0358971d74ac9bfeaf9245d9421a7d20b5a4a2ecd40e4d23d71ca5a7e131b932acc89bfbd6866b38719ce78d212cf028cef1628129d642240f4b2730357494ac27446f5e56c0978e0c2fc239ee112666f0bee00ed47f0164d22a5215d5db82f3ab6cf249bb50703d3dc27d71423028a4f72123edc079901ef7ccb56bef61f6591b0477b23cb07795773f20e2bb12e5e0ef459fea65851cfcc4b387fc42cd5e71bc089a7f4381c913855a4f2f1f0106cae843799f89fa4b279a364f633a37e4b2640c69857e61279dd803ec5c6d039606c9c10584fac7c1d5b10de7b25738d89fc5569329afd79e885fdb953cad2cc05964e713e4c71e4c07ff1cd10c406ff55cbd851532a4839738d7227ed257241f748badd25148e8ca89366948ebeaee84d613987f693e0d213aaa594db3021fe702e566a8ad2d75ae4f812859398669a51eabc475fa34a0d77bb9611932a904ba84084825294979e0ede81171919e8bbab7354cd01123a8d61d9548b311ce05d765d5f5322a49e084b9796079b3196f5a5ef6761db7007dac93649c4a387d02a34ad68acf136903543014ec4b3d4a3fe900211ea22ea18eae5100b319d329034f88cb7f95f41dded0a0ad75b68c71278a61b51c19c035158fbb8259d36bd505735e825c6b8f845e8845155cb93ba122d3e98c3db8da44666609cf7192ff0d15d728de03a78427d9b166b5ad8555e4b65afb3244bd53993eb496c5cd50833d22341df3b6674d72bb8271c4b82e7f03740f15b18a7ce3fc8943f81f826fc8fd227bf5ff41b0989a237271e140ec6ba99a0c2c913033c1dfa00f9613114733a42111810a91eebbb5bea13246518438196d97dabf006219b2203cbaf73568d7f8077e01b07756ea1d188ab0a2d7d2b901634618048e281da916256acd484950b7175c097adab59b620eb4718fc51493f0566c9e30124ed27baae31fcb691fce092acd8a3e8ea251794afe8d35d55ad7037ee89476c111e04610f219a1aee124c22ac4339cb28af586a14d986b328dcbc25636df3bd150a77cea7298745cb7fd6b2ef63e7413dcaf3505f98d6569f1e4c8f3d5082903c2a15cacd73e75fd8df54e2307f9e71217ebbcf22bc61abcb8690a22409214cd7847da52e761f7ced049a31c763c92153a0b2904739905c9cb26452f4f573ea8f9a7740b72e854a50ec596115078a8b11c57010a27a043652ff97f51ca448f30614810e3765b8a4149a63e291d1683a4b9a0b964f6ffece7dfb0cdf1c4ce4f0fc04be99672261f50284503148cb9351ff4662a49ec4803560cfbc9165ad379fc90ce53beb5ab320807a8d91d0a10934a2b9e4363934b89c786d314b1a242e9128fccfa473dd4fa8f8496710aa112f31617661961f5e97fd2c3fea061bbfb54946e7687ec43dec8861421bc140c7c1bdb0a3d9b5909cab572d3434a2431c3236a57baefb073fd1bc6d6d1912532702a84570676a2eb0d0047ac4b2bc9fbe5c927e3dceb3c5c249d3cadcbe929008bdca758870e554bc839114d0ba80cca1fca48d28166f949e52c54e6928b1b9605ffb5f5f6b3db23931f7e59b994d47f7c474a3564aeb179664ee01f91770839111d61a992bd1ce5fe02631dddf3d4ad212e79a3aa20c635f97ea8d6db1a1bcf6ec685335f5a88413279438d62e691fc5848efb92ad7dbf44ea4e6f23a8d20414139bc656a727e0ebe69c8a9dc3802d314028e5a8643622b705ae5ae82e01e2578c9d36a252ed8138a7aacac14849121aaba10a66d6ddde63431e9bae2151950ccdf9487c6874ba926706e38df897c4ca3183893c211c3846182cd2588da2d398a58df3e979a559c498fe06a4a7a0163ee286354b8da07da8b9eef9945c618800d7ddab549c895cc7e2ff3000f1781554884bfeecb44e4124d603ebc19b829730a60168980a8fa287fc8f86c0a8a90ab8f38e71f804bba01d8365d1255930ccb79be29beba86407961ab765e979b3dafc32bb1f393d16702fbc3566aedda089832173ca5a7e5069fad1e0660959d49e0bfefd74d2314b393f2fcccaf682a22bea10fe8179d3ba752e8044853c47f4683b4310914f61e58b7a1df42504a74113e6facddec9a9ae5b220a1d6cf4fc0415e9f725e11104af98a7018d5dbf4b5132e8a07a7b4803847e32293d13af6a33d297cf15e40db4bade0a4774ac86b0b12fbacf70560a28f3f7b4db8fa73364a46bb2eb57964005bd8e58c2e61eefb861e701eadc30caea24196fdfaff46b16dc10ecaea90bfdcda36bd80ec0f006d9d2e1bcc89a79ee552a9d1d32fa60bc21ea126a76871ff91f479eebbf887884f360274da76723b26de1d7a5e8ce9ee53c7bfe8b5f29ec186a407e75ca0e3d661862b867f5fe4b79871eed93603d868ecbefd6a9b1188007d91ab5aa9944fde3f6b18da6194ed89cde701078d634b6c54192dd528fa637977e5c3675f4ada2b502e13be091100049adcf52752f514bf95c3fe99e4e20abd509446b5fc66a8857e1d2001066787b655dfe8931150d5648b382f60bbe72d6e66c73e3e6529d54dcf4811cdcc0314c615042bc66bf5173485c9881e9544493687da1731b6293a9679fb04b9622e9b578c81c7608e01f3053cef3f632d4ef5a58f172e8bf12259f6d5f21e25a74e2fa134a379f6308d57c51335552484fb0e88867c9d243bc181a090cb031f58e0fa9f655929adfa77a05baa4894c7de6a6d37290d3eb16283ff637dbd2fdb3500df9f2418aa9a9f250fde66f091fb6ef5acdb61a27902e22fa6d5fdf0057d28171834d980f73ca8ccbc0b303a5062a068e03e7ecfea78e72f78bf920d00be36994a8ee4f42a36ed3a223fba9826a967f946e75760a85a595015b8af2e24ad7c59e99b87f60a5fc7c76e351614576c43732e32d314ddbb85daa881eeed1b150a822d9945663292ce60728bbac00dc5ba3c649e814005a52df5c0fc59b81011cfe6bed95a7ff1808bf7c6e1984dcfba5975ca1768a00381f2974a32d1151e75c2894ff4581c65de16e354ddf938c056c93a50c61579815a9f0282488c76145951a635f929a71f8e662224c9364e12748d715cbc7bc93c5606f07687844222416ad582df9b9091bb790236a28d090291602b43b80c146036ae1d2d3c911123f37a291933fab7e30deea52324ab9ab3adb486903c9960992b5ad8cf6d89670e608c9b4061890a793116ccb7fbce38857e020824d1db42f14fc651164d22a60aaa8f2ad0f20b63778277b1f641d7fc5d12dae47ddfcb2d55e6b870d8b2814c20ffc73af5fadee89dc3b3cd116e881d5c768520e9fca681290ab5c58ead371022b65ed2116f353e440fdbe5d2fdf3f025e2a6d2e9d3e94c9293ceca8086b0de285a7305750eb30cacef7b5469a0797e42080970c0c3e70f990892b6ebff1044023dd8d11b77a419b3aa19d4bdbfabaac8d553dc042fe6c4555b6a14fd64ec980146ddd60ce32d76980b01b71eedf0bdee8b18f198cc0255d73108f17b509bc13025bafa936bc61579f8c1a9930017d1f0b042c5bb0566743b6c731e05e3bd7d1cef12b035210c3ecf81d2caaa99da32fea59317e383b970e419f861ae2573fd2b3c6b4f0c1ca9dcd2203e4b1be938e7838f970bbbfe78707468e381083605301c190b6c5f06802b1dc8b2280acaab86ac5046231ef1060033cc35ee76fe2baf2d661ab0c19ad8987ab3cbb89c97f3c6368ff099e09d1febe8e7f6ecc1479f972b5c27cc320c875b5f129f3b6ff24b4c8a2eb82af590659ba225f3e190fa4e6b1008897acc6e797f4357055c26eeec55360f23d1da9543b6ca7bb34519652626273e877efaf30df25e18578770476876265c499564d49f34e9f6a51e30b1dabe0c32c7acc142ddde363e9e60696c0fab4def3165b7cf5799816352fd5147cbbd053810b943836eae47e715380acaafecdaa5c56f78ad25cd6beb48b30b71e97224546462e575474e305a384c11241bfb4922692f7ada05ae8ffe3eb5a61f4a432346ea3071cda58fee452fbc4db70cd573ef7d17106659050ca1418bbd2681da0af56fd4cc9e2c6418372609222d7387c272a336e2b34a001899e647750744331b117ae4529b0938e4e4712dc5686b6caa250480220d3e94a35b9632e3a73fcd126572f8c3d4ca698b890cd2cec074e5e7a8a7f6f624f385cd36b9d21144013e1d4d49e7dadd46d3bb09ef8d4358a93c905259d943a18b6a020e9701b77274ef12ca1ec8b6d0d112d3b1dd49f29c7bc13ee5e7ce00c1e5ecce92a8c5b0b5b464094dae99c3561ef02693568d05c04104963444dbfbe0e6cd804ab19753689d2f1254bc80d6a1dde41cae49945131b625cbd58bdcf37f4cf699f10aaa7267e1d62acaedd0bb43e6003a32c7112ec16756df55e6b945e730898cfcbaddc25621cb0f3ea6045ecd0c18e3c46ceeee924bcd8b5931869ec38afe8b79b6dcec6e649f26fe612ab89de39ad9fb9d355f67b6608ea70697d9f7125cfa4831a71b894a0a0bf5eaba34f2e38a421e11ed8e30af9a02bac691e911dfd2c5cc8bab6fdcb23904e79827c342bca3644d0ff0be3bb71ebeddb24e04066ab1b9fbb82705a3266a1b742992abbea7a4b968075d5348ff4e1068b01de9997679713f13c50b558d69224e93ff28adec2874a0f0131ed5937a9a84f1a1d27815ef6d4412936fb2d9ab2c9f461e5eb9aaf0b937abf2c25c62926c3052eebbc13a311af28dc949296b271595a279367d738f840aab4617ae5d46cf23b6a6f6b932ffc79d71daf27bccb2128f76718008bc6be9dcdb3c0b25b5172b1da3752ebfd6f9ea2c8c609d906b690b01c120df01729bd22d73b94dd8afa3b34ecbe74d60ea6d449c60645f1528622ff8a547dac1025fa5fce863dddc98f0b30fad91b413d57072fafb52119e58ca1516eee808b2a74efc1cb43944b1974e17032d21093d286720396ff7399fb63c1f79cd6a75644f67501af7e6d876bc562174d7fe4eb0434c4cfee35ac6be75ac1820791537c5df12a815ba14d92b0f4fd6d78169fa6451cfff0eac6ffe080c5c2bd37fc059beb2f3793a7cff7025761e181b81ddd54b11acb6032db51a7a8ed713315f3711ea9f0a97830ae8b36494b8543ac9b862745c4215db849ec6a8fc6a1c5ee285c997e54b3c9fa212c4eef18b07de6901258f3ccd0dcf9ae10e0cec6028fc22b8bdd77d9f5f5753eb121e13d18332b7ab5e4e1b8da6ed82e9149a8261093fe0c9ae8dea8f167327c5614e10282a690196332af402f400d795d62b79112c1b39336e2d239a9a003fd684b32c1eabe3d12736033faf849ae7b6d13f44770823917fd825b94292e2cc911cc0bd9f55e29597fc6463429b0e3113ce09bf1223150eff80c462c613876c1afb7506910c9d57bcc4294dbf2154e84ded32aee02db67e7e6d6ef0b310397c49c631a159f637d7b54fbba46993bde91e06229569289dd10aabdca78e37e5e65111201ba9db43a5d736d09002d9bb979ba354884f0ddc0e655817c6eca1bf4e8399e6059ce13bae13442905698486b29df39028c226fa402d682da8022ed12079080cfe05a60c2764aa1d7b8ce819ef89b73474a62a32750b401f56656c401f6fbefb83b3fa391cbd494326e63cc172aac33ea37c2ab915cfa8935f6c1b643657122c82828d974eb995919f27f9045f1bdaed542120f563c340c7534d63bd89254d5aeb0962d72358fddf008461ffb28c7ca3331224a274f4a23db46311983cebb2a0c25c643781c581dd1853a98484e7daa303272696b4c3fc3250899de7b73273f0cb8271959eeba9f47d6f27845142bb5a30241b037f5bf9b9a97dc46a8293e61834ce50f783911f3be4c332cebb2a1254d2d02770490657b1d03830ed3ee8deb26801236387b361c6422b4119a60b45c17936281de0179aec58b237faadaec4581354ac0fe01e42e4aa3e7d9660abff18d87106ec366b781a8e7b6815aceeebca6d1742fa5b320e1bbccd556fcab55f5df0fa25613aa330b14f831113d7b0e58ce43bf10ffbb5922d8037fd6e8895bec323a41dfc55b695ae69ae883e77735dc097ad451c8943fcdb85658d42a356aa45a10d079f8b8125a7b007f583ba170dbace2b0baeb316a85c9992f4cbe7463bf97e420595f7e9889b31842f7bcb87ee9e1659e67146d3eb1738237d580ec4057b010007e11de07d72ef853d011846238a94be1d45b6af5221dbbaff5d7f2b345aac312ee1f0ba76c97dc811aaf550748da69a8e703e30d162f6c4d5e3bfb584709c610de2f1e1324166ce349aae1e7925db177f435d4dea9943c13a1a14583bc4806811ec85e76d455b6ecfe19375719b71801e53989ffd31d68393958d5db8d28f5e23b717a3076b3f25ae79b373b4c2f8b74ea54e68d5b611508ca732b86b8e682d0d2fcf22fb341c462a809a437c34275a2b1e99cd2f306ca0e5c471513ca2636b189a2f7b2fd610eef2f1f564c494ccf64b450345ad58e46520438d478c922304080088b7ac282721cda9cfa89dfda2df6b663c9e071514b42a6e3e3d3f4b8a382289a0b58bdcc4d9e19fa811d6cf64b4a703bd072cd660021d4d515e59e6df6b3046f12a2efae22d170874e2650dcef1a24d6974f77cecf09d6fbfd8b34feeb40652708e4d2e7170b5938e06b95d7239537f7ff192bded21492eb0b817d58b4d165b06c7bf692e0321aa3778a74dcadc77994701581806ecddaadf49f7104e7f0bc5921a00718a37a6af9d199e6e7d94a2bf032e92c0eb564adf2a7fc68f24701231b482e813783b1f35ada11c23433530cc7bb6fb050f5e9ecd90b18268a629098693da7c2767302986f142e06ccea3467126f980182235dd26f84f3b4168402ab0ffa139de9f700d94fded6ef3da03e6137e64131ab66dbefb912545cfd9ec2140d43b2b04494a1cb5de412225c593576471f8421345c6461404437cd50bdc05e52284204951c094ac5183937c52eb1f89d5efc2ddad671cfaee747cbe411027d28a630695a70bd84e6c8f2204baa7816303b598333816bd2e069cdf2d900c25394ac8abc092015c03de91897529f88364c5920c96d79d36adaa49fa4ee79a1acf5eb5cc8c68c2d207e2c00a4be93e9f7f68fbcf3b22641cc46af5b00e468b266253abf616d8a7219eebf4ed0c186804c9aa518e6498a95d27870b09e9a7910d7d2897abb953838358a1c632c883fdf1da7f014a0145b925a4d62389afc2d21d320b72198c16c59816aa7980f35282f8161997479712acfcbf2ae7fc939048221d36c6e5386de18e2e31bc9151bf31caf26bedd9d9a294b1582a0ee1fd54da2b29ef6dbc542e0a402324832ab4a568d02661bee1222aca13a8b8fedf6d1a212c033e3b768116702bbd085431c7df39c570843069c428878590357edc235a0d12653312e04bbf99f98c84e15b59ad2dc98ebfbb620ea25d8800361638225f0f26fa394aef30b30116a967ec0c6a1fd541f82a8091afda6a6d6efeb080c1e0ad26577e4b645ddd36cb9658dae88d305d1fdc55f0015d1b457fa072d4873e8fdb1e81db21d53d8c4cd8c3d14ce58e0a65f6e4f36053c3c0c3243d19046bd8adb80790a527dbc5ede9d8ecdf60de807d0e924b52c138cd1ac03a04d8e88d07c6de29ec091c14d2da49d5d8782121da331473e86bf1bfe45605de793e288bb1aa71066aab84a29256bd7b881523d47ecc983a2aa4255097c5898bb5af93edfa26d5015bb0c6cd798907d7713346c22b48aee272d38248ae714ea7ec5b82561ad2311fd201458f45a4dd86e7a0f108886af9c8d7613617ef0163f18e25aa9ecb792929c4b0889000b9a49cbc9fb16aa12d3cfc54184f17e50144038d3a2a3626f31e2d9fbc165df3f9fcd75d9e99f535022ec91b19bf7c24a033acc8944dbe79ccf224ce84f0ab04273fd6974069d53931a3a69ba7714be5da0f234df46855e054e8299b8a573817dda6b09843956df7a0e2e21d4ff9d91853431e11061482a315f001d434871e69df4e1f24275172d544c130a1c6d40b3bd6b1d7a3d4520217577129eb8a792342940a31d20af3a99f0f4e005da9e561e5237598bed6ee3ee3820a170ba23dcdec74b1b3b461944639305c1596d3b64c83582a758a345624f51be201d7688c69fddc0ff0eceebb2de6d06dfd6cbb7047857b1ff42f680eccd1ac212b73a863059add2efe748ac8971207921c1195f099f9ab6eb43dd55a303e7cf52525392301fc899dfbe7408424a67c509243e5eccd4cfeeeb00b78288506331f06eaa5fd76a09b44f56feaf2d7af4d23b05308b70ccd0c1d5ad8ad1d47b6ed200fc31fa90f5a3102d27b3b1245948561a7259fef448d208a4d87472bb58b647024fa6e040e10f43ebfa76dff924cd8eb7b20dd80bd5e8cf3253fc75ba2921ba21a0ec8828f4e0b8b951041f4e6b816ba41c45a187c8a6434614b24a67aad33d81226a98970af6c1c254981f8fd1d3325244b579ba13038c2e15e670049d7add31e5883b5055d27d3764f707a699a7c34dedbdc2dfa2388b865e81f2f476a9d74033cf6829ede66868d1df503a99b0ab65dcc9ff4581d674e3cc0edd62f6144551a124eabc55b48029f4d416c598c41215d2e3517fc86598aee3d3876d356fea301e68d91f485409a6939dd9136e8ec513ec47d57cfb3f3e0c130160725b15d712c4d57fb83fce70a48b1f42a06f7652f13a403c42e096aeffd06aa22ababfa6f16f60d110b6e2b66ea8828bff298724e5b5fcf493b2106050b85f98ed06491ac17b4c24d508d47a33aeff7a156692b0f923db58fae1b5cc154be223e28cf7085008215ea995ef6c42fc4c9fbd66a6bcb70b2b38709054ea35cd475bb49de59e10956147508ba2e4fb0382e90998b369f03ec4b14d8d41369fbac5544b4139cbc2bd1cb184c504f95bd229f7df496b1e8148eab68ff7a47356fcb4370c00f9a452fad6ce685e37ef2fbe60c09063c8269b6f4a4f58501bcdd6516d59ff13bc307194265fc4a499426ae6b3d0dbbd38289a438005d3a1230768fe7f22a6591d73c1897db709e4dddee2ffea8f9cf5f7505c38eee0e056bb84b077f668fa3fe29441212919a9819f2e3e22e177096168d5e245ef96e5c116cf5c79748d55620b9901ef44b6da68ac3effcce28cf482c7117c35f4bef183e4bbbc96512a7fdbfe0381833ea263ebec528a88e53d624614b2be689b4755ffb1d27f661b4f5a41301b90dbebf58ff3eb42dbd35814ea7a002d1e718e722d9adad207374586887a5224a2e1c83282cc07d6cd0aa8d1c5758ba79462ddc323bc3bbb930373ef1c53b92ed2d96d4d238155532d1953410af79f3d08aa233e2fb256778a04dbdd925e7bdbc182a8858a15071189ed105aa6a222a7a4ffccd9aed35c4d7f7ba647273e2393025bcc927bc2fd289d1e434e8d15d038ecef09f44680b726df17fe0aab28e386d24fa7843e6fa06f472c82dfaca32d85fd582afd60ad817bfb11b3cae843c751e02776d66f8bf51a55acfa283bc6442d185512af1be7154b7a2da03abbd4a60c4127af50b915ec98859d5c684edf56b08cfe66418f2a5889f9b3a87aef425f6950fe98c14c6fe622d1d1c2bc47cfea2b721e97c8dbb1d9cb37577cd019545b71f0285121e51f77094251805dbd8d085ecfe8ccea6723dc062bb3fedf7c50593b0205922a540423bc8c3d5e42569bb2e7247ea76f0336bcbccbd1186dc9ce7482d03da45465c43bd0de56532970355c7ef777b177c7fe6a7532f317a18f136fde2224e443ab209e43f772d8074fdfea3b067c5381c65bb75025ee3f9dee77ce4dc03c743c2c27d44ef52d099e299389080c52600286711e9e1c734dcdebff96c9219ba0fc80d6ea186e6c29dc5c3191ebcddb75f9a6fa142abb71b0eb24ea3fb870d74ad181209cf52fb62d6a0b7c45d9f539812c01d85dee2e3de2131e9fc0e9e2df8e785877d96f7453353cd8e66536472753c38f34c924a11f9bcd3e1df5b24225211c57d2be13d95cd10a32f573bd85de9b70bda007117fd932d6670a44a0206cebe7808618526d6bc0230034e66ce9f7e8f7696a54be414b4caa9cd0855400c5b7787ab19599dffb8d491cab2af3858179c4829812ccfa8950148db8b0925224e70668ec89f91317e477701835166eeac74a894791d8eb76b1baaa550f11216c0fd4163f586a4e16ea766eeeda37ace01ec98c628056398c52e154fb4fa782f2af6aceeebd78d7f15b25ad97c9903deecb86333fab6be68bd8c9ff9facfe4214f0826fa40d3f55a50d102bcdcfa14680605bf36c2d142623c49239b8c22c31977245235b6d40d8c19937dd89007a42e79bc006ca2dbd5457f812fa1f32d9f1029f5a1a4d325d1518f606530e4b5d112c7fe4fd991d78467c24a0487c346a3258eb48dbc8290f47244f0dfd8152f2c2b6c12d1825bd4ef6c35da4a958ad6db192114ee30ab3d73821882eb27c746bd064c8d29a5f970c77faa3b11299f4bde099787744f327baf3422124943d9662f27c114be514e8c81cf618c21a009e2f82331c0ce3f8705e19f585abb4fd7adf1b9718854ad54a8bff4281e2dbeea99271874da9862988c3799ddd9031aaf478420767989fb32ad7577fa16523d27518e0a961ab41d2f1a80097e95d8c03919749c46f05967906ae8cc3ea5de2d4f25d8110ada472dc029c62964550f9ce1372c049f582e33fad78b81872c25d5e7c0521a3f7c7a4873e16b9def6fc5cb6b8bd7d918e64498de20f4de19f6d0c344e526175ab4d28c8c1f400c5b7b8cc871003b1d5cdcd40bb673a700a1edf8281ebc4a0e3721c6515c27adbc7da9925914ebab3eb9dae0cf2200cfbde8e446c38d7bb4295bcad28c370cbdd42eaac458f3ebe5cb7fa2ef98f984babcbfdf06f34b8f65091ee205e13701a1c2ea8a843f5c4b6efd809fcfabead21b10bde2d146aee526215a4fe1159a4d459d3e0016eaf546adab9cdf32bc4379606278bade85a725f7158a13d111c9446a19f6b0bce14bf1651b10bc0123a2a09faaf6919b112dddaa0a0ea3a4ecce723e76ff8831e4cd13d7424c4be81605104116740d58fb086a712e326db739292746d1985c1f9ae8899358e00d533a75efb5d7de1ad2742836322d49011ef90a17d991fcea02ac3274e6b2a9d8ac45e7227708a6ff1b1434586a11db76e8211ddca3020b2850fb31e09acc20b25a225d945840db8f189168aaed18b1ffa314189d1a899b0bde3931abf4178309c5e553cd375db69e22ba0131d8234633d63ff52a14b8ee82edebff56b20612aaa1828f1836d47cd48a889358a31c2ed3975a00706170f68e5c4fcf468d90ef43d57ea3f28b737ead30045fc1be2f085a00fca043219f011f86030f7f33ac46e1f9796a788f6b1c600c0cd7f74d21781ea6582c1001799f2d348f46f6a81f723560d7e920c1c8fcbda35d6dd4560fbcc1e3fe95963b4b591935b7506b55e309523f6ef0372aa53f6f6f39a8fced3033a3b0ff7bf32b9347d397c052d1114065d98e7a107ca39c1ebb71d52d79f101b2e9d8bfa85029b731263a28b39c9f0e9400d3dc6dc1c9328a022a74b704f2000bf3cb1c7232b14fed08b9c620894f038b79fa0dcd99081b21527561ef27b71531fbc148df29328c03a958ae4a00e803eac930ffcffab30209fff34b7d3f79102a1b45d43dee8dcff85bda9102cb809b22e2e10f32f6af247f3cd2b5db032c29d5334d06da44474e388dba32fef58f6f41b64ac8c0ec6cfcd4dc3e0f2673f92e5b3ff63c00f9d5296e18b42d1abd074dac590e7c6e16d339e714a8168fe9dc14582423af2f47b9078fea487c501377206684605bcb5724e6dc63c1e7822abb0855c33f180b5b20ebb2b40c27267d315c4c2bc75dd5cf4a2a5bceadea37ed78153883fb91a526e6f2a716b7139fe0b86b2a8900372f0172f3aaf9ee4a2019ff06e9f15dcfbba8dbb9dd9f3a28e9f54bfd43de7e0f8482a383ed5b608df6cbb6107cbdb223a442c91a27b79c4bebfab136990c609a006f94a4b4aa357bf3b4d70581cb1e022e7beb4fec5b5fb12d0c964ae273eb8ab4dbc0ca9e38768d621b831eb161ad789abe47c91993aafa4250b09fbac7fcb9f489d93a0be0cc4980ac561a170026532a309839237bfa1081eae9a778f6b16665de3237f00c8124fa1fd3253636290e6dbe6eeae74358d67aec6b012104749f53bd345b362b75ab3b549d088599bea97a0c7955ee2b01338bda7d05c5579e6822b583147e1d0958e70eee1b1d6559c7b4a21947d81d6d7f82d511133b9ce051588ce4a1a3e381ab5775ad0a93dbe6e14e6f4d040a4aacb7864a1468b61fde0d2aad5d57f75c6f9679afe9", + "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441124e9634ac86d5322a89fe272dd95ec8f0910e46f753f89c72c622ae351ae9ed00000000000000000000000000000000d50b7cdf578f4412a219947e71659c0f00000000000000000000000000000000585506e2fc08284102cd3ce553aa726a29012c2b59ed2e47dbf67687e99852bec5d63ca1680e3ad65cb5c747a9c37eb900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f17b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } }, "test_exit_code": { "crisp": 0, "folded_export": 0, - "enclave_contracts": 1 + "enclave_contracts": 0 } } diff --git a/circuits/benchmarks/results_secure/integration_summary.json b/circuits/benchmarks/results_secure/integration_summary.json index c0ad6e144d..2c13fd863b 100644 --- a/circuits/benchmarks/results_secure/integration_summary.json +++ b/circuits/benchmarks/results_secure/integration_summary.json @@ -8,114 +8,114 @@ "operation_timings": [ { "name": "CalculateDecryptionKey", - "avg_seconds": 0.599410291, + "avg_seconds": 0.614281708, "runs": 3, - "total_seconds": 1.798230875 + "total_seconds": 1.842845126 }, { "name": "CalculateDecryptionShare", - "avg_seconds": 2.123328597, + "avg_seconds": 2.121472944, "runs": 3, - "total_seconds": 6.369985792 + "total_seconds": 6.364418832 }, { "name": "CalculateThresholdDecryption", - "avg_seconds": 1.93815725, + "avg_seconds": 1.95707425, "runs": 1, - "total_seconds": 1.93815725 + "total_seconds": 1.95707425 }, { "name": "GenEsiSss", - "avg_seconds": 0.755760708, + "avg_seconds": 0.758238652, "runs": 3, - "total_seconds": 2.267282126 + "total_seconds": 2.274715957 }, { "name": "GenPkShareAndSkSss", - "avg_seconds": 1.230714874, + "avg_seconds": 1.242666944, "runs": 3, - "total_seconds": 3.692144624 + "total_seconds": 3.728000834 }, { "name": "ZkDecryptedSharesAggregation", - "avg_seconds": 18.895682083, + "avg_seconds": 18.979502958, "runs": 1, - "total_seconds": 18.895682083 + "total_seconds": 18.979502958 }, { "name": "ZkDecryptionAggregation", - "avg_seconds": 48.057542125, + "avg_seconds": 48.341644417, "runs": 1, - "total_seconds": 48.057542125 + "total_seconds": 48.341644417 }, { "name": "ZkDkgAggregation", - "avg_seconds": 20.904339167, + "avg_seconds": 20.006914333, "runs": 1, - "total_seconds": 20.904339167 + "total_seconds": 20.006914333 }, { "name": "ZkDkgShareDecryption", - "avg_seconds": 30.160204763, + "avg_seconds": 30.277848645, "runs": 6, - "total_seconds": 180.961228582 + "total_seconds": 181.667091874 }, { "name": "ZkNodeDkgFold", - "avg_seconds": 102.337581166, + "avg_seconds": 78.310650236, "runs": 3, - "total_seconds": 307.0127435 + "total_seconds": 234.931950708 }, { "name": "ZkPkAggregation", - "avg_seconds": 49.016015041, + "avg_seconds": 49.050973916, "runs": 1, - "total_seconds": 49.016015041 + "total_seconds": 49.050973916 }, { "name": "ZkPkBfv", - "avg_seconds": 3.839788277, + "avg_seconds": 3.850818819, "runs": 3, - "total_seconds": 11.519364833 + "total_seconds": 11.552456458 }, { "name": "ZkPkGeneration", - "avg_seconds": 65.134843083, + "avg_seconds": 66.056590278, "runs": 3, - "total_seconds": 195.40452925 + "total_seconds": 198.169770834 }, { "name": "ZkShareComputation", - "avg_seconds": 52.426543555, + "avg_seconds": 52.534038875, "runs": 6, - "total_seconds": 314.559261334 + "total_seconds": 315.204233251 }, { "name": "ZkShareEncryption", - "avg_seconds": 112.963847905, - "runs": 54, - "total_seconds": 6100.047786911 + "avg_seconds": 114.608395854, + "runs": 36, + "total_seconds": 4125.90225075 }, { "name": "ZkThresholdShareDecryption", - "avg_seconds": 244.367978902, + "avg_seconds": 251.230740403, "runs": 3, - "total_seconds": 733.103936707 + "total_seconds": 753.69222121 }, { "name": "ZkVerifyShareDecryptionProofs", - "avg_seconds": 0.092927916, + "avg_seconds": 0.093863888, "runs": 3, - "total_seconds": 0.27878375 + "total_seconds": 0.281591666 }, { "name": "ZkVerifyShareProofs", - "avg_seconds": 0.266464458, + "avg_seconds": 0.264344016, "runs": 5, - "total_seconds": 1.332322292 + "total_seconds": 1.321720083 } ], - "operation_timings_total_seconds": 7997.159336242, + "operation_timings_total_seconds": 5975.269377457, "timings_seconds": [ { "label": "Starting trbfv actor test", @@ -123,49 +123,49 @@ }, { "label": "Setup completed", - "seconds": 3.274390084 + "seconds": 3.273315 }, { "label": "Committee Setup Completed", - "seconds": 20.259594916 + "seconds": 20.279577333 }, { "label": "Committee Finalization Complete", - "seconds": 0.005869333 + "seconds": 0.007173125 }, { "label": "ThresholdShares -> PublicKeyAggregated", - "seconds": 7204.022842209 + "seconds": 5158.12970425 }, { "label": "E3Request -> PublicKeyAggregated", - "seconds": 7211.068496417 + "seconds": 5165.210807791 }, { "label": "Application CT Gen", - "seconds": 7.746761542 + "seconds": 7.707659625 }, { "label": "Running FHE Application", - "seconds": 0.088362083 + "seconds": 0.0710595 }, { "label": "Ciphertext published -> PlaintextAggregated", - "seconds": 814.168040875 + "seconds": 835.140242834 }, { "label": "Entire Test", - "seconds": 8056.619484583 + "seconds": 6031.697821958 } ], "folded_artifacts": { "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000830d9d4344316b026000000000000000000000000000000000000000000000001d383081c39dbc5a000000000000000000000000000000000000000000000000ac70e435f22d64fb500000000000000000000000000000000000000000000000000005bbc150f125200000000000000000000000000000000000000000000000a8a546866290bb770000000000000000000000000000000000000000000000001fd3f2400d703cfb700000000000000000000000000000000000000000000000b9038d2ae3e79290b0000000000000000000000000000000000000000000000000001e3d48d51e5500000000000000000000000000000000000000000000000067a0471dd42faa6b0000000000000000000000000000000000000000000000000e9084f4ea2d5e512000000000000000000000000000000000000000000000008a356e94c183365dc000000000000000000000000000000000000000000000000000254af5f427efd00000000000000000000000000000000000000000000000238e18ad2a5a9480f00000000000000000000000000000000000000000000000bd3b65543dd7dc02f00000000000000000000000000000000000000000000000759321a99ec5a19300000000000000000000000000000000000000000000000000002a525effa8d9000ee44df0d016c13539e3e1de25cb3283bfa0110644e6c3060b51acf455c43f02d5202ac66917f20fae1a39f8cf51134df47884f67caecca680f87bdfdd85ccf0315bef50348a88d4c79a1b50bdc50c9882a2946c73cf72c563058759727f8a009db15cdba20a346d9491fdfdff4ddaf05c2474d9c1f2c4821a5e2e101b7b8e82e181958e78629f078e836c725ba08236958e3445a0dc31fc4c2202707b61c7d0ac53aa35319f776db882a6acee6b04a492720c30b527f6a209efbfb4b22975403a5568ec8e19525b52dfe82dfd9aaab141462570f5c39f9a42f13700ff87603118b076682b92bee70ee8f9b972b8cdeb9ff1fbd603352f945f2c95fd35184f70f989616eff536ee31d0349dc97067aa11f2ab4c8782c4d19a4b89968e13f69f208509774cc987cc232b93c9c49974be00e3ee21c6d743b80d823f9eb1ee13be236cf0e7b7aa0a5a5f4207edc057a37096d17a63c48f2866132c681a904108c02045139ff715913e4d22a696f788d1cb2424d855ef9bfe36f67721de67235cab0e4f4cce9ff0f3588aca137e0740c7dac2a980816ddc38f10be0dd37f01028891d4476773d637a1bee280492d73d68838af602126de7b85d767e835f1ec2f5f7015609620fb34c0980312b5b7f67ba6ad756f683152cd1a95e9e4c9a8fd58bbd1c0b2d262ca7d1cfbfc729424917aa0bccc6e667b7d4e4293e56552cb688b8320ec6d51d706a3d0b516eeac14f7b49e736cb687e82d64d239005709ea7a22af41daaba74d8165e869cf52616a224d38bf14b43f9365e25bdb8f5e3088158cc3e2ec485c6affc47a2b1a4a1d0b691d81aa7efeb0d4f243c3f9862a9b376e7648a2a1f40a23824acd2860b8fd4464a89ad9da06c090a2dc69564011c9749dde2ed15a551e0c27cb57298106bdf016afc08b87f0ac06032ee6860c10be94821fde507c4f9ccbfd67261a4729466f98ee1db61592af1fc7b39e2181034e27abc492409e069c23c577f4749acd5236e349f1c92837155ab5553d1ce276d8aba649f661e4ae3dcd8f73ba139ca807d90d6dec1a9b860762731186ba09357343823fd671a0a8440d758f2714b07ce0b6d8ee3e072af2f999efd2b2f4bd29a0b7e4ee2fb03969abdb773917cdfc033166bdd42ee8c0f0de8fdc1f0b959ffd56c806c06ea1137b28ee248c3176911c6a89f3ac4fbe9294fd2c25740790a660a831c1fb96109efa0ff705b5c893a9243584fbbbef285f05ca9370a3a352ff33e3fbb4ce74222a57e9df2068cf76844517674c6e6a188fa7158768ee6fb34da4c185fb830a8030b0eff418ff974072732b830d30df3199387ea05c52692283f7bcce83b46392ff77a2391ee371a20d92c00b3e9ce77fdd50918e3ca550e914a7a53ee6f8b7709d5a71495d8ed3e4500f7d429da6dc0ce8b1e10e8153d28ed7b0454f33cecd924540395148ae0936911fd4c376a78890ebe5d7fb220351c257b7bd4569d752023276726c1d48dc36a0147a3db2a69a24b00b54e87d42177e95503de125797ab2420f3fa31bbd5c0e70f3038b55ad7e40fbd4380e86fdc7fe89164eb0aacd59012dfde37496f6116d41ff33c74efb86de3dfa2d24cefc0b63c89d79e133cc29905efb2920c4f7da9c8b961871dd18fd44999a25e5dcccc9ccab601a2e675373e100c397861eb058b5755e03a51eae9d52c2e4d4995ae4ca18e4dc2233d7d7aef09e64d43b4813625ee86b3dde7f88897786e1416eddb163c124b159785245e69114691c2e2133c527da43f96a3ce84e6dd4ca5565323c6c315ad829d67ffe1c404621eb8bf726f2e29a09c7859bed166cb8ba83b62b89937330ba87944cfa8ca0ca6890ea5b94cf33b92150635f7eaaa4f6ba748de2c1511f5951f64b2020cc62dd083cfc17c88a46303505006aba555321be0a57109e342280647134ce385c5299579a2c5323a9de3f476deb15b2bef26ae534a4cc8ef85736d2e278da053c606e1876d5599770ec050ca34a7586b97509498768869afbcce36fa99b3bea7e2190eff69b5e545803434ea8ad62014852a371430a727701311a6f04fa47cb2cd08ca37d24e1311f454ce5d64f1be459f3f63bd3c2c5d2d8b894886deb7403c1915a57f7b0dc00c079803ca7502bfe4818087b1bee5e5ef561924cb46df8ee9af2f4791d0d4821ba79925efd25af9808cbb8277cd45e6c8b1c435290fc3a81816113cd7b0348fa54da05b8a621dc0216d78be0a5d5e1a910fdc581e4d05f27a011ecc21fad91def43ccce7539527630fe9efe81a8af34587cb9fee87f922e63d01377a702022f407844e60f563192d097fc190d4b9423e4e7b237edbe025c47b910c6da28d26c5f25a5025265d2a204a519b833f8e64d2a3a4c0f00c1c39ce69e1d0b89313a4d0a35ddcdf13ffeaf15535473b98771e39baf7e4aa6f927264e6119206d1b024b808af816db984825a1ab0c4ec9df14120dbabdcdf4b0bb4445ac022d4f53f6757cec1a02719b166bc272aa26fd3d5a19f053e13fbd00b5d67ada109d29051cd5ec728a99bc53a016164989493cef0a3fcd26825ad0673bf2fd9a17788433a5a33f5dfa3d26c5afbc72d8154c7ef45b0321decf426bc6f37e7b0e0493ee9e522db3775ec83b6d4c69585fa5023553e5d477f6e1ac2a80b4f0477a0f18b2c4014e7596d55b3e6cc268d4b3f0d265cf823feb97355ad804bb1510c5021956e6865c693615eccaa18c8dfd10fd643ae26d30bd4fd07af6309c8385af2ae91ffade4e050bb2a85681ec5eee4e55168bf626743731018ec69c8ff8574700456dc0c1b55946cfd78d2350072c21be9d3081f24bb64349c2dd8f63fee8440c5a2c18c8332898034b2f6b5c774f71d8a436168330e2a43d1501d35bf7264307009ae8c13c7f98a61e2b6294ebd04b54eb61cd67c868e5a70b247a82c56b5000773850ad4fec37329ce608029bf0091939a6a1b6b9f426f2042c0717b61dae1a416763e0be43ca69a9f855685aa38ca1de9230cc19b7a4defaa050052549512770183df9e2acc5a1723ce3d73b96b32c41adfafe5cee370a1e678fa79ea3722461dfd9aeb45139569f0e6f7a3c3d7f60013fa59ec8b7345fa311351a12d2140d8e6ed91a51176926a8dba35e2c65d4ac7320103427b36f20f3411ba8f04ee614427ff6b94415c230ed5f49545dd15a4e1df3fed50437b81ddfac5cf1165e6116e3e7fec6439f5f56494929c6fa96e7e6a49d999026d174126e0deb9eb11aa01cd1e0dca8ffee2d57bbb6a22e1393f6ebd5392244b30634971e9f38de5aa999134af1bc04a03e028bd552b71f42a2b798e649db9214c69412e408467037b7de1f4fd334f1c9f9c7bf1050182d4cb55bfa65f679a1c01e10cce60b0ba019b0a7211b9f3e4e5cf04297d83eeb51a0d4582534a00decceea4c163271f2696053e8164d2dad9506d5bfcb921ae50e0d91b96b81d4c3a805116e90e9c4f6becf24e42fa10833dbf0f0713f1b46fe67f689ec0b3d6e6ae54838dc2b20549c9fead4f317fa104e25740c58fa1089a411c6fe1140e07cd5e859dc3f4b10cad565cd35c21eb743d7d066b0216ef1222ed15d5d2b19901623f0ed9ade841181ef7384ed412f47fbb67ab1620be7c439652920a57f0e24e0489622a90ba284b0f15d8708f105dd4dbc8cedd61f619f19696f3d65d947ac5a37117e42234a0b1ac09891a97d2045fe954f13a507dc665b6f4dc1af44dca049b48f50601239d54963830057c21fea7fbc790dba2a482930e983d06cf20e52f841048ea23fd9becae3c6c56dea16d3627053072fd2eb637138bb5af7f1574e5ea375e8d147294672d93b1ab92a2e625c96a55982d59f2908793089c5d675fb63e56ccdcd0872735cc0c45351970c34f093e20663390986b19081d84681c360a40344a48044e228a23139c07de62bc0d25c0f844edddb2e17b82340e9d73f228772ee64c59f9746aa416f1405860bc6bfd996c2e61c9bc823024de7bdf863bc5133fd6ab0805c4c88ebbd3fcbb12d0f7308c4c486a20860283e6e2320e198f6a2d085cc8980e26f2e51a550933928e561229bfb72912cc955aabeea11b030d1c17551eccda5bb5f5bff83fbbd5013563d0f8a86a2d65ad84d5c95ce6c5a2b656b3b578b73f21d02ba88fe8a9d712e2afeeb9d7e0eb9c1a541f91ade3049ca1f51897a474235342a9a6f88fb499428e9770a22b2dd768a096dc5616a65630e49d6805da5c884ae7e0312ccf8feec24843bd69da995e08aeebb8e5a4c54b61d70edb1c5e62db5e3ff429ae5cafff81dd26c2cb92f24909acd104662f7d74d54466c57386cb437cda86fdbfa342f3011ac3251f702fb97585a11f54408b29243d4eae98f77a096a0ea94e624d152b8267e3d7dfeac3d7df0e8224a2f2d99102031ad8a74dfd347c88c55de823733b90632ec5a50f12be845c37ae121d1b0d662cf8961ca1227bef498feb4928655861f5672914a9fb0b568580a74142716cd5ebb0ce51c1c8d072f6dd5c981ca3ed106bef9c00c32e0246166d0d789aec5041f57d670fb2f0fbb4aa87335a7ef7a512cd1a8bb26b2d343de10f1b05957a69cb3e99e955b9aec21c4fbf7a4b5453c421bc106f05c610f438528f8e733d48e402f42600c1ae3b74318c41b722dd5cc6925154ed14a9928b5a96e2e4b4efe986e226c755e98e61ea76ec944eb78a3d69201231ee7b8063640dd0cd244ae2e598bded49282ed4d79c0f890c098432a534708246110b4e213240c5bf0026fd920a4bb45e2c574295ba581b644d13d762cfd0d43d638af1e48c7e08246e03fed8b6dc6c09ab358b627fc13faff5add1d19751abbdb7ea60b18e3f2b102fc3d30167795ea71badf50e36e7ae300dbcabd1216048274a5622365a76c5e7a50d353fb8e9a1094f8deb532f930fea082eeb6a4b31c1bb329608eefae298673490756fa62d97ca75d15f4441f1e6018de13991f3816bc02756edccbeaf4300ebffada8d6b6c943cae931a17f6a89a5e2b232117c0075f297211fe6a9cfdd0a4f32127175b900f81e70ef7e79e1d1e51e7afebd95a0c91f87a48820ad1236710841d0f4cad093f3173a2d3060d59d33d2de467f0072a5a51e107eb89a2b8dc2ecd12d77db3ec7513ac16154c2f1ce91861514e615724f19f85a4c2c2b99629eff7eb549565ad3f5217d6ed6b00eb83c75e170215ea04b957bb50d43308a0e5993d64b0341182bf7e615835b8a971f1d37d18630b46287d062a775a49374c26263f01e4062cfdc3b934fd8c22029a3d44d0760c116a242d2751cff8a77d499e4b9ba267e85143e5f1a59195d98cc13ff0a4fb3ad7c90907b712c497a116fc6f365a7f4f4285f7f5926487491a9cbed80268203b5e53074c7c275265fea6cbd5555f42dc8f8f45122a9f1a64120f0ed5f2243f410041026d88d6e4179b61e5d74d705240cd0d43730cf5cd444824aa68219d38dce9192f1023376a1d43ccf70c0b7382b4253eecb6aa387b83120cdfe6d02788ae70b3303be8647e4498ca34cae02c5fff879a7d4106c8ece7153abc8db46c12dcb49a23c6dd66ef69852617850c188eb1e9f6051bf69841624f9b98c909b54559b1e42f85ee41dfc9ad92b00495f0fcad184d54f6b3d5bc239541e0a4a1b13750efd50ea8779427d2fcc35a52cf61a4786f9ed6f69c9c842dbb60436c1c8fe999c51e2ace7522b27e4b3b8caff8e1a4ee75455e869e24333e541db868e616d6bcc60720e529e44071d6f59aabbc1921a7a28a662cf5756a53fa23bf56fec80b6ed6b90a65fc7af3019b9a937f10a38e6e9f505a5560cd594fa6c42b52db56befdb9160be7f0de83d3abcab2d9efddec09d43cb6da76a733ffc61bf9db3281f3bb6c3a27bcb2167b53f38d25f1e1b85e1a55f53dbaa39ed09dd99da47dc62ac3e8676d2179043618a209e0cf54b7c1d85281897b86b7fc4d2a03faf6272d30339c9d2029841ba7c096a9f52c3ffd13d354f06ca15bc394b99de23492f7da1757e3769419ed503135e7736210e1f37ddc3bcfb9b7627354bd38b55f3f3d326f2e8a761a17da2abd212372bfc5fe8f07033d8bda07733512982a3092153286ef6f95e4df1cf934d31d0566f00c1b1f1186bb66a3b3083c285f7c08b21eee1d2733784d442063bd18b682dd4e90921766318cb642e3789a1cc4a6a191643c49a9b5be21fa004f66731f08c82f2d433f0ea3a5ce0d4fa2ebe5ece4545d4bf75eef7387c3622006f028a52b5bdafd3a058c16068a4d331df9ad12888e64e8b52b12a514c0e51dc2c154263d1399b3108002ff047d94c86256d801891f8c3d0cac48d7d5503f2bb7074d74e23b2bc7056963f5897a95d9dc32006c6a259166474287b15063b900bc8f035a99d7cf793ef4d706050388921536d3b3bac47fdff272b1f34f94800f0b6de358640c1f7f50cd197faaea1afa3dd005abe027f5406a1d43b4fa753e1bf29ad3b1ddb946fc5ad5aab9c781f13a9bd7fbb4024fc769271c1617b160b62821f77d6b20c09b826540204521241540181ff1156eba68f62c3807d74fb6b82a26ed573505f10bbe1afabf79d4d85accfdde58bacf25838f0fa93d87c276d72f7af912395093ae881e3be578d3dfde5675a7df316907ef4e349b8e0c493c481c7a29583b0eaa6ef46c964cc64dac3aad7c065a79ba92687ce0a98ee8cdb6361a14fce6daec621048466b4a6bbff5176467f07e6a2b69d5a59ce0127c77c05912d44efb3fa2a2d643dd0631c0c420303970e67d144185aab38122ee4d89a180002c26533406e07c05fbbfbbb148d6212908b6368226ea7c7d5b3e839910389e0099bc3354cb8d84d8a9effe2cd41ef669540fa409d96d787b622cbb530f643b09aab6a03e9b83f0a22202c68286417e48731d44a2eb367308d472ab2d860c8803db08bfa695f3f2930a8c664374b927c41dcc3c9c2fcf71e1c3efb95fd866102947e9746b2cf78aa01b14cb5db1b082a352f58fa64c4506028b405e82ed6ebd0826c6541fa085bc93ac86d87386c2042f07b045d93f017366d6c1d93ebcedd014e278d3835050677c5d46e7378734d23c51e67f1fcaebaf567698e4eda0f70e15dd2e99d51ae126ad71067d10cab934a9f0d0f88b6b004e1e1e1092b7cd460f1a170e7efb388dd92ff079c964f5f0191a51b99ba304b159294220629427c66322d192e3cb8014a8e42c965e9f09703949fda898bf106f70e3200faaae85c86e10f790ade8f2875364d93992679319355f0415beb31b498a59f932bcabf37de62a6e3e2cc8ead181b76d7f2f81c89665e5991486881ed6e85957f55d87c4de2f0bb2af449984fad5b85aa1fc465a345e5c098635d36cd5df525866c9925158c120366487c32261f99551943f7bd9b828fd0f805c91af36923afb9a1035a976cf29d7efe8355bfc2823d0d9d26252bcf99df9af15ffa66a2a57d675b8cf6494e20615cc6f195c46ac770f1fe2cbb8f966071ea08c126a5993126a291ee908a96a2214f44d6e3bab7a1f8cc9a535d86930423ab2be7b7f50ab026ae178a7464df6002c08e6f95f946dec9d918fa7c701979e5e7277efd92c2e0391bbcdfba23e102c2d4162f5812fac7806769430c50cf13d041229d170f339e9fb0765ea57b5a90afcb342c8d26ea08634abbcfae382a9292252b2722c90071257e8b6a3542a7d1b202c88abbb094b7a2f6be1d22ea647347d0f43ab767873da3d12382713ae0b132942d7950c80d15ea5a933684f30593ed3517517987dcf7b800fb8eb8dc64b07bc25686cc77bfc09b2d71f441bcff96a0a7c7bb947c6079080f694243530d600844e32e68804d47077fed9246ee42860b7d03ba6cccb59b539553e212fad1304214624e71fa2f1496d36e6ace06ace6f520af8bc12fa6907234b65d64d3a81300ed8c5074835551bc7cbbef0b6dec93fa8eac69ceb2b6fa787ed2b21cd15851840cbc48395ffe7276e88100c327fbf0d4b7ca7d9e7a4a1f17ad4e214a4fac82a7bab24a3c7a0e15438197bad66ca888729446d342811f1aa9a76c4452531e605e7fe0f6cf94dfd74cc7bec4fdcca0269fe0f2356608838073b1a2bcbb0bd130f19d0156490dc9d40165ca992696c5108931f1a0735fcb95193f56f5af1c4a70125c502bd7355b66681cb150761c244f8f1c12b1700a4aa873545c8d44f1dbd2c27884cbc54e96cd0cb82a908f5cb4f98ca4848fd7d6607c7c376fa5fbaf5b80634c59c38c194fa0c158398b64ef453fa5d1d0eecd13fb4c47d1452ed75bebf1874785457afda78924f0f4f191a26da477702053e6b4ea9a9158aeb8be5cba01eed0bea52ba039d30db1021cf35d604bafe3e53e81d7d7a2f54cdcb1a07a1de113f1b5a613d9e4b57b599353128a4e4fd25b865767590ed535d0f8b64a5ba6f1b2ccd91bb5128694deb43752b489f8ef72aa7850b83c921f56b27dcbcd801d8293d9bd61050e6ac52b47d25c4ba3eb7c3268719971b9c5f6b6285e7de73ab861c8a071a0b61d854c12f15e8bccbdb3948f41330dab8f1e1b46401fe630cd9590cbeedb644bca3ab31753ce8759476832ed9eb828375fa41106cbb8812a4ab3f2d2917d97686724f15012e3aa224edbfa79b5703723b9f1da9d8f298e7a424e717c15f97c6bf2975729f8056bec981a39d6c055d27c0b46166a6ada05e93d96d21e8b83dd54e3cb2488d3e4750dc0cc64a5a3f5ecd99eb8598c57f36b698f19105f585c424c2f0c2a8bdb04498b691ae1c26302705c2fcdbb7ac34181f65900108f4a30fa53778b73db14e6d881314fee1b43d119dc7500b68eff4b24650bb7510e8c3728a3ca4e710c32347395b4b203884db0191c4ee2039e21aed587ec1760ca67d37030c26656ebac257d53dd24515d20dd84a5ef465978759d706139a0c259dd389daef6ffa3c56f3052ba2da2a49996bd9e3ceebb79d7338319a51569811ea7cdd52331d67c99185bcad199e61682a180a6f16c021229de73dee8e9eae0e057f1a75896831b980d2376c6baa22430d90781298cd2c76a3f5a5832360d30c6d8c121ced3ea63e682940893df32891a0f20fe3771ac18e8895421c624da426b14707eea022d5814f3d774ecc970a9b1ff47bae53a335b230c2f29334f279215860b96d5c4e332dc5d521628505256bc95ffcaf7e6af856188f82b31088981c8aa702e18474e5df8f3ecac017929b8ac9a6a8f475ddd59c408014b4c8129001e5d9a9a60c8c13482d0837da1dd4b39c69b31f0d514838b6fae82c89e06c572d35b1b48563839c0992ce91307b4d837ed609baf6afb38d48e7972b8b5b99f91fdeca4c830613e7f9b72bd083efe820181fc523820f15ed63fb0822b9230c570859aab904fd73648275e5373ff1af6f61712b1c54db6d978406694e9b6038650f79671116f91705532e3dc721ae876dfb1bd00480f5eb58caac1171e79fc9652aa650cf76380bb290d6cd3732a2d080cc997d2da545fde1027339d4646c4dec09214ce863c782bd94e0a31b28b4752f7941d3a92401bfa4e37d81c61fe0f75e02162aaa21eb2c66e4dcfa0bef894309aebf66b8962fa9e8afaeafba81a283d0125ca9f4cfef741def31d6098c96fbe5bcb15fdaf3385c768f2f8cfc183ef6662a46f7b706b2bea3d914c8e070012297473589bf3e9669b9b4767073c80f7a7626f3ca968a920ce519da4e4f48f62a480065c015d4865430ca207d6582947f7403bc218272d157440faaa13a39e22f45866cad2e2dfdd09b7f7a79b1b21e0dfc0bc45b781f6950f78d4631281d285180ddc7579f12d53da5254468947f88c64d2404ca4392d6b9483901ca83f488b0eb99c6d9e61855f940e349618bb4cdda120cb9fdabf9a482fe39eabdaa2b4f8698a1085a949dc6ee0fc4da4baeb3270e7a153fc2f4912de3780b345be03f1e15bb753897c2a0c7b00b7e6a618c7b3c20e10439bcc07d2377b5dc924375ced34e7d7cc8ba6a0d1fa6697a457dc6e612bccd0964a3ac2316c29aecd74957ea9bcb5f4a70a655a1999fafbd95380d763c261813f0c6ded6f4acdb425e3047a64f187e195afb7aa9399bd775e29d3578af140b224bc801d54c95d3790079c8393ed98a7bc3e5acad2cbea47887b0163c1544a40966e04884b239de2dac9e8aeed580e5f956f8a8e1fb671e75d34e5fbf0054ad0a974b331ccbb54c8e8585d5eb41a5ce017860bb71135724903392d6b2f0017819c9ff87ff6948eba679e1bc202394505e6d368ee5be6dd25b4439c7f75a96501ee54142e584831644a3e8241064c3eed654b6207aad54cd6d499674b43450d811025dac2d3557cb347773d2bd3295ee079df0f1b3efc2fa0a9d82cd1ed20bde2bd6e34585718101ac22e513c10675f3aa2f9bac70f9f870566b54d8ce8a3efd2b60b63b6b6e16f8dd1c78424aef184ffff1a53ad572390d8edd42e12c6e5e9d01c2c362010c018763f2154e1c0a5a03fa54832572603c918595c280962a7d2c01d9259c30854eae881636f2256369627f6f380217b7aa0801cb8f5d486fff811a30fbd4048a0c81d9560ad1462dc5981aa2d8e1fa9c90f2de629b8503a127900b2fa796825e2c150ac4fd3bd7d195cb67af638e3c488b981e0312ca79e038041e241d9cf8886003759b85cd3c669ae378e8ba9422ffc09858b4f2176bd9d5b722c3f11e8c8f7cb8a3d231024e60f79258315938b9f8ab8974c1f0221e8571e00c98ddbea1a84f571064b2477455777ffd10e902a33dccf434232a62c946e557076ff7bc613e5111167319e1b3d2234b3da40a8b4d49e00b4a5d23d953bf2fce089f706c73c7b0e82c212743ece53b7c96cbd5445865fe705539dc7dd0ef0fb60fc255d83f113467e1d8eb4da93dad481732cbe0d4b4a9769deaa83b6abbfc84149e3502435b22304a721cea21100cad0220b078d0f93800b8032d73e592f88e2e3aeda6320f26cd7c4ef4299193396343c12bdbbd9a87cb52b18f2e08027716008ccf50ef396033799f9fffbe9d32766e7d9d3f4d32e6ea7ccb08cec6f2d97227954aef0752083f3ca2d5dc02994622d1e06dfdc7f043b4e947b6ce3e217b7d27b0d8db69361d9a78937e99143d81fc0990dc4dc46583f3cf73db704c2cca2927400622e6bda6427adaa4183ce35abcc598c5526a69e26a3c6dc4af36eb6c160ab48cc09ca6961d808bec4d6084741b1b2f33534553e7d24f630f0bb640c118062730001bebb4e5702ce2fa779104caaa107e1f1899fec2374a7f27764f7ede21a5e12cdb37b4ca76b6951212562a105f92a315b950d8f434ff416b1b9a1b2422542f057fe7d51597880e645ab1714fc229f68002b3d1e269ceeb32969b353e11ac49ca87ea7f88875de12309ddfe3f6cf4501522e68ecc199db40b4001867c123a1e6a293a691d8151ad766f0130fa0bd970aae5ac366b886257423afdd0761a28cd4a57083ebc02a3dabd01693859a12b9cacda074fbe5ccd2ab834b15d65093c17d5ee31d0c180f8c74b42e91330ff9a9de6c39f23c4e7533fb63f284c63304f216f7c4ae3f54a9c627b8d0c4630fa6bfdd917830ed5d3c0235a6e418692237fdcdeb42e7ed028fd7f95aca773bd7573c654e6856604ee0d9d7fa25f6cc91b0021a21d95c9e2ed43c38e92cc99d0858f791f33c7c4096b4073a50a605af92e9a31efb3fa1054ae2b053573c05cf80189cf9cb1eeaa65561a54f721df77ee2ddf01652c0435eb7597ea08e0664181b3f679113845f0e03ed829431541f05d203def0f84f22abe9fec00c6052b290ecd0db4797466aff18461037e202ee54806e756fbd0e3076fbdfc66fe4193483139f60f235dc8f5cddfe98439288a7753155bd0112d2d9810e489a5d98f38170d50ef95978af50b478fcc04ecc50779f40050c9dd0f00897baf1d4d1b06c9aac43016048cfffa660bab245fdada960e4f041af6a74318a9dfea942ab43a0f96759c9202cfac134071297e13a8d2f85ef508175c4f36719cc2a3a4d21955a3402abaf3320f83fede6a173c7414b5883a8f13d47610689ec9fc2ee58b124fa5bf5a35545d41457c16b009cd2a3eb7e109f71ebc8c881ab00c42acab3415b19b798ebc498b1c3082f4569d01e3de6a0508cf2ba3949cf042821c3acf2cb6db150a88b36f7ba6684d39fbfcda0e807dac34871ae08b9eac0b61e5a37433aced9f98b6561b794309d4baa95ded5888f022a8eb1d9f79b2d8e5956fbf4990d68c906bd82638d806a842a601783e4d4597765a60252c2c6119bd618c2ba6d69d08fd192f4a3fd2c3b4c7f010d53cd6e2a7423ad008ec05208111a54223a5273410057b8981019bf1811b991bcc366049469605b42fd28cd0b86bde221037d2b8fd45cb0c9b27e48386a963a84f61dcc58440ca032597de6c3507f1e648311c5525fd00378d3432955cfdf7eb87fd3832624d912a2696d383a5f0090b5ae652a07570818d0455a505c3655c003e79ed841cd1a02119556b5f142928ab98a491ca0b486300c0e126bf9308797faf4d6d4f096c8fed301fa9aff821908059e36c2a2ff6e783796e33140ff21e46a3e19320a162c0a80b574fa11c5610721789046457a8e122dbbc31f9db8e9d60eea6fdb78fb62e002942999bb7ee575ebf42514a77595e1177199575464f7cc47e535f0d0c564a3a1b2e5e37b1d9f7eb0404df692657f7d4d5aa7ac1418d3bb1c0055afda07e6b1e1b6bc8f49f0e6255250aec766ba36d26c78a34c64c379689c4bc13302fc0a2e90923bf1e1915ed0ca385aba72da2f48566569f21a88069fa4600df845309ef7b137e09f44bc8215c0b31d1191797b2a789fcdc460bdce0b58eef3ec23e7f46ee09257488dd2f164e17a31fed823468e23e7791d0897daf3f937ffe7d05bb55511e1c417c6f2fb6fceea5ebfcd854a23ab5ca8fdc7c04908d8b81e436207dbb1f18da479741bd2883269c262a870a23bfc99ca1a714ddcdb769d695aa747bf726173a91cf40d052149374a8809cb89c2ccc1751c07e2b2bc4e286774bbfe4b1712d38e2106b4546a9af90a3008d709994d0adaee76450273eb6715ccb2ed12824070533ab886efef8291c861e327d1198221667f380dd075a86fcd21d5f7c3ff7032d213496e23fc2845413df185d31f73a6198904c94ddccb0fefa0f250b599b0223370e91052e2b4b71b6133793f6f6c9a5f313efb18f2e88001e561b480c7f128af589420a68ab0dabbf4118cad6fe88586d6759c1395cb199cf6590a1d4fd052eb2aab72f8746d2147262fc3c1a64235a45ae1d171c31a917208adc36b84013fe1e6b33fdad0187aaee03b96a3626e4d5006bb0ffcc91d1d57239ce89461e0570641c01456e1c92e19a0054d9c812de26ed8cefee8f1e29903867aca772a11cabe48a842659044e170f37774282a95dca132c110aacc8354be42019156dd92a790c670bcf81ab066867a237e984e6e51b28f0b9be32323a1b76eef7d25c4d0e2079053cbc8ba35f2b1823b437a526f482d892c240f8e8258eb73f29d77f700fa00cfa645e659a661969d96c5d93a03239997e24f2a3d551f74804e235bbc12117b470959358f27fc14086c9d9494b8f6074e98cf99ba4d98607f8054e01c30dd270176d233a81f079282ac2d90d61e6278c0bc08fbff1914b49e432e0039b2b9d3af036e3554540363571f6cf94384af6a31647e2416da794a816dcca9e930ddff997ba2d5d6ca43b8b27ce0e5ef64097365087bba89d904ed998f250f93f134d50ffec261e5d928b0e7ea27594f54febe371db232923a7dd799d8de591cf005909f50abfb4f11d0af2edb4899ca7bd57cf2ab1b8172af3d1cdb4b32072121ba1274c502ba63577953f92f9dd4f715fa87411d6501435ef42d64c3b9941c11c5104477a3a7c216138f889ebe0cbe7ad8687c9cc998c83a0a5d64cd37b08a80411ea0f65a76c75969c095f9103dc1d950454549f95eb2b4139617dcb0c7d9e21ff3f9786b19ff2456a4c77191118917a82179807d42e4b6a03ea7ccc6ce3462f124adb34301fe90c49423e41e8a0f135b76d6653a107f8f91c9d8a3fe14874283fd2c7d4173367a0a729b8c378f396ee73c3310dd807b80a12c3e1f50e76bc235179e6eade026a5b94aeee06760fe269c187c0ca04cd22f8a6933f617ef55221d07bbd98ac54cd8d7e4b63980dadb35296060af0bab5cc9969a7042cf6c8b0000ddd081697143999fb6c1e12bc4134602fdae6180e5a69a1b54d203a0e086b272e29940a796957ac570af02ccaf8e1cbd94013607d2f7bd4be7c466986d14d15b90f5f649d3da06cf9a2d20d684075971fc6589466ec9560f78f95d63af4500e621998656153ca8ba44402b31b19cf7eb932adafb783547e2e019e152fe3361b7e76c63017866dd5eeee8c7ee7c569a1dee58a78b8c3ccb250600c9aab1cd706a210f1d7c892ccf6b68f6dc42c86f8993a9634952c4c9cc3ee0184a64a28a60afcd2605a76a47a34885bf7cb398e70dfba201aff2221f55345464ec01bb36a2ca81d2a0e0e09280964d5c06671235fb5d3976aa2c31f8bc74c0e3f6f9fba500e7650be7a2791e8f7bc78c1033f6e3e829af8f5664e7703f0b48ad9d3e1de8a15f7812ec86a5d13fd88077241559c19a4cc7c174741c6f091405081a809562b1d7b74b4b4c7fe9d36b5d542c28135a6072ffc5ca0d746fb98588ad7d35df9e618b80609be85aec7266ff9bcca42c3714c9f9f2724fef38f698e63d3139c29a6", - "public_inputs_hex": "0x1d420eaa08a65528f470fd3e2a802913b611527f41fca008a0ad4e97475078032a555ccad424037773cae7569cd26f46467d9bd96c32334af741c911096761830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000022197e95de61c6c2844727c848aa819fe89bff180954ba01135f7e3d285aa3d8e240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f2a318f2fc85748ea90c49625631654288c77791d8dd0792e201c748ca9863ac417b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e2bad40c7a2fc975f2e4811607e4d5fb72361dd1af1bb2364be799270aab5c6f623db21355d312ad82ff6334e39518d7aec226005c56d124daf506a44749cf370" + "proof_hex": "0x00000000000000000000000000000000000000000000000821730b5f6c7306ca00000000000000000000000000000000000000000000000027d5a4288c59517c0000000000000000000000000000000000000000000000061a32d74244b4e4cd0000000000000000000000000000000000000000000000000002752ab748caed000000000000000000000000000000000000000000000005a4f0140d4a1c7f7300000000000000000000000000000000000000000000000512ac80c5fa266d0800000000000000000000000000000000000000000000000d400822869689e0ec0000000000000000000000000000000000000000000000000000a3ecc527c1e200000000000000000000000000000000000000000000000564b7881fe1989f5500000000000000000000000000000000000000000000000674ecde0680d8bf4900000000000000000000000000000000000000000000000584cd67f303aef6c30000000000000000000000000000000000000000000000000000623ff53a7e1000000000000000000000000000000000000000000000000b27d89433be674a5400000000000000000000000000000000000000000000000d03b476bc4cac62c900000000000000000000000000000000000000000000000d562dd63dce28dce600000000000000000000000000000000000000000000000000007014317d4d7c2bdca3a8f64dcf8eb8b35863e69e18fd4f152ed73eba57c25990e80b7c74b79013d6c8d4d7310cd110d6e43bb18fc56336d2e4da3740b50e8523d5f9594bcdd812036507369a09143ca35760ebd0173b2c22e17b4dc2980119e4fbf1ed9cf2a9021fe43ba1b07e24480cdba82eac2af02f2e755eb1b42e866b12ef874db8f56729f0b56939196bb391b63f552db3f3c7ec39a1d778f2686df8f01eacb03019c80d8bbf928d3be121e24970b738be38dd033d077d66095a42d4f1494b44eb7df0074e45e1376a363bcf636637b442460155ece719bb40d1fc476322ceb66ab5261818431b676c3ee34900e20139f2ce04bedc6ee159747b931b42f2b22b3d7198079fe5ff134d61e1d32094cc83972db87162171f68aff7e77845fde2854f3b9a0d21b74b20d8c2ec809d9db9e189051c0dd8557ec1661fa1a1b0ce322590aecc23e610a0c95bf8e2f1ec67fad3b50a0d2e04a267e7844e7e78b710b17602724a2b1fd0daf5aaae67ae6e02faeb646dbe547f0c699e2cb1379f50d28f36ba218a1b615a728d5b46c9da5f17803b7b0ddfaa6af8a8d6d945602cfcfdb1a8c2845e10ef52b08e4afe6f9717aa1865a5df615627ece311d2bfccb7831e0631a7271a08ce5712e16458da4091348c134bbbc0f6c546f14c8d9c231ab7975bccb9e02e0c991572aba8f415ac14e2e466eb01533edbb3a35795beea6327e635c6b103740f2b82ceef34e542ab504d3202e68b230920bc61d94d1cf18cde724d06e23a482b31011ca389f49559a044f8bc99e2eceffadc140cae4937d763106987d7fe30299aea525ef4ba58a7d10fddd62430590152bdd9c1fe3f5dd865bb2ce4e22a65086dd1e3b14c653011e7a3c89c4abaa1ed50be316fd87f42661de510e98dc9bf0dddcf46263bc755e1f5bad01ba6f03708b0bb47ea5aad02d6a9052b1fce2f05226a3e2e74566f10fe938081e85af521d530facec93e917a64abe8a781e246752f984676b56b5a9c17fb37ec862c78c596c128c75422712251c9e25f0fa4352a2a7bf93147adfa3937ec9733a4e035e4a297fbb1e9599d1de9a59b617dc808f117e08e894d7ebdc106e7f065fa3a096cecca51bf047ded0439a19e86d1f4a358099e717b59523313b12586636c72a0028ee88c7cbf053fbe465dc0d546b698cf132800fbde649562ed1d1c65b70ad4ba7497d90bbaa8dab5316435f6473614f501bf945798b6e787cba40d1202870cc74db20387287ff9fffb4cdf7a0160ea04251adcb89e4bed874a70342a96386f8ab23147019c7e3dc8a6f2d0f6ee77ea1b1683337f4dbdcb041c320a5df0f41519161ce81427ee42e7e55b381564cef1ff1036c245bd9b7f0292937e19a58c6f917d8bc00ffb2c098590ffa91e35aa88bf0f29c027c75a7685fecf83028b01891bf2582da15f30dbdadf169772056758b112d80f494136784c5e55d2ffd210cab43b12b3b22efff7fcd159f532727da6ec05f1b98a8978a14a941d2489d0948799285fecc08732988a56e66e352362a6be2cc8b3127ad5279b02a55f57f785b7e1db4de806714cb6cfc421b1af185f408d2beec04fcf9b045a9fe4911bab199445b8cabc822f63eda13db7ea709458a02c27135db9d0e4ba34442524e335b54395b3c5d1d19d856c4a813e0fc2303a45b50eb4e75e5e2bb32813c7346b9c9c1c0ef2b8cccfde4c1c8f4370c89efceb6be328a05d97d39aed2e4cc7d7536b34af28247ede4000fcc7b428147375abfdfb5516e986f5197eb977a865b855e9772fff94c52ffdf99286ee66fc4bd6ff9fa6540e0da9efe06b9e2cb8c70f7bed562275ad9485849152717537abaa41b09aef482b701578723527aa01c63295dddd454473177bfd0415c06d3d4e1848d50a58252bf4553e8afc869321e3d7796ba736c8b389b852bfec26444709e9d423192bd117d4a7cb64bb293e7c7033de3dc675267289c8ba6fcc0ca6ce0b9050e79e4e2d12956851fb28b58225eb8c0ebc9a45158c59a5655fdde45136ce3888dd460ddb15888a69073d825555fcd88eb1a3d7f67a4ebd571c54d2d1274518f65805c2382c12086776a4e11771b7d00b480fb1c5a78c300cd815f8039dc45ea68e61c51e130a50b94972ea631e451d8eb55ce9868d50b4e67952699e020fe4a972b44a36115a8998e760ca80bfb4b64576d97e16bf0d1c9b703a106482cf6872973e94520ce2037c03b5c1cf4892fe2c779650c50d7b88b19a1f6f4be7f5c78fb11783571256a19df3f4b96c9fce648218195e60d1c2e4c662d66ccb18a71bd0a9fb8a8b23c3faf51f7aef24669b70e1a4274abc0f66b911c67f15fd970be027f76d1aab14d557ba7d4f268f95afb5068341ba0900e85cc7d322674c057004d6fa17189123eae8a63d39bfc00d3630a696781bc7ecdc4a6b1d7677ca60c64c32d111d3c10f75c8f14135d4faacb046778787802723936036487091e65721e7feaf94a87d10cac1095e8bd1785f16c5e7f0f5fb9fbfb5faa9918ce2a047c7c0debec9fd5f2c41c01fe8b3062e6fb6e6961c09ab4db1da10ab612f4c5a7328a5209dba00950b62695a4af7c7304b3eacd7d23b4de36c705a55605659d07d7bf79a382923d82ab46fbaff077b68f5b592be6cac56d52f95b7f67123c6ef30cce46bb673b92b0ad6bccfde38ae2deb094a64332f2645f4cde17c0a64aa6cf9b79a7ed828fee42cca7f36d7f6b946dfd1e01db6832cb6f4eab7ea793718651913922d4f360d4b21f257a41c05813fdec7e7d01cd94552d86eae1bced28135690ba7c02f94c4102e5902efa5fcb489bba7b608b977362ed8ef889df360bb12d3f6fa737cc23ea410e2c92ffcb685b442e3884384753e48b3af21056bb1eb92dd975c59aa54ed01161b2d1f8b8e48050ebebc4226dad4c4efd3ccba5c481e80a25e903ed9bdd7992355c18cd5fab093b281f89fbcf4c49a728b3339e0a50b7c8f3eaf38c0a45a241cd2d8c6780c99d0506d6db1d8b009aac9b761cb438e732bebc6c473618f58a526589895742bb0bc9bf2157b0ac83056acd061226b5155c952999f617205e6231dd54dfe603fac9886d0279e7a02a79d39fc16d9590496af4854499544f0d61623b4c14179daa63917368e6315d7c8044998be25f1fff60ff99cebeaf702094322d12ecbd646a3e725894e99bfa905064f065a4bb9ecf069150adf4f6f234c7203c810c6f79c786b859baf6db1ce8395ded182bfce2fd1385b1fae68ce21305026844979fc3f6f15e3f01a641e070dac977d4c4e8251de5b25aeba717b43bcd322a34d4d3c3c7f307f3cbea1f6c4ff7736b1fcbca1b856a1d39a1de2a09e2ff306d5df092ac06ba92c3a7a18fa39a0a90e5b2c1d4d8645f0ffca3717f752afc42eb754439548876e6b43c3a5d94e1bf5abf0e7f9b5a6686050cbba01a352ecc21598da0ad02780190cf24cdcbc430d5aedfc4770abe9c6863cfeef593d95d28b1b050913d0e34830cae0602973282d94fec6205ec8756b4d696623c67d33e55e05d1cce77fdac4c7fdcfaee946a7baed22eb73fb1af5cea27644c13e2e249b6a0fce2f7340ef3aa4e2fa39063e6c8ed748a9d29f33a38f4b50e12d60c03433b81a80e41a565ac3c7013a1e851151847f3bb22ebefd9ff335ff703efe6189df8611dd23fff4444e25494a43eddb53fd61199cd4c1c04def81d6f77187f8f5e3da1a1129ba1faa492ccfa688a8fab7566278f412deabe1f69458de9a4991000314172a67e9eec385ebcc15e24e8cd28e117a2e885e418a5eff75fa6e0af53d4782282f17a9691bb7192b5b670ab7a577b331366962dd0a36346f28b8f56ec241ea0b6552eb0d11d855088e95a118fd271c8a3a1922ea0bfaf0afe9ea5c758e20492391a1721c25d590aeee4199f47b8e5c32ffea485cde82f7392674c9de1aeb3c183f9916e9789575f1b0b461ed9905831051ce8b19952d6c331efbf48b7dbf4614a5b15d0e87af9e76b285fd9ecce3107a983c726ae5d3d6ec6e2baeb34a9e390ee6e7510fc9579db80f9d8ac57e1cc886eaa4d2e4afe8430ff03b6c6f3aec5b2ebfab036e1b2efe026beca2aaeca416a017afbbf80ccbb2e72791f9cdc6f6b505b1dae159a08ee04351f5f2f240edbe45973e734d98f6f4cc9e2b7da8da6a110f7e97eed170300d1f8541ad1e1cb3bf6b3863a4cb490cb5c39e6d4faae2f6ea0082ec6630d36696ea41f90d0d64da3c8ff4facd1cec120e8736509315d426770883f14157bd101f004e3e63407103842843b512eeef44a77743bcefe483286303ab560fa84c14a40002cd93f22ece518b999cb3121c7e1df64eca2069230193028e8d3507fd7d7be0e586300d994405ce6dd9895c747b49f51f20d494c916c808ec85a1e118a4ba5f6448c66d7ebbbe036e81080e7fb9d38cd1ac591d5667dd060cdc04db6517473b7814ad9d757fca4904ebcbc818ca1f22ecf674dcc0c8ec1bb2763dba05f118fcf7500e370108e9004dc46a567294751b7ca51e51229b22220d0d21392e57177d6e2671cf3e954eceaca2cf87918287bfc1f6bf533708943011f277db9e4f9d9ce32ae3f3a1a3343d87d3f95b52d768e4848a92aff7dfed1aead60fddbfb11590d84445c4e75305bb2313c20df2f95eab7e64eb085ee372282e3acefad52cb23bf8855d760a5ded264e7cf806f650248c6db9c54b48e80709642a094184762433ca772b01c277a6fbf700c2046fac1e7c45852dc4c127ec0307dde473f72467a910331f49b44d665488a4c88895342608a78ef07cead2c305ad0fb767e03b49b8e665584ecbb8651dcafc1b5c116b33ba927fa8d15b98f5214a6f4c52b2e56646a8d9cefa2258846c3de653e2297a4051385c199d278a5926a6a8f3f0356900b0f226530e88bb4714c63d444b3dd57e11227770c75d1d2f225236f50e50cf07d29626531dcab3db32b7c1a3af3e43febe274500247334660014e70f3347b1f65c35c55630d4db54848774e2c140eb7c7dcba10652028cc818c7a328564594c77c3ca4d6cf9b0ce46a65cd4cf70a6820eabf65f863291f0f0c89ae9929974dae20ebeb9d518dd20b2795765cf0b0addfc027806a744965d41d9fe3385a89d328e2f8a5dd616160cda986b7d7ab9ec9543d99fd0f70ca38771d00e76228c39527af15a012f227bff39d231a2682a9bd9c4b45ca1fc2b260aa250577f8fa880edd4a07dd8115511301135921bbc68b53bd2375c7635fd9dee70dfc0e14e099d417eb4d6035da9ff7a9f647f84df2437aa344deb5737717058d0fff3c23d38e8d2548ee3ca6dfb23b0c4dfd22cc50c86134291cda45e0131e1917765092935098bb1a016aad380ecf5edc52dd0f95e566d538900955bcacc4342d16f512ab3e6aac573cb9a03082605ae8a4850e455b5d1641c03a37b0cf6ff90215793fd21ee0fc330133beaa6de3b5d59c40755ce8d0cd2c434b9a228fb79815ac089a2735a487f497d5758fa303de789f3ae7a09298147bea45a9c69ce19e2d058fefcd8ca169e2ba7760c96e7af51de2a28cde2d2174ad0a910dbb954f6e2fab7246831353872aec29ee4df899bca2eb5001464c97b1cce8c138fcc94ec40c8e76d15d58b5353e6b3f9ffc5b871ea1d2cc1fc1ab411671eb7d4f80c28b051dc71f34aaceee78f29a56e4529ca51c856472af3c41d587c25a3bb5ddd190062840ac3eb0fe54d3b1f28f63b89977405cd88ca9c73df613c7aaadc6965661c70747b5fc78ce643b6811e78b86b7f68736e2b356a934001d2ea264a89cfbe99a12dc049b6f9ec05d04083fd34b5647bd585f1be04af90aec97ea1e1ee9d42b841d7f31c6fd3853b6c12510c173a710adacac5b23fee0d5586900c83d9711955a1d5d41d21d27fee28b4989409d645d05feda97d3b12b1bcf31e156c75bed1d3d299392602de76f62b9103cce850a2b5a875ef961bd2f58321bb605928c80a122147f4095ff4fc0c4772cc9eb0052f677550724a61d0bf0d328fc6116e13e20ba1a7ab9f9f8506aaf4d953b7c13ada2220f7f6f4695fffeb8a712b5cac9f185ad15a710203071669acc41cfcb817ac9aa6d2ed7c763d9de8b8c7ac7374b0896db120a5f2e718e228bd07965ea30f302417d9f9ab3e01991d4090fd2b0920194ab038128867db1f90f4a79b4586f7602b80324cbacb580b34263c724430b9b91632d8d497956dc8231e14a4d8a202676f3b8a272bb1e26122f025c4f8f78d5c72c21b998aebd00ed34be2d76e4a43006fe81588d6b23eb5bf4c3367285c9a9ef2927a7877682d3af2d5e33c05808479f4521b3a17168e6c97bdbddb7770f93d2f01b08b7b99d331e78b71e84cb19252fb9f9f1ac65e844728db5722e55ab95b9f41edcecb4f31deb949896cd3db5cd0dc2ef15e4ba0eadb9bbe2657b321e467ae20c88064c8c15e19067e28939f8ee13304d7283a98fb49625609483ae02f2a30d160db7d5914120348062db5917327da32d027a758811aa7fd1c21b6a1dd8c75e09d22df3f7027626e95fcb651e8b7559471fcb5ffb9162d550aa82338c51cb0f02c653bb8a2b59c2959f293a4973748870484c05d4ff511fa666604692f73cbe282d4e0e243d6d9ba21e950ac205857f6d41ba6073034f315ef27929d5dba83205f192e83a1e5003de8d1c38c6dcfa2593bba4898090ff610b0890515f9bd44d06d0e8c2d93df6d36626472b3ceba0994cc76cafb660d6a692e7bf0559db1ed02fc0cb1865d7d25f89fb247bfa0e1a3fdae33f97abf5ae7d9e35033050445f73244d228055862735caebee5db8a119a9d8d11a7035555ada83e299f3387abf5f0000dea04c2732cab2470e3e04688d9f1dedd763e036634d28ba9f8e2c5240ca271898be20fb585b49b60139770919a34305e52be70f0d50192770fc02517f652e1e7ce1906dc26a8fbde6939f69b2c0645b8cb4a3954ad2b43918305a27046603a85deac0c770c7e523137f35e3000a0bf96b8c329525f65957437b757c262a2bc6a9c8527c1359d8e598afc781fc2e7ed7501a730554c58d2a552329f99d5c2635fd5fa08d5535ca03c6ea08662a9c52fbc5959b1a998374ed3f624bab2b5b2c33c8f5aeb856586abd239d13286104a2e90e79983c92ed579bfd5576668f7214523b4f53f4bee84986ad86798ec100d603f863f155fdfd2fd2cd72f5676a852c49103b1c0c67f55c4af21fafed6d1d9ed79f863c9807eb055b1777945f8d4f1e0db4f8234739e50bb75bc8fde5af7ab0688ff97d67209fce8a9b39e7b4d05d25548e0d72bccaffb3b604d3b33ce22039ed319792b1fa674d396a6c9786dcac294231be2234a234be2524f2f7dae91c55e58074b0503b24530a0c6e6297f19b0e695dacbd609ce9ca7cc5b2511ba837f4eca002f7102967d35389efb30000cb181f2a3daffd5d7f9915bf8dd1de5d4e7659638e9584d13714469a9ba5d37d7313784f05375e9c5e34ef8219292be23da93ad73869d0bc71516e4393f5a782062975871276d39f2f41d36b81ebbc221648befd2dd8b9ae5610fabeaf54f1947f17dbe4490a05d99f3ac74e0d537673afb9d993294d2aed3e7e293ea0d280ceb019e6f0704f9b34dd1a8da3dc616c365e09b09075d2fef5b1ede4a3bba6df095b1390ce5a31053ffdb83cb05b9209d37592156cb464012744e90748e708378d9c04416b2fd032528cc00e516f1fa6bb6bead7b0d0a69d97e0a14e3b40ada5065b101efc0f1f4cd612b723e18127513fa2b82d5f5cdeea70c60581191b3c7cd81f1cf121cc958060e951b4e6c76f2d557bdddd63f9f51676352d04e0174aa85a900b4a92fc1ddfd06e8006f1d78401e5f7390ace2e425bed97aec36ff7e00d2f6525871edfb56c38063860c618feb09c8748f76f88ea04b6ed77e5421025254d1b2ed05884ee40dd3e9536f678676913dc230188ced021bcb986b6b18b475fe0ff25ca62e1660243f9d9b164881c2398ee00b789bc8c4444d3682420cb869165b30e224323381cb5cc73620a7a96119458441256a6229f2bd621cb86ecc29165db17aeae0846231e6b67942cec4406b326de3bf6da88d906298be18f50763420171db37eb6250875d716390e1399175ee4eec8b0bd26efb179532d87783746b5521a5304ec07e9daa765361558c3187a2073c503c3981ea7992d9c60bcf15ed2832f492d65ba407662a090ab3ef91cfcdf450a588b143f4cbf6fa16010ea41310c305c41056c1e5d407b1eeff592b7fd4f7321aa7e2be12587c37faba2dae3b5050e6c1530a67f22db6c8febe5f34295ef550fc8bbc338a40623dc6065c708338604f699048cd976fdb44878c7b1059cd85f4b91b964b8df3bf9c70f3c2befd9322551cd9f2b50fe2d058916efe06f883fde51721cc8523939a3350133f533f1810524dd023854b3ae2592e3c34de948a860ca68eab2e7515f901ba4ef130450802767ddf18f04412c57ea96eb43689d7148daf50f18621a2a2f4aa76ff98011bb12d62e69c1c4d4a8baae33a8117b84857e317f8562da97c5769136574dccc90706388d13056cff5c7444a3beacfb4110d60cb4a41e70cfcc8de69c72a693c3c22cc4374fcd2cdef089cdfe6a0c2a0e8f8acf27d8e36b650e13a8d51308a25a6829c36bb3cf8ad207df79717b3a3fc45a0dd3b5db984b8293dbaf91f785fe0fcc0c2b38ec1232d147cc42ac3808a34322fbb5f8306303cffb36614394275526e41f473251fd02c680ab57b99de93a2ef421ab91e4426b4c99f3c6d03504de269b275d2cf9faa91d300dc7bbdb3dda6da71347133816be7b051d48a33903efbf4407f90419f1332cc03e9fd8c41e24a26c8f42481b2e9fed3327ce1798263434e51fb358e785403ba67331bfb0f3133ead7225bd117acbf86d18a8703e1d3ebaef2281f87c90eee0cdd19c503c9e39020cf0a6f0793d93dfc23d0167592855aa6516320c766eb5089fe5089ff9c2a5f43622cca3fa745cf3e61a9ace7b7e1c1efe1bdee1c9bf8561b342a2cacb2584c6ae87cbc23ca7f21561483dc48e65ed74d70e36d273946c8af8fbfac07b8067c7537725fb15dd74d6fd8e06d9560d04fe9e0bb9cc66a552723894d500bcc67d9dbbbb2f7def521d214cde49257da5ebba58127ac3ddcf681962da25f22c4452c92bb8643d2d51cd72af07b36ec40933aded2a7ca13c7f42fad892ec2a215c0b050a497585d5acbef59321362e9ebc54f7d7299414c10a9a83fc9beb917a3272cbfffa4e7da3fe84a0f10dabec1f7e5a897e0962a0e842037b4604c054cd61aac3a07fc1c81f3a72e51e2ec990d4db00b9eb14f32933b1cbd476385d2d315eb05da63cf9aa7392e86f8789f1eecdc9aae8fc14541b5d0cf84ceb4c04ef83b692a470b986b75ae8fbd52ed926f7c50a3f0a5c0025385e05933854303b5fdd3eb968d912173130bf0b081ba8ac3f93cdefc9a8143fa61d6377db816b1367c023307d2fab251d5ca6e846a272a4577a7fc82d0901acf57ea102113af63c159c1f5d0d91078ffe6f22541bdec846436cb3729c8126556cf495ef535047d5bdf6cdb5aff1c08ace3e8ba81eecaaee4bf99b80bf98026d93bd1b87cf7eb21a4085647627e2b0b2504884d459721c7b979153b14d161ecf00bf75bf12b4c944c0096897bc8c53526c746135500931ec160fb77114a317c0ab237646eff1345dd26ad855f8d7f7228ad671ffa4793f582b208bcd2dbb018fafa828663cf93e8ebac379ed326fcd502f1b27bffe1912716dec34b4189d2949271b39f8384eaaa45e64fcc800b5f805dcfe8e9986c26d7541bf962d1166044483913e751c75bae08db36edb57973712fba0c80d6813f1e051c2af60ef6e117a84999eb5ede01635927eed50f201635f19e297f45c406e75470fbfe8a40f0db953affc8f61b592b5b0bbf515eede750bc8a0593edcaf5959a5445a1ae0c1130526a514a02445e3a6978f1849f50a7c23db9340d42577892f4d385814e49b151466ff20534e74439acf791d130b0f765f9c9b2ab66fda9098c7771834d71e0ddad7d678af5183635414a7ee104cf52afc1dd2ce8fdff5ba21534f4d73667501ddc7df289a79ef1a336f930cdbe947883fab991b26adf61eb7837d582b8e9d15ec335ab0809126826fb09abb2da87e9aedca01dcf1a662b74cc555fab8b65c013fbe0dff90977f2a74360eb7fb0e75c59408389757e17ad071d76c112ffbc4014b0ca129f864a2489339ed260cf0796380943a2618f3b13e66649fb04104ff15197fafa3b047eff947a782bea063ee95bc5b8cddbc7db60661db0e6a47be4619fe21e5918752a3f48836a6630ac27392a10fe2b6a6b292903709ee2f82c75e0d667d9b51d5ce9ff23fd6c7f2c5a87f087748824f9bb170c33a51a704be5f042a94345fd5fa26e80dcc485aa26fa6c6061d6cafe422caf1eac52f8405a6c0aa2bff08666e2efbca4f1baed7f5532cb579708baeb3555ae6b984fab00610901e1ba452a848424b71e55829122932331f5306b62a5beb24c70237eb9c0e0207591d783524c1a28c1fe61f050b6bc6c300011f151959e387c0125b787cdbd2c7241f837fb79f84889b30cc8e5e84cb49a895585e78ca301052c5df2a4fc873db770367667202002946d7dfbf953f113a006ad4837ea696baa9272c58c9af1d6d8e1f0f21da94147cbaf178fb414d0a77e22c33c3fda3d0be7ebcfb9d95daed750008c9a1d8ddc601df5867b8277024e8c2f447a739164cc63ea44c03ad55282f181cf08f3933494d3938e6937267d1f54289a4e1f19d16abd449ee8372fce0834b212bfd7c33276b09f5ad9221383f3bea85ff25427d5deb17e7a510d4104e32aa160ae05861837210115dca42c986c81002ca19b8d3645d1b473134a160d34ee3261287fd51ed3dd9518c3ca8a42d99bc095a056a3a51411fe822eed25ac7b9392e319e63cfbdfa8c25b357407e9f6e2e249f9a75b5fc17b8940b10c7a8bdc0c80ce7c78c5a7da26bef638318da682b033778c232ce708d33e025782dd268861c06d6ea5cd80d15066128b7b0b5d5b6f51f240ea176d0580ef7b02eee47a5cce712042e07964c9c052cedc831ad39cb143a888041c8aeca71ddda00e103d609160b7ed571aa0f7dc432de1024a9572b2f46029fe8563ff2fe6046cfbc4589099a139ce636ae588318153e65aeb57232762e7be53e82ec3c6f46ee4f923625378f183f5c778c1d9420a1523b518c7b970ba291de12f4ee0d3abc0daa36f7faf05901731bb21c7b0c1e3fa46a76e005632f8eba62e811233000cd2539f44b06619c0391e67d0b33b06bdfc98775458a4293c9515b87e5c25f6cb6d29918837096890ed9428f0cbbdcb8eb0edc385318bb3e61aebb5774cb91852ccceceae70c38cc2056a75e1d63ae67c774a818ad111bf39acba607cbe4864fe74d45aaee92912e237f27cb4f8d40f7029eca2bae4caef946b9549348e37161a6e56168328e03490e955c18c7bf6cb2ed0f8a4c94bc635ba90724e62b29de6d7fcb2249d3951b32012abdacd304147bf0b87a684c56a84e4654a1fdb1c2109d4210f7e9031f3ff9280148dad4fe9dac49cc6815a9d2910e9676cb332990e6564537f5a787e126bb154cfff073cfacd39e74a57c4d0d382155eea6093b96ee0e0bc1d204f58742131e755596903ab9eeb3e947677bf81b62c73f504acb1adc7e4dee30c034ab75790ebae3861e8c094437ac0d5cfefa3b3b0dd75c18b443e46060bb69f122660a7f0d8147ccd093f2aa6b1ad705f3791229891faa6f27122529f42e149eae990fde118d8dd0656f0fa9f5267beb6ccc40fdbbcbf34de723c173979387831ba95cc811e1c79446cb200b31e31f3200a287f582be616f920f3b24590529f1abea7c180a6ce5ab8515f5498960440ddf5000079fa233245d1df8fd688ade85739eda4906703d70e7215b65746facfcfe1aa1ab8c7c817b137661d535ba08aa63aaf44f2b87690dc15322b2c5cb26d729a557bf30748c7dc60c36a9610c9e758330ee4e1efec3393675cfce7c64da0c1fda8ecd235b8c76e3681cff99daf8473c686d1f0bf6aabadc7acc20b88f11869b498b3d839f679d443073ce6ef84512ebed8821286504bf8db57ddaa7f07b0ef748604de3498c5a8be6c3b5b8121515bb8306782ca30bf541db60bd1eaa09ed005970e3c80a2c7c143f6504d10b208ca352b8880e915045e50f5ae5d45f7401b0f70076e20ca6635e89bd950b832ff0aaf0236e206fc268a7f893c058c73030c70f4c7deb51ed388a3bee3aa16534d5319836be14f0addc9788e212172376c5f8cfae54ee2cd8792ae628061ce47cc1a22869761305fc7a5369bbe86b6aacfeb72427f397e40e8b901f5b3e292d7d29160a11bb05979b806f46ca206ada7f1ac05c54c4f49cfadcc39cba3e49e3ccc263ff77c319ceb2c976e8f0ed37f6a73c371cfd76d1b82af0a1e58a6f8e6c0068076db9c229f59e929d9547d2de2db72aa9b89fd37dc41561ab1809614d396d06eb5689f00b058cb17c2b3cf46fc636066b4632a5023dc55731dcc76db3dc1a0a0ec84c900a469a7d17720805a3c2bc7ff493a2df926d49a394a7a0c45c7620f051b2ef14160d19492657bb67d1bef596d29b79d29a4babaa5428795879ef66d3aa7dfd7807592edaf9d568afc173e452e112179d987725eeb41f1182a9f2bf32db42b63b1898abae8d596b33efe7b6607af0079dac5d356bd7cf13d10d0a4e0768f2114c25ce2889ce6c34db05ff06fbfa4b955b018546e27cd0bbfb2bc0cffa0792cb5823bab8a977dfd68e70f068ad03ee38aae0e7d49a8957c3878d643e6d0f65fcec272c725699c16e846c8638f5cec0fa2d981165b3bcaa7602938f4a2149ed71e10cc23a9c5e7d0a3f5461709b23cca9f4eef68bfd06a6fd5e505e756ab4c40a8e2859e0f20337582b5f4556a47c503934f1b8ce4ba7b27a31560d3809029ea2d2067381928499d6943b040cef2cfc40f7025ab51d66d46db1eaf2dba55ffb9d472f04933ae5c2edea96a0468675bdd6c86d3446009068ea089303a1b9d053a8841d98c5b5a491cc1f8e8e260a3655fd3a6b3dbc20beb8e874272a67260b49afb0213e712579743fb62f8ac169ab6500175cc164c2a5caccaa675159759f708016141c4e101152c0e8e55842f9bad78fa3d8c4ed129f91d6450d6c06e85338347f0f6a91a32ba22a390cff1ceb374f5e2b6745e8905f0866029a4c2f9ea7299cf31ea5b0b47ee4d6329b1ba0f1ed46fb0be938a45a2db24560edd0dafb2f1d5526073075b6b2bb62555d44907340a599754fb868566a768b458d6f6b038866a2512c37b7d743fe40490af6e2267fa03f03e2a8f9b6d95650221eaf0b4c87ccf6d505125e1dcd88c3be809632f750178fb8b6bae40b12c686a256feeb481b20ec7a2024b45fd5c00f5608c9cca96508b2425fa584455c1c79dea9c947c13e54f2bd0b77f70ae6e1aadb54cd3af5dcbd773c96a36c60a6e94d41f051284397b36e4102431a5c1227d7a2e5eb432dcc11f0fd5884c17eecfe66a1ce2a22b0419b751d117401dabda490ef21888c13c136e09941774ff0b070e9b24e762ea7ff7684822e8d26105cc2ca0b833708f06574954f6b582e8053824a60dbf179e50db6f55c069244550b03c11e5cd22653891fe5064198a330115698a1d852f57c32eb855423c9db7c5aa271f155577ae09f6e5a7e32c2aff1f5150feba43b795cc2584c07001cb655353eec53d999060ef4380640747f65e57196198444330db72f8081f5202a4f8e4f598610629f96fdfd5734ff55a7f4031c8538f9fe80d1dfb973e8d61beb98f1f854d9783b319368ae6f9a015484bbad829d30cca00981f840ec563a2e24c11cfd9977d1f787fb0a395ba4b1acfdbf6f2bafee57074e5328affeb76204ba93ee5b82ed1dded622a843db90a4d19c0b4ef46867161b3f6525493b3a3e285408073fd97e2f53fdb86c06e9845e8d410462857a2b9243b348ad17b662cf06686483db4b559d400f33726b232420a522d3a4a63376d60b56f5ee7cac6688203272656b35c2a109ed301e8a298fb397d7b66d22b4867b9806269b28a5c16d2c366e20f6c78ecef995bf41e82d6fc7cc578e293bd917b60d9bd6d1dedd21bd12b872b9d3e443055b534b753d81d39377c29f810995cf6238b69779a358fb6208eadcd48848b22b262ad65f2682172834b865f293d2fc5cc95538f242b21cd12261023dcc253992cbc1c548d996c675b14dac9b530fcc0bf78fb90bad6027e52502201fd2f781fa9dcf4da5c91b6706f2eda965b330521737df12d13d350c2506a779924f2bfd8c634cd73c84811da8534e0b14ee42996d6ed01f879d4d858605adbb356eec9115a7e0a689e0de4c27be333631fcfa9fec8d02744e206dde6110f97142186a44a6f4f220b1295b4e1b0385b0826984a145ac28bcf89a9c3627084ef803b0cae77c7eb29fe2d6ff15e3762928f2f1100f4a8b59adeb81a445e70c54d7b8453eb39ec2e05e612d1c0884eab9b6d8792606e5ae8627d0f4d44beb2d4306f31b6cdc617da0f5374ae79900cd9b9f693debb14d59889d5b802fb8471c0a414faa8abb86d379cf24a883de065656be4205dd39718b1dab3ef93ba2e5107d2c79ae5b564bdaf2971a6ea04febbcf5e2c7b3e3743d8b37631ed2ebfc2a116cc9f8b27037cb4d7bd4078692ed74caa2a1ae3458d1eaef27cf48870bd95a", + "public_inputs_hex": "0x1d420eaa08a65528f470fd3e2a802913b611527f41fca008a0ad4e97475078032a555ccad424037773cae7569cd26f46467d9bd96c32334af741c91109676183000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008f26088c208eab68279f6f45f234d271000000000000000000000000000000008ec0f15e98d9058c0e708be73acd2b9d2197e95de61c6c2844727c848aa819fe89bff180954ba01135f7e3d285aa3d8e240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f2a318f2fc85748ea90c49625631654288c77791d8dd0792e201c748ca9863ac417b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e2bad40c7a2fc975f2e4811607e4d5fb72361dd1af1bb2364be799270aab5c6f623db21355d312ad82ff6334e39518d7aec226005c56d124daf506a44749cf370" }, "decryption_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000d6343409c0afb816a000000000000000000000000000000000000000000000000e0e3142188542d9d000000000000000000000000000000000000000000000004bdda217c121af9d500000000000000000000000000000000000000000000000000014a5db1afe856000000000000000000000000000000000000000000000000ee178f82f74d1cab000000000000000000000000000000000000000000000002e8d0a46d30478dfe00000000000000000000000000000000000000000000000207560c01e3450dbc00000000000000000000000000000000000000000000000000022788c7db5ddc0000000000000000000000000000000000000000000000099ba154d1691f0c0c0000000000000000000000000000000000000000000000077a57fa84b59575440000000000000000000000000000000000000000000000052b18c02725e6860800000000000000000000000000000000000000000000000000017e9657c0fc1c000000000000000000000000000000000000000000000002b224b4548754d742000000000000000000000000000000000000000000000009134fbdf2459e11e8000000000000000000000000000000000000000000000007ae759187042674660000000000000000000000000000000000000000000000000001b7072ac05fcc10fd82a9f5e13726dda894346515567a79c225b241a718f1b252ee23cfcb8dfc134749cb199d7dfa121b0233c0bca54919eea35871367be619fab7d4acde565f21f7d05e4d6075633ee1781849710d0cc9f901e277b8147885e33549518fe8c9235394cb328d148824ef86c283f67c33bd9d74125ce290de790d17252755f12a2c575b654f3c0128b45fc00733497bedb1ab89208d38b1062fbdcd9874d1a1102203a3af11c6d2beeefa926f37841cf1766ee9c1fd8fb937fd7ca88bcf091a3b0d693f463de1bc4d89d66c527f61a537f8c5e09d43384776febd12c1a0b160192419f01ad42306732827a9e2b737e59e99429dafabbc4b63fd1eac9ac2d8f50324e028c3bfc9cb7efabedc43d2c85fd8454cb2ac6edb769ec5aaa71a6813ed252ea7767466292e673a4791482b20189da899063637b2fb233fe7413ebe14ab48172ebbec7b1577ece1ca982dfe9bc31189268e16381b3452830ad955c85334f723b7cd29f8459a2bdce9108984d2445710388a4ec18f02e22446ef9281b115a80a16fb591cb108f0398b7bdd4b096354d07245988cde80562a2e3997dc8d77ac05bada7a25ab6675abb5c42348a44a313a519ade461c43aa3993e73cfc06472e252e3d75992b831f25d123331077a32c38e1377c7e7e41f360cc4f9cb84e70fc047c37bac2870a10065df9c6c9405302c93374fecd0753fc9874bb9889e7e2d8056c734dfc773c2d255b48cb1ba153afd8e628b1a7fcb0ca36233ed95a92e6960811d86a8a694956d28b0187c66038d4aaccb51e0a164bd42d83fc40fb48b8a61af5e281d9149910f3494c80f943107661e722113d7b9a6c0c1deab0beae72c60ec45189b66a1679eca9165ebc7a629d2e71e0a594277d0fbbb1379fa345c9a61c5b614ff22f7abbde64cb1c7c49431e04559ba35828a18bfdba63c1169090a409a9f16759479cadbd816a6eb1116a9a4d0c3ad1b5f36f304a97c7e87643778f0c38118f46b63bbd48cf9b4e18bd76663b71ad6b8312ad607a4664b2f47259ed009c81da4d44d2d89b736a3ca86649ec926b8d9f5ce807ea302b1ecbc0349ba0010534881c9a4b14b496d7dd5146e97bff9978f74eb7cd73dfdde685be41267606e74867136658c65220b3f1515fad8fc3d291f636b9ba4a03f4e288464e246a17c606205cb08af4feda633d7e7358b8a8c1e3a9bb7cc3e0089717bdc29914ea0b923cfac7c47dc0b8d04a4ee9071fc9317c266eec4ccab59ffae46a9cee283d05e0a63d50303298db10d4af510792f740a8bbd35be7057bf1cee727e79394c22a8e2545755f8a0599a1e150671f54850bfbd1743210499c84c3b77b4d1f66431069cb273078a2e10f1f015ccc54118eae036e1947b49f63342d2e5cc69ac3db0e6346f2648d7fec2da28cbec5afb3314ceda07cc2c3ef10078c086658fdb63229c49d8545542435bd4d3b1696c001df587e38707a12cf521214825cac7af47d227e93ed63f59ed33ce031cd61931a57bf28f14f457a815be7267cc3c210ed870dcb1324eecc54a3357207d5d9d2c42815d5e7b2a65b4c9d5f1e208a9ed0a6b4235e122935a8843159470d69ebec0a3383369dee35693d475148f18247247c071a06a44e4197aa7a02bc80ff31e3209552172b66163935d82fd56dc4a6a730ff173fc70ce51c6c9dd197840a1e873489010c6750c0f7c05ba0de148c871f50570359ebea3159661fd9333c2db2b4f5041249f8dd96ad6ecd2623078086bdb0e51b67b47a31148be3689e5bc49025c1182f1ea881ed3c65e72c2944f0928668171ec2d7741c74f5047a6b13a71eb54058979c872ce634aa6b5dc6e060dcc85d1002cd3cbd4ab0b1076ff2360427b4157bf24c8d965d6c836962a84ec8315cc713080b314982a7345e5a38ed87768e95095ab5b39c8736cef5710baa273277ac2e17f55debdc276dc29eb726c7a938b352124bbfb0a07c26605f144d404bbd2bdf149594defc22c1a6717c5147d2f36dd017d5524107ce84c6e97b7a143e29d52f25022de025b573b9eb662e6c3d09660e4d0b423a16661e9cf66f44eaf21945692150a6292c541bb691e59f8ff4fb579f797bc5d89b3138d8a7aeccedb49729c724beb14ae3f33d99876f08496a48a22de7c436ec88364ba02e10bf3c52236ea913e8426d7cc3e2d38c861f8981014f91432d53089ac70e114b86d4a60d150e51107bdebe9f1e40b98059a4313e5bff2e5b3200c6ca3a0545a8f115bde4fb7d7107b2010c1aa5c9d5ae36db4f703cce98712fac6a633da3874a71943809c40cd7260a628aede79ffe3799bbe5d49288b947d1d067f4ba336f26bd7862510ffb4328331991a2f89b9f53a3620b32bc7bb50f76eb9cde2cb2f9cf42c4a22df0c0e20331793e2f642f142bae542cb7e2f0fd200db0b710d3fd3c0f4d37afa38b8d501fc34640655f2776937aefd2c0c15fa5dc91fa5de878ed805b700436d8ea62ec2061cc0c19517812cd43acb92e01018dd857565ff19d40bb8f09a5f2753b26900f1ee465a4bded176bdb8c4cd3589184c8c80c0b95cfa3484ae2655c46508c4b1e06aa30e32f43f454846e4dfea668903fed3bf23762dabf7b4d7fdc33590fa3010b8aa4bdf244b628b32e4468ad96056a848209a65f1c42dca8318754332aa109bbfe7a82cd199fc831c48b5439c09209b31247b258bb665d2190407ba46dad014ed3c854628e09e8ba9da2c4e2b1e658a6b56fc772a101531810ba1efd61040ede249e8bbacc5b7f064e3a0a89f98d64bccfa1d47c52bafc19f615c4df0fcd059b763205544ba63668706829151458142db92203b996a171fdbd9dc8016f54105b72228df5503f7a4484b4e99320c03d7d8d384e83ad9cf5b9ab322a9f81582f48298a3a781a02a0fb4e6a7b116dc94f11cd919b909ae8fef369dd4a7498252a0c3cbf87c8e91ac7e56d9bcf6ddfec337df1e6f2caff2fd04489a0e15f51c00c8bab2bf1e204b2516dde8c6212fbc5d519398e1d7ffb0d3ced8ccad27638a0183755e45c97ed7e8496714a425b0683362ef4cefaa0acb128464c50054393010a3916f001a49abadfaa9c44052829ab1373491eb5afc19c448cc2ec2384cff003b6ef542acbc10237a0355395a4828bf9c356e66a92f998a9860477393e2ecc09d9a7501d79a694699ccd39b0fc5f7518b6ef187bea3938e24ac1e649107ae7134b4819e221010ff3ea8ca2aae7cfd8c913d727339e5e90d8bf9af431f2767f229d00d4bc9a9ab2708b1a268395b66e88603b50f8ec614b1ee8f042247191be099258078233ddbe8699093187d4b87238b8503be1b3a992a66efeb3c15bf46e114045770bc9dea0af8d1b3b9e7f89ad0f0f7b5cb58347f9bc31a1f5b749125503095d5ea015e6af870476964d02d0836687d9e205ff986efa3fa05eaf42567813be91e7d92751fe7dddce9055502b2beab3e4e3b9987491834fe202b41a16142628026d775db7141e97e2d4144abfd41e23c68dac14669bde63aafd40d4a8002c28aa160a0b5b1f57bcf17e056e62e9a6a792e75c194faecf8edf72ab65904b061cfd14a239bc808454c33b080a44af18784da9335cf5d3de85828c5b2a91d113bf19bc7ab5f87b921f7b88712ef3895fbee836d87dd311efc22d394dcb758321c9d1a26147d519764b79da0bc929d245fed23e95e58281d43dc93a611641ad104e9bb58a706ac4f9212e22869a7d7d816c3afc5f2b9275babbc2353dc59c332db15dde7753b62322c8bcf8d41b72e3bbe6ff0a2c61eb466e5512bf1a8be499301fe18941e16b2122f0fc390e191cf3a4532c849b39956f3e318c907163810611034a1a296a7bbe66780ca88c6f599ca09c82d83d70e1bfa4473776b5c068221194dc907822535370338f889825f36a24db7a3b42168201e5e80264e41e7569162cb3669ee45cf5c0810dda88651c91cc32fb2aae51c18f55174129409892050248d04cd731434d63434389f80310114dc92993c9b39e42550954633cf31d241754f6dc46a21f7be676f914feecb63bcfa9d839638e8fd140acbbe7e494540a1da5b4f31a302ecde922b1a10aff437aa96759c3059fa958a3a6e2c50361306d1c4a7b7f63a4abe9b13738ccde8195d2cc4fb4c3c85ad53c78dc8496283d0cc601396dd75bfacebad9ded60880f37b46bc61c87724c7b8c0513f1783675e4d5018f7f30a9115e2b95cbb5052e03b3111d90798ce5272e2c6228c165fce6c347c27711e7de6d91d0b6bdf34677334c6e8ca47a60e0b7bbb5a0f01a6724174d0cf0f38bdebf434e84d92160285043af5227e5f628012786f658f53dca24e3d3cda0841e6a5b1c9be5b9b898e5e71a0eac8825cf7d8b4f38fb0138dfda4cb5a9e5b0cc2d6ad4868dfa422efff32fb32a6535891e60413f524f001d727d786f2970e04e0809642af932031d727274d05962dab59cf469ab5d400f6291950cf78382218b051a65adfd64e4e81a5e31bc3dc22dfe95a810750fbfb0e9bb9e230aec7a3227e15527102ce7d9462df9e992926f691c129f6e38371aa044411006660b45b22ed9c9c0335ccaa9a3771614eda0ee18a5b1293cb713f3e4cf32209bf2b2be91b52a3e0461b00b50bc24212e7a0a168cd4a5670eed7735141ffbb2530bb11151d70bfc2ddd7bf86ec678546a0ba985b6152c5b427e31c612f298280263c0f312db2b751667a6b85ba0fac6656417340203010f463292039979dfe7bc30897160e633531a0d52f9a326a3aee24c35fbccdaa387a801db8f6d9ca2cf6b6641eae06aac300aea7c12bf9a28f3b667beb873af6f9caceec3fc3f0616dc7f4bd22f4146614c7ed9acb39a3915b92ac5b7787a877f46033e414b721b49d8d27e5ab892415cd864a75ef2e316f4ba10efa47a4559fcaa336afc1d9414c0204b98cc0a70626f89136564bfec778ef9807939900337c2616739d4a50f3be2c71830968412b0790e7e1110b375a19e3f5ffc7b3a605e187f41bff4a6283828996fd3f26a213a28f6e3ad328976ed2b72d62ad54cf51d8215f993325d697137dc2a4c1e3c80f6462158846588d3f5b8cfdafa9b1018b7b1348b150b76bcdd0640f57fd2d862dda4449740d5cb065e00bc50146bc70b3dac6a6e9103d0863af505eaab860361ed7accae9e15089da9d1d801ae35817a5f67a28a604771cbf3be04ebc9c20e51368750ba4cdee1f00fa042d805ab474446a90cfbf3fc97a20fe1ca5e4a6d588266864684004140b5150b5cdca08014cec724f1aef668d2ba67254a53f2c59d50ea76d17c1e2160bcab9fa7540b366abfaf5f8413244eaf950547f7571cc057729ea749b5fbf56ab428aab3ed476cd4f68b3f41eac270bd6b29fcda4f75626071b1a20be49701c43b4b16437ccc9fdf48a62fe1a2663a68c352e147f4ae8844c2807157c23509fbd64ac8ef2db22655f9745461382cf08b2d3cfdbf28081198a21ed719565dc566fb084e14c45856676c2a3a981576fad4bad652a20e85092a128f13027717bcd2bfaade88737b4ace18b183076e1876c817935ef5d7ba8b0622f6b2441c65d5d4c293d3a0506639a43c5d085c2df2b838a27263902349be4951f7f12272801748a9b3d4245de5e60f77cbeb1454b069a9f476e59bf36245722244ac46a6da45d3406581f44125c5661200e0d92ebdaaa3d14e973d2618ffc9b2081a5ce7bd73efba7488ec506c08e8100329c8a9f4db5d1d94165c5e0a21f202a8aee42247f7d031bffb09f2d852246350848d82a5c139169e8c8d39e6178bb264a9dd76aea3c0ee71750c7a9287741eeca96cc3e2418426d0e24d5665a4dc22cf017f7fec4b71e1e288e9efff6882b3fe1b39b4a527403b8d87a77b1f7b92511ef72f0386ad6da5c92005b739f5bb3c6aa212453e8e6d343ade9cc24a752631e63d16b0a0d0f0013302d8a6b592cac45f107cbd67975e6c4bccbb48572b6290fdbf02aee0467e7e24d7274351a3fd001627678697c6d18fb80fcc5cdb2b79e294219cb7224ebc6a5ae6ec05376afda73fd323e700aea6553a139f1bfaef34111e8014ae15ce5ddc2568eac8f8621f643468697c0f957c13d13de82457e4310297c09ac3934c2a272a10621472fe0deb9eb13dad684b66f5b19a420d8c010a82fc2de64ae10f7ed94fe5a610ae0f8889fe1d94f92544858c65ec64b95055ac11c4652efe064f85ac337332ad95955bb6db02f2d11040cffb5d6a8f9e632a93b14045aabcba545e42a03bbdb72421e4e08644e587725d0bf29d3c8a235bab183158dc24705ff40a5f24f8a0ea39f30aef722faf69af92a500abef9e2f26a2b642d76adb78616af6e74608fd27de1c8ce87a090d832f57e13ec2534abf164ba0b2be6d35cbaefe0366ab88d79d0f152a4cbff4a40a4dd1585cd47f7c6d39492721b4819f391ffe75d71858e5e7f3b7040d6d363761eb4b596aedbba067d8c4add0183eb7e4c92d2f449f9287ff1c0a8062ca1d719ef98e276c98ed954559047ec1aac319dd0d0e925fd34e61f3b450c6dc69cd7f50d4df31733d0652aef9d20d91b5aa21fe2b9a3c6915f614a7f1616959cc3fc32c5187f0dd24b0f51b32272ea072d7e084d62c3324dabd4f1985dc2c0aa88915960a5c1785ca8683207dbe4792d9d900add917b458ae42c0c8f66b9c414c484644e56fb083a7731d336d210060d5bf4c1b5f807c4692ca713632bd87b26ead2b7182937890b091a15f42d6ca2011026280c64f222ffd8629a17136b4c7a6fada3e2742fe377434073a9cee2bb03246938701a602957d1bb0abfd402035df562b6ac784c99647ac645c7958366136f0024347b1fd8bf330b4d697b97838393c0c91b82582343eb58e2f9d6b9c82b1387eed1f819c4d9a45a7e4d1ec5f2d2f0a8fe5aa96705c2058e1f62b5b2d5254c98a089c8f5eab8617604beb94022770aa9c76fab0cca170d5fdc2dbd40e628da831293d1c24273d9523a420bc585f93d4baa497e68f258121f9647fb2ef90bbad294f96003a9069d13d95465fbfb65362e6c70e61b6056e5b7053477fa0b17f609298e716d5fe9e20b2e49d5779a225f535ffa20c88bdc387a1ea66864d62571705f8745c3d21e0b714826d23644b10d5f3c166f1bd704291c20e7f685e8245e007dd62da8e45374824a7d819c48aeae8cc9beb2988bd8cb3cf074c7af0f2ec4fde771894a79f484ddee1e2af510dc80843c64f2dd12b7fb36d69a4b323b1d0aa5f93a2ea384df044c2132470d4c5aefe263fcdf47e68e9d26e63c81dcd32a389e21e2d56d771c823017fe31533809c3b5d3016afd6f95329ed4db23daf0106cd2e9f2addd7e0f013c1a32c3d5eaff36d796800acb744179cbd788a15a3c037261f29e401178fecd97f8fa01daf54700ce5982b1d58e025ed6ecbd300e7107afb7af7e7ebb538d40acad316ad54db0bab5ada811e395e0ebe6cf74ad149629c2fd131d0ef7d2faa4fbb177351dd1e68135f5ad97bfd6651a2c98ca8ef85926aef7180b5d563c5ad7df270d921a79feafa12e533cd9b8d602fea0ae16899729fc9de73eda204ba93c5c60ec0420cc4bc9d06b189045d9c12c71bd79e673c40c7ccd521d3ff61c7eceb8e965c00de62c8a32acfd1f121c0ee841fa2f756f0618f2d4d6ac96d7bd74f67427e347e2e760446958f9115ad9a35b530e801071be246e5576bd91e99ade8d75b12fbd1a43dd83960b318f970045dd374984b535e72bd2ba51ecd03b9396ad32e9fc4a8fcc22b203b32a45263a795786f4fbdc459b0659c4f1cc8261dfa55ea5ab693197366697b6ade5d4340c8192fceead82ace629a7472f3b13c28a954d467990509f4ce8ca0d37464673ad92a13c2715b7db55250d67b3a7e4d9a735099f8aee1544d0e6fd73f0cfad9c3aa5e40b0e2b8962561ec35f1ad2b11aff259d79d1baaba2fba96eb834e76a9c80b364e97b24307a281424aa2fa30be62314f75d116f5c131ec32bbd3d548ac60e287531ee45b88a9911e2292468a9077985e7f9bf3b9d7c9c7f4f4d58a034168a0846edc8fd6e821919bc426b90b9d31fd35ea2b87b4ae485c0684ab37528cb0f6319003a27dcf72e1bc9e5dc54f4a62cae86cedff569653518ce21fdcc660bbd5e7be989b268663728da72800734456991bb11783aa00a75d9d3e930bc9355f763b4c3d040e1dcf01955668b29288a41828a44bfcce4f3d3d409fd71f61b6a69b12757debf0d01692551a363188bca817da75832de2a3115a69e2cb747b0cb16ae52e6ee572c5de717941f01982ec1c364c7cd5d4d6eff0e3b03c68e7dca325c1e804b2e0abfbfeb1c9c593a923554ecd202ce87adc8dd2f5c4866d494f148edbbd7496abe6faf5023d53378720ce63e06078b8d9e84ca9a1d2a65616bd2def3a8bef72908acca0a10543ea597c8d6d636236f8faaea56d55a20c9142f080147a46a88648bd9dc11017aa88cf3adb1e5c174be8ce4b43d33da7b54a2d92514e12b6b768ec63bf0c31f2a9605389352931a3b69a1f26ac4c2163544780d60fcc85795256c6afa280027b06fcce4b557599d94a87b5c481d9a34c331c396df9656fa89ba922dae138408bffe3ac2706d43bd7fb1c8e56f3718bc24cd0b9e9b0ebe94080cb5eecce6480f8c185f442142926ca3172b2e19c03c0722752911cc8a6c7206f3c2912787122662900584b849d650e0c4eedfaf8187238a97f307266eed20d6e0b6ba01b9f20046fd636ffc52fc2d5daf18ebb043f41bfece62514c98854a64ebc2fdfeaf7c1cec169dd44365b740df2819d9ad1aadd76bdf6033173f06ac4d778fa9d4855822dba8778bcec03e6fe23987933ac5841cbc60c642f2aa3f59f1eca01f7802481358b76b89c085167d1b82e5e893efb5c368bdabf60c4d65c8b526e791bc70fe24da05333484e79a43adf9468afc8a513e75578bc37681732417d87d3d1a1e5a1d7680fc28c20793b079d2fbf91f06483f9faf0d3ed1f7e0c3414ca35b2f25e7277eda67942f851dff283b7a1776dff8760a130b2e4a95fa7a494e866404815d1f8313141a02a6fd2aaf2204dbf452587087026b47df4bde2c459632697f3909173803e820b6a810ead209db8c49720978493b40daa7651c88244627d27ae18420957e21543565fbd8367917180042e123042789206e7a0f382f05630a7233ce23870618eb29d57048ea6baa35a13e7775ea499b77fa2b2939a21948c33c49b80eb128ad72c44ec6b2c43ebc0ebed56c4d357759a372cb724cded062b46bd9a7242e8783d21021596916098b8ba9210ef0df0b8f5065757dfd22b3564c2cf1c62776f8659e98c20f45088864e86e85b8e61803d2e2e8db08c5597633e2884b1312f78654b323134010efe0a5a22f96ff83ab4e467746b698b8d2d68d2937d3132e98b53f62eb12c772cf6b86924ea8990b7fe9f6ca76e36ec6bb71334d5fe7ac0ff44d2a4c39e0447d41ee9144c125ae86e1696d83894163c929b99d5657682c0ccc8739c3c024b7d3b35be279dec63ccbd81e8c0d6e63debbcea29386640dd127985d1724b1ef912fa749d00325fd280af6eef3c77346dd5e2022dd02963caf2169bc8168aa63972cd3c404977532baec258ca30873d54b585b7de7de78081313ad920afd58a88ed6de63c31e93a3c05693b27665cfb4daddccb2d584b0c71f0577d99ae959e0d3295f3b009a1bc1b357cdbd35bd564a90c10c57a52c4d5c9e175b5bf6cda85e75a362d53be71619e033f18a912ac2bb171a8650b6494f385c23cfb56b3e56656966c1c3ad6aa4ff5fe93108e3aa5f266feb88c3654015fee429eeee7128c5e0b683bf8670ef76f2064c82e33acfa4b98fb010516c9758c24c08287df25152362f76b084441cecf158a6a03c74473f7ded3f9a280283f3a94306a6b182ca1c741819fa8676d33f15534ac596a39d184f208664084e86f69f491355d22dec6c7fdd47db8991f40363b46b90b495a01bb12e79bdfc17c015222c072641d13506921a872ac44c9cc8d108225e2aaf54c7d51d7a2b05ef429931aa01430a19e1d3fff8f96d9abb6c0e0cb3f645c059329e2c08162c99890102ba0d05634e00f98c8be1b71cb16bb2844c4cdcd67eea6259c5a9d668c058afd5889e27f0261c1586d2b4cbc5948a248e38240aaf1b6ee10801c93b9f6bc130cb04460efbe72cb208793fce34c92d5cf696958d7d560e5ff6847c635498a769eae2392b0e3ef9384f3ed5a8fc649537d71b6c540bcdbc695313c2d581d999edcbb7992ee1be226490863613c815b8677279673ed4659589212807f82da56e940e674601240ccf06909e2191a4d52f09a513a0acd557e70ee7bb5df0179cd2659547b10fa1792b0ccca44cd07e4b82df1a2c5e017d2f8a32c0842937f182a9f354a63516308aae017cf8a00e316b678fd379054cacb79841e0801c32e8d34e5b52ea8b0c8cd36caf58534592739dbb0ab2de7572923ec1622a98428768e440b38d4ace26bfbe8863b8dca57239ebb222338467db5400732d172f716e449e63c92fadb419e5644af6620b3258e48e198f2ef956a6856143b35a756ac2e35cfcb6eecc7d178c6515c496180fef749ac8e977fa63a28fe6dcfbc73ddb360ed5709fc9b0fe026c4635a79e7f4caefe5299dd7cf4b0210925079bae38b94a1cfd393c36b5730d3b39ddecf9213ed09c1760211d7c8299f793f875acc0e8a1e444a7c8009d5d0df95cf94b07d8ddea9e064bb63e544b266a94c00d0c91b75697c7164fea0f912983f360a60797fda997f5f370162ef1847ae23ebfff5e72a8e8c719631b7f8e24c08cedaad805e39e5373db066ee5705cf40a4641472965ec2e8165fea29ab119fb1fb534d5183820622a1d4500fceb3ae14eac2b420e084526dab4088f174c03abd7cdf5e33ecbcb6c6b1f09875a347c283cb0920de180cb615648c29c203f0ecd1b1a3b9d78569171956034619df0c3f6bce2442e302b4a7a0d6c321313491247bf62042d00eeb61610243fc11ad0d517806fb5f9ae448e7facf517db96571a6a1af751ac14a6383f96870460481013a08d296259a69405f1b94b9c50af4e262e4a32bde88f8a1c7abf78808893ed9a0b293eece0feb9e5fb3c86cd4f874b0a8851b7ec202d182ce02749dba88d816f94c2304cda0c56573114472ae4789903a9782552283c2c2b88ed75ae3a610b32844cbe7e7f7c74f5216fb6cb6615cc2797978cef7d47016bee6da4c77e9f60453cc17e44724812dc958172c38e98ba2407ea8b08e0f194575cee3effe062c4926bce85ba7e338a9a3fce58d4e021650d19a35f54d83ecaef10cbe01579973ff5bb6c07b29feb89ee137864ad11a2a70cb411e2a5b220b3fe8a74bb8d9bc4b624dc5914e52b9ace98e7671e0cf5e92b19536b803836dde90b9e384ffa4d590e141d96cd7944b79c6fb3d80992fc108702956f27608a987c9947ce3fdd637773787e0f976bee528e7ff57a7fb94fb361268bd81710fe3a615437e23e557ea5c485b4a6dbcd89e24eae87ebb9ae61eace002385c62bc8c9c1925ad79428be87cbc883c29c2bd9bfca108086de9053dd5a27999b28a3b0a8e41cf1fe430c3a035940be16521438e35fe5bbd212b8d0bcfb0135f7b015e51ad8ec8fa8df12cd077ad2bcf7a705889b9aa6674aa84c0428eb1ce7c1fa8d1b1adec22d51cc8a501c42b95c783dc1320c9b4d0fcb6f5dd4506b206f292e5d06fa78f52666675fde9819ce5dba63fa92ea8a6463422461f58e622d8937aae3718f509e1cecb3c95c9c82ae33ad610f692d7df28bffb8ffd4b3e4039e63003aa372590c543591e7d89ccbae71b74aa468a70da3db0e3ca463b15f0e6f4cdeb5bbf5ec3d736f1505610aff03ab11756a701f5b77578daf8989bc322dd5c44335a39dae704ad3f23389a598b98b69642f6cd7fa1830b998d64dc6a3250d7e6609e26e1725a4f6255ffe0e73e002b4aad16a1ab58b3fdcb8a26958830810ead864d8a658780beb619fab6c34e15199c1197968c99b38a5bf174478d413830e0056c5c2f967af9b3d26fb050519d4800bfaec15e7f13a94dcf2c5a2bd1c524d5ae0d73b30261003402d404f8e596ef73e98c0c4a6acb82456870f58671d138fdfb25ca284ec0793739a7cee577e6d3ba319efff2cf9f22b90f604e4f7014c701b5b3651d06ef3f3c3d566842801f26b1a8cffa425ec7aeffe6c1205932807754ec92ab14d58fff617ef19940a7e40c95ba9414628d59e6ea2fa9cc1140dd37f315857802b79f5d1b31c3b076de22ae95fdbbf2850886a0c671a67666a0b789aaeb6190fea5776179f028c774445d9c61c76dfe1a263c30a0ce5880bbf04378426e45dced169fdf580d0927fe256cc195db8122edb0732eed159a32cc72cd17f0ff0775670ed47492ab73e9bdb1646d1ddf6fac59a2f1698dbc00da9fa24dc2ab6ee98dcbd0682385e98342ffc86fc964c46b89ccbc2e990c68a761169037021867fd84d7db8c3a74c2a31bea5676045a5d33c4f525d51c11e01f58d200f0fa35b54f19c81087074ca714fed679d10f181f9cc2dfdc8cb1ebd703ac7200150fdd527067f0bc99b5b785afcb640874b3f62159de99771e6a86310818e5f2fb0169c55188588154761e71ffe774e208c335942d4dbe4aadf295d59297039066fe4bd1064d8ad040ada4cbf1f5cbe7b80e29396dccc2e0c93e4c1e0f373db107e57b560504f1e1bafce78380cd492758e1616d3076b68ada6dd12ed8adbdd14e14ff30a2ac375956f6087d8a68b13539c5a45d2b3de89d08a7db022f688050ff38bc3ad29e40c07a6159f119da20b870054811250aeb41f835d074b948a6b0f6f2f89422d726d91317c14441ccda2e382d0cf289c03d98aff6b3d34934bee232323cdc38dbb69f1c9092ada5e3a9cf8aa6e130203f1dadcac0ab7066a3de015dec2ab95501c4ce019c7cf444beb5d20d0e31b74e319c170c52acc6feae34009bdff8a7a5e189aba127f8d488ecec7bfee67c0e4da40da08e1d216c95e4e531569adc78433ec670379654df38bd2ba311657bd0273f3f945c45f7c9883e9042040c5b6cf63fb1069b8e0046174d371d03eb6cdd9029575e42b419a8b72380122ed3efddc9233f58b6c2dbc2a694d2b79011a794943f1a99e6603632ec4085927adb6976fb676e768d1ddb26b2c88158e8cba7b666ab6a20b030432ca67c8eb29c3b535066e0f779fef60ecba39001047452fe610643fb4491c13b86dbef2f409b504bb782009166f4d3069566271c6cc026ef64cee56c321be4aef2e665d47030a7fcc5527f2235722880893ad58c7dcc873095fa719bfbd937803dcc2788302a5ff8a658c1426defc4915c2e49e49ac66eb4e661d97eb9bc1c19d03228a58003a38e29ad1f40ecef9edefa3c9d86d6fa481d8bcdffdf1de0e419883f488bf2684050e1b465beca794930b7de04f78f0001bb18b954352807a99200f935f08133200c22324dff58e9f920bb0e54c8781c29ff6466cd26ada6ce05255248138001cd0f79242fd0768675144caacff113ce2d470a5d98f9ea44b6fd446e8511c1bd7c61a3d26af3415eb3532dc9b7b243b34752c63ba0bc2e81bd6000af3ee3e2f9409ffd485289bfb3e1ff44d8b181e081f9f948aac37c0d7d535cbef1a42501a0050b1ace19cc1779e23acc5aee850bdca8fd5591bbaa08e5b94d30df3f6b32a05139aad16899b7620a46d0be03c740e38704090e4d3d584aec4eb2d56f39a1573706fe29dae924284cffb950843d5e3090b3b59c9ea76a1a2215bbcd869712c7129bccf788ff4ccf5d9f28673b69788488553de67c648560a49f98c9054a30968dd170b7f9ccdc98147a7b6b0552bad5bb39a2eea0dfd942b320ddcac5e382ee141dd1b89eb46cb5e9da7537f63b77523abab01e9574ad161a911a896b867123735ad4c98de40f373bfd62165b0c737953c8c816c27142cd245917969bce31163936dd6680031e303c4086e9c8a6de7195c51fcdafaa9626f4691f201eb851e943c2dcf5a5e90005783bba67b6478fd637e43b5dfefac385e32f640c2e3fe298873ade499d92cca544769a88ccbaedb5cd4eb5e8e7a431a7b10cb0dce44f411aa3a22be6af7f1ef5b93f96b39c28a818225c7961dc5879318e9be4af78d59150260b3b712c8c4c615e4f0558d5d7abb9935a34b4e8dc050990c4ccf01a0432e2397266aaa7a635fbf97199e3dd6cb8ab9ceee4d1843f01e42df99b7b94179272eefb5e7453450e17b2efe24e3b585fe8707101d3d26e7d169e7e083538693066a2cf45e25626f4766328ebeb180f4c9a80d5264794e3395ce216080940d8b2f6709d618e173e4c91acbf76be013ec184526dd9d99b2149c441cf1ec1c7daf170670d5df092b15e582daecf85d140daa23aeaa5008183d5ddf926b0c8ae0ca22a9c8e4093ad0df5874c69c34b912671057b6afeda2fd41e0e223710ba8eb4d28afe45de7a7bfdf7a5d6443da901e2c2c966ef093056c4f62c820c8a0bd8c9c28344c664db4ae049971d8f089bffc11fd4535874c046cef36fa7a398b3ee6410b62b59f2b7c91d2a1d851e94ed0af4367f3a9aad84e12d9fff68aac9fde91bf2223dee4ea05d3500dfaab6f91203b3ed3f2346f1462240763462d1db99e8bd205ee3afb116f9fa13790c13011b967994cda0d7d65a4aefd076870bece6b2b3f2ab8907218701ef6694146c2c0ea8b1d7f40e95f744b957dfc325397e7ef1382", - "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441124e9634ac86d5322a89fe272dd95ec8f0910e46f753f89c72c622ae351ae9ed29012c2b59ed2e47dbf67687e99852bec5d63ca1680e3ad65cb5c747a9c37eb900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f17b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "proof_hex": "0x000000000000000000000000000000000000000000000006443e4dd7cafbc6fc000000000000000000000000000000000000000000000009a5b11556957a2fac00000000000000000000000000000000000000000000000481d8c87ec8d9e44400000000000000000000000000000000000000000000000000027e3c69ce5a8800000000000000000000000000000000000000000000000c89919183396d2ee500000000000000000000000000000000000000000000000156b5f6351b4e1677000000000000000000000000000000000000000000000003fa278d2c3f3cc83b000000000000000000000000000000000000000000000000000257547a6577fe00000000000000000000000000000000000000000000000a7acecc082a3669e1000000000000000000000000000000000000000000000004e4ee60a9610ccb0100000000000000000000000000000000000000000000000139a7b0dc64569eb80000000000000000000000000000000000000000000000000002797aa349525b000000000000000000000000000000000000000000000000e4efb10408e5e22300000000000000000000000000000000000000000000000565dff2497b05203c00000000000000000000000000000000000000000000000c3ee606bf31b8fa98000000000000000000000000000000000000000000000000000144da9a140bb701dfc1ca1fdf6f4d4992fcf7bebfab3317fc2caf844b02fb8ac4436d5adea45f18531115019e88ab0ae6f13233c1014519feb8d5364b2b488e9d836182eba9d800f3b9f16b517a82e074902c3c99bf34e7be3eafddb913ebb2c8d05595a159bb2a543541d15947ed4f1c1620e84108ea3ec32503ad7d073162c30b94474e387c0cdcb845177847e28da58f2486d85540c5484ae86f2294cb46b4cb84d0aa3609083d483a8b920f898636ed7798e980729ee4ba163dbecdce8b02670604ec9b920e6c4aa8dca3ce558f7cec8fb7f4bfa1b0d4371b18bc835220613a1409fa080f120c539f947fdfeabe4f2a16449a964098c614d6fc20e3e80d0403f0241f5d8a13147d749da88cd2a0d8266d4380e5070e0fcf87e2e312a3cdb01409afb8ce082549d88678d5f866e68a4d0281b41a6b539a157e18a18aa47a9d801ba82c15b4285ed10e2b52a839fd1fb5a55f8de22855f4af96518bcaccc2dbce494a296ebe26360d30cd1d486f49978b029766d49825f3c54d91bd255e22e279a69caf0742070495855195395e1742793b60d1378c09dc9c7053216512cbd2452209ec4be4071c5a521b696e975b1060278c4f77f59bb6ef505a7223d5245c2faccf2d7a7b17bc6a08396d8036223bd5f0ae7ed2f2891a3c4e8846b79bd36ade7b09fd6627114aa182ae1731eb6b9cf19b8b841c3c2b6d8056888915d6f3833646d375991e22759e6ca02fd6241ed37565eeabe5d1c1ed7734680293580c5485cae983d60911a42e17e7646d7d5bf1b3633d1bf857ea6d0d6dd6ac3947070d93be4e391a921af9366211aa3384aeeca7a871208ff44293b9bc62fc7a31c346b3bc0a41d8ec2faba055c65299d4680c399879ad3b09b91ca75c154614e7c2365c05d9e1e1bf0312970f67ebf20490f3b18aa7c84bfbf44044a62091158a689ffb7eff443a0d006f17dce991bb9008594904f9599b39252e57e6a7ab50656c9e5a8df72b58d51b7c9f4435e6f52a478dad1fa0f66a4117c91477773fef118f1a5b2e2246a83126b004cc496b97eaeb0939d7fe1fe9df4c45268c13f7acd87f8d7a7251397537066d564a275044ff3e9013c7416550403fd3b89f31931a1c9bc4c78890d6039319c12ba5bf473841715e3058c08b58f6c885980ccb7196c78fbab8bfc448f50b23e59de65950bb9e7523d7c99364b96ea7e2b23207d02a56f9a6ba47ffe607b0110784790f007d11c1a16dfc27e06e1ca443bf4740ab87fe60bd2e4719005c8706dac42041fbc232faedc6e10c6a6f75b3fbc206b8f7c1648c1104fa3deecec91ef7ed44600c3779a8af114f9e25af821788f45bd741c89b36e53c6e5e6e983e23f372c640298eb2ca3865a651b2add2714020d6de218a78a66e53d5eb9c037921c9f13da3795f03f8a780a09119c28b795e6e6b97d67250bc77c40a81ca7253285c8d29c99aecf5b4aec5316f45c7934a7c13e79ba5f526153174eac6f0fa7f1d5423429dd2204d5a0749d4f1d72ded1463077de54e2914170e854d559814782791a449f5831160a02643aab224d9ccadbd7c12366cbe5895233711003e08701b69ae17495eb9c96cb4741fa95d3a2342926bdd5a796de050b055178f9e91ba2582ad1dda122e9168349f910fba42f2389be4035b6a4a0776ec380eab4a7e1818da3933777a20728cd32e8aeb3f6dc1c954b5e7ee588996ffb14ff769561b1427200b52b53eb0c2aeeed7d7ddea931eb9dcd23c5652b768cf3fbefce53500b8030754c5c1ca1108f3ed46afb942bfc01b032b26a8ba44e62c0365ca4033b1b219a80f8a2ca3ff9ad952bbfb2493969d7eaa90cc4aadbcbf36dc76a0c848bbed2978369892c56259b660b0a07ee28fba8b592f129d029bb31b80535d8003742403319cbb781f5e4270e2aac914ced8a3fbbaaa3d9f1e834bad9b9f07b44814681c3e7cf0859f312e121eee65169a441b1dadc576870842c917a36a744b4f4da91c33208fd45e9c462ef67ea2f432b555a46ded01dc8ac89fafc61142efa714650817710edcc68e99b475b7ab403a6de405f94656a27d39fe369e561b26a5457c2921ad7d3ef554ad5330d553e322f95d5c40c50efce4a009493e71875eb2182d0f82765a780330127718248a51508491c0d2bd80766fc4007dc818073c337f882d78d25f805d23f12d1db526fca5ffb5be0e54a6ec25e46bbda65b6bf5aec648184761fa18ff033b31c97d42fd3a43ff3f7ecaea4d304d336e0e917a0d2e4425050be6d7fb830cf4562eb87b213a5d6a0dfe7b3d63f8e11e3b1efa9411183811071ad9e3d533211eb93739574879ef787af1314cbf7fb4e874c3ce87ebf8c3f60f93f0b8ef56a6f27811b193c26971d3e773e76e68c5daf56140ba20f67be6242773bd78452b12738a0ec3b6204e93c9377acc0358971d74ac9bfeaf9245d9421a7d20b5a4a2ecd40e4d23d71ca5a7e131b932acc89bfbd6866b38719ce78d212cf028cef1628129d642240f4b2730357494ac27446f5e56c0978e0c2fc239ee112666f0bee00ed47f0164d22a5215d5db82f3ab6cf249bb50703d3dc27d71423028a4f72123edc079901ef7ccb56bef61f6591b0477b23cb07795773f20e2bb12e5e0ef459fea65851cfcc4b387fc42cd5e71bc089a7f4381c913855a4f2f1f0106cae843799f89fa4b279a364f633a37e4b2640c69857e61279dd803ec5c6d039606c9c10584fac7c1d5b10de7b25738d89fc5569329afd79e885fdb953cad2cc05964e713e4c71e4c07ff1cd10c406ff55cbd851532a4839738d7227ed257241f748badd25148e8ca89366948ebeaee84d613987f693e0d213aaa594db3021fe702e566a8ad2d75ae4f812859398669a51eabc475fa34a0d77bb9611932a904ba84084825294979e0ede81171919e8bbab7354cd01123a8d61d9548b311ce05d765d5f5322a49e084b9796079b3196f5a5ef6761db7007dac93649c4a387d02a34ad68acf136903543014ec4b3d4a3fe900211ea22ea18eae5100b319d329034f88cb7f95f41dded0a0ad75b68c71278a61b51c19c035158fbb8259d36bd505735e825c6b8f845e8845155cb93ba122d3e98c3db8da44666609cf7192ff0d15d728de03a78427d9b166b5ad8555e4b65afb3244bd53993eb496c5cd50833d22341df3b6674d72bb8271c4b82e7f03740f15b18a7ce3fc8943f81f826fc8fd227bf5ff41b0989a237271e140ec6ba99a0c2c913033c1dfa00f9613114733a42111810a91eebbb5bea13246518438196d97dabf006219b2203cbaf73568d7f8077e01b07756ea1d188ab0a2d7d2b901634618048e281da916256acd484950b7175c097adab59b620eb4718fc51493f0566c9e30124ed27baae31fcb691fce092acd8a3e8ea251794afe8d35d55ad7037ee89476c111e04610f219a1aee124c22ac4339cb28af586a14d986b328dcbc25636df3bd150a77cea7298745cb7fd6b2ef63e7413dcaf3505f98d6569f1e4c8f3d5082903c2a15cacd73e75fd8df54e2307f9e71217ebbcf22bc61abcb8690a22409214cd7847da52e761f7ced049a31c763c92153a0b2904739905c9cb26452f4f573ea8f9a7740b72e854a50ec596115078a8b11c57010a27a043652ff97f51ca448f30614810e3765b8a4149a63e291d1683a4b9a0b964f6ffece7dfb0cdf1c4ce4f0fc04be99672261f50284503148cb9351ff4662a49ec4803560cfbc9165ad379fc90ce53beb5ab320807a8d91d0a10934a2b9e4363934b89c786d314b1a242e9128fccfa473dd4fa8f8496710aa112f31617661961f5e97fd2c3fea061bbfb54946e7687ec43dec8861421bc140c7c1bdb0a3d9b5909cab572d3434a2431c3236a57baefb073fd1bc6d6d1912532702a84570676a2eb0d0047ac4b2bc9fbe5c927e3dceb3c5c249d3cadcbe929008bdca758870e554bc839114d0ba80cca1fca48d28166f949e52c54e6928b1b9605ffb5f5f6b3db23931f7e59b994d47f7c474a3564aeb179664ee01f91770839111d61a992bd1ce5fe02631dddf3d4ad212e79a3aa20c635f97ea8d6db1a1bcf6ec685335f5a88413279438d62e691fc5848efb92ad7dbf44ea4e6f23a8d20414139bc656a727e0ebe69c8a9dc3802d314028e5a8643622b705ae5ae82e01e2578c9d36a252ed8138a7aacac14849121aaba10a66d6ddde63431e9bae2151950ccdf9487c6874ba926706e38df897c4ca3183893c211c3846182cd2588da2d398a58df3e979a559c498fe06a4a7a0163ee286354b8da07da8b9eef9945c618800d7ddab549c895cc7e2ff3000f1781554884bfeecb44e4124d603ebc19b829730a60168980a8fa287fc8f86c0a8a90ab8f38e71f804bba01d8365d1255930ccb79be29beba86407961ab765e979b3dafc32bb1f393d16702fbc3566aedda089832173ca5a7e5069fad1e0660959d49e0bfefd74d2314b393f2fcccaf682a22bea10fe8179d3ba752e8044853c47f4683b4310914f61e58b7a1df42504a74113e6facddec9a9ae5b220a1d6cf4fc0415e9f725e11104af98a7018d5dbf4b5132e8a07a7b4803847e32293d13af6a33d297cf15e40db4bade0a4774ac86b0b12fbacf70560a28f3f7b4db8fa73364a46bb2eb57964005bd8e58c2e61eefb861e701eadc30caea24196fdfaff46b16dc10ecaea90bfdcda36bd80ec0f006d9d2e1bcc89a79ee552a9d1d32fa60bc21ea126a76871ff91f479eebbf887884f360274da76723b26de1d7a5e8ce9ee53c7bfe8b5f29ec186a407e75ca0e3d661862b867f5fe4b79871eed93603d868ecbefd6a9b1188007d91ab5aa9944fde3f6b18da6194ed89cde701078d634b6c54192dd528fa637977e5c3675f4ada2b502e13be091100049adcf52752f514bf95c3fe99e4e20abd509446b5fc66a8857e1d2001066787b655dfe8931150d5648b382f60bbe72d6e66c73e3e6529d54dcf4811cdcc0314c615042bc66bf5173485c9881e9544493687da1731b6293a9679fb04b9622e9b578c81c7608e01f3053cef3f632d4ef5a58f172e8bf12259f6d5f21e25a74e2fa134a379f6308d57c51335552484fb0e88867c9d243bc181a090cb031f58e0fa9f655929adfa77a05baa4894c7de6a6d37290d3eb16283ff637dbd2fdb3500df9f2418aa9a9f250fde66f091fb6ef5acdb61a27902e22fa6d5fdf0057d28171834d980f73ca8ccbc0b303a5062a068e03e7ecfea78e72f78bf920d00be36994a8ee4f42a36ed3a223fba9826a967f946e75760a85a595015b8af2e24ad7c59e99b87f60a5fc7c76e351614576c43732e32d314ddbb85daa881eeed1b150a822d9945663292ce60728bbac00dc5ba3c649e814005a52df5c0fc59b81011cfe6bed95a7ff1808bf7c6e1984dcfba5975ca1768a00381f2974a32d1151e75c2894ff4581c65de16e354ddf938c056c93a50c61579815a9f0282488c76145951a635f929a71f8e662224c9364e12748d715cbc7bc93c5606f07687844222416ad582df9b9091bb790236a28d090291602b43b80c146036ae1d2d3c911123f37a291933fab7e30deea52324ab9ab3adb486903c9960992b5ad8cf6d89670e608c9b4061890a793116ccb7fbce38857e020824d1db42f14fc651164d22a60aaa8f2ad0f20b63778277b1f641d7fc5d12dae47ddfcb2d55e6b870d8b2814c20ffc73af5fadee89dc3b3cd116e881d5c768520e9fca681290ab5c58ead371022b65ed2116f353e440fdbe5d2fdf3f025e2a6d2e9d3e94c9293ceca8086b0de285a7305750eb30cacef7b5469a0797e42080970c0c3e70f990892b6ebff1044023dd8d11b77a419b3aa19d4bdbfabaac8d553dc042fe6c4555b6a14fd64ec980146ddd60ce32d76980b01b71eedf0bdee8b18f198cc0255d73108f17b509bc13025bafa936bc61579f8c1a9930017d1f0b042c5bb0566743b6c731e05e3bd7d1cef12b035210c3ecf81d2caaa99da32fea59317e383b970e419f861ae2573fd2b3c6b4f0c1ca9dcd2203e4b1be938e7838f970bbbfe78707468e381083605301c190b6c5f06802b1dc8b2280acaab86ac5046231ef1060033cc35ee76fe2baf2d661ab0c19ad8987ab3cbb89c97f3c6368ff099e09d1febe8e7f6ecc1479f972b5c27cc320c875b5f129f3b6ff24b4c8a2eb82af590659ba225f3e190fa4e6b1008897acc6e797f4357055c26eeec55360f23d1da9543b6ca7bb34519652626273e877efaf30df25e18578770476876265c499564d49f34e9f6a51e30b1dabe0c32c7acc142ddde363e9e60696c0fab4def3165b7cf5799816352fd5147cbbd053810b943836eae47e715380acaafecdaa5c56f78ad25cd6beb48b30b71e97224546462e575474e305a384c11241bfb4922692f7ada05ae8ffe3eb5a61f4a432346ea3071cda58fee452fbc4db70cd573ef7d17106659050ca1418bbd2681da0af56fd4cc9e2c6418372609222d7387c272a336e2b34a001899e647750744331b117ae4529b0938e4e4712dc5686b6caa250480220d3e94a35b9632e3a73fcd126572f8c3d4ca698b890cd2cec074e5e7a8a7f6f624f385cd36b9d21144013e1d4d49e7dadd46d3bb09ef8d4358a93c905259d943a18b6a020e9701b77274ef12ca1ec8b6d0d112d3b1dd49f29c7bc13ee5e7ce00c1e5ecce92a8c5b0b5b464094dae99c3561ef02693568d05c04104963444dbfbe0e6cd804ab19753689d2f1254bc80d6a1dde41cae49945131b625cbd58bdcf37f4cf699f10aaa7267e1d62acaedd0bb43e6003a32c7112ec16756df55e6b945e730898cfcbaddc25621cb0f3ea6045ecd0c18e3c46ceeee924bcd8b5931869ec38afe8b79b6dcec6e649f26fe612ab89de39ad9fb9d355f67b6608ea70697d9f7125cfa4831a71b894a0a0bf5eaba34f2e38a421e11ed8e30af9a02bac691e911dfd2c5cc8bab6fdcb23904e79827c342bca3644d0ff0be3bb71ebeddb24e04066ab1b9fbb82705a3266a1b742992abbea7a4b968075d5348ff4e1068b01de9997679713f13c50b558d69224e93ff28adec2874a0f0131ed5937a9a84f1a1d27815ef6d4412936fb2d9ab2c9f461e5eb9aaf0b937abf2c25c62926c3052eebbc13a311af28dc949296b271595a279367d738f840aab4617ae5d46cf23b6a6f6b932ffc79d71daf27bccb2128f76718008bc6be9dcdb3c0b25b5172b1da3752ebfd6f9ea2c8c609d906b690b01c120df01729bd22d73b94dd8afa3b34ecbe74d60ea6d449c60645f1528622ff8a547dac1025fa5fce863dddc98f0b30fad91b413d57072fafb52119e58ca1516eee808b2a74efc1cb43944b1974e17032d21093d286720396ff7399fb63c1f79cd6a75644f67501af7e6d876bc562174d7fe4eb0434c4cfee35ac6be75ac1820791537c5df12a815ba14d92b0f4fd6d78169fa6451cfff0eac6ffe080c5c2bd37fc059beb2f3793a7cff7025761e181b81ddd54b11acb6032db51a7a8ed713315f3711ea9f0a97830ae8b36494b8543ac9b862745c4215db849ec6a8fc6a1c5ee285c997e54b3c9fa212c4eef18b07de6901258f3ccd0dcf9ae10e0cec6028fc22b8bdd77d9f5f5753eb121e13d18332b7ab5e4e1b8da6ed82e9149a8261093fe0c9ae8dea8f167327c5614e10282a690196332af402f400d795d62b79112c1b39336e2d239a9a003fd684b32c1eabe3d12736033faf849ae7b6d13f44770823917fd825b94292e2cc911cc0bd9f55e29597fc6463429b0e3113ce09bf1223150eff80c462c613876c1afb7506910c9d57bcc4294dbf2154e84ded32aee02db67e7e6d6ef0b310397c49c631a159f637d7b54fbba46993bde91e06229569289dd10aabdca78e37e5e65111201ba9db43a5d736d09002d9bb979ba354884f0ddc0e655817c6eca1bf4e8399e6059ce13bae13442905698486b29df39028c226fa402d682da8022ed12079080cfe05a60c2764aa1d7b8ce819ef89b73474a62a32750b401f56656c401f6fbefb83b3fa391cbd494326e63cc172aac33ea37c2ab915cfa8935f6c1b643657122c82828d974eb995919f27f9045f1bdaed542120f563c340c7534d63bd89254d5aeb0962d72358fddf008461ffb28c7ca3331224a274f4a23db46311983cebb2a0c25c643781c581dd1853a98484e7daa303272696b4c3fc3250899de7b73273f0cb8271959eeba9f47d6f27845142bb5a30241b037f5bf9b9a97dc46a8293e61834ce50f783911f3be4c332cebb2a1254d2d02770490657b1d03830ed3ee8deb26801236387b361c6422b4119a60b45c17936281de0179aec58b237faadaec4581354ac0fe01e42e4aa3e7d9660abff18d87106ec366b781a8e7b6815aceeebca6d1742fa5b320e1bbccd556fcab55f5df0fa25613aa330b14f831113d7b0e58ce43bf10ffbb5922d8037fd6e8895bec323a41dfc55b695ae69ae883e77735dc097ad451c8943fcdb85658d42a356aa45a10d079f8b8125a7b007f583ba170dbace2b0baeb316a85c9992f4cbe7463bf97e420595f7e9889b31842f7bcb87ee9e1659e67146d3eb1738237d580ec4057b010007e11de07d72ef853d011846238a94be1d45b6af5221dbbaff5d7f2b345aac312ee1f0ba76c97dc811aaf550748da69a8e703e30d162f6c4d5e3bfb584709c610de2f1e1324166ce349aae1e7925db177f435d4dea9943c13a1a14583bc4806811ec85e76d455b6ecfe19375719b71801e53989ffd31d68393958d5db8d28f5e23b717a3076b3f25ae79b373b4c2f8b74ea54e68d5b611508ca732b86b8e682d0d2fcf22fb341c462a809a437c34275a2b1e99cd2f306ca0e5c471513ca2636b189a2f7b2fd610eef2f1f564c494ccf64b450345ad58e46520438d478c922304080088b7ac282721cda9cfa89dfda2df6b663c9e071514b42a6e3e3d3f4b8a382289a0b58bdcc4d9e19fa811d6cf64b4a703bd072cd660021d4d515e59e6df6b3046f12a2efae22d170874e2650dcef1a24d6974f77cecf09d6fbfd8b34feeb40652708e4d2e7170b5938e06b95d7239537f7ff192bded21492eb0b817d58b4d165b06c7bf692e0321aa3778a74dcadc77994701581806ecddaadf49f7104e7f0bc5921a00718a37a6af9d199e6e7d94a2bf032e92c0eb564adf2a7fc68f24701231b482e813783b1f35ada11c23433530cc7bb6fb050f5e9ecd90b18268a629098693da7c2767302986f142e06ccea3467126f980182235dd26f84f3b4168402ab0ffa139de9f700d94fded6ef3da03e6137e64131ab66dbefb912545cfd9ec2140d43b2b04494a1cb5de412225c593576471f8421345c6461404437cd50bdc05e52284204951c094ac5183937c52eb1f89d5efc2ddad671cfaee747cbe411027d28a630695a70bd84e6c8f2204baa7816303b598333816bd2e069cdf2d900c25394ac8abc092015c03de91897529f88364c5920c96d79d36adaa49fa4ee79a1acf5eb5cc8c68c2d207e2c00a4be93e9f7f68fbcf3b22641cc46af5b00e468b266253abf616d8a7219eebf4ed0c186804c9aa518e6498a95d27870b09e9a7910d7d2897abb953838358a1c632c883fdf1da7f014a0145b925a4d62389afc2d21d320b72198c16c59816aa7980f35282f8161997479712acfcbf2ae7fc939048221d36c6e5386de18e2e31bc9151bf31caf26bedd9d9a294b1582a0ee1fd54da2b29ef6dbc542e0a402324832ab4a568d02661bee1222aca13a8b8fedf6d1a212c033e3b768116702bbd085431c7df39c570843069c428878590357edc235a0d12653312e04bbf99f98c84e15b59ad2dc98ebfbb620ea25d8800361638225f0f26fa394aef30b30116a967ec0c6a1fd541f82a8091afda6a6d6efeb080c1e0ad26577e4b645ddd36cb9658dae88d305d1fdc55f0015d1b457fa072d4873e8fdb1e81db21d53d8c4cd8c3d14ce58e0a65f6e4f36053c3c0c3243d19046bd8adb80790a527dbc5ede9d8ecdf60de807d0e924b52c138cd1ac03a04d8e88d07c6de29ec091c14d2da49d5d8782121da331473e86bf1bfe45605de793e288bb1aa71066aab84a29256bd7b881523d47ecc983a2aa4255097c5898bb5af93edfa26d5015bb0c6cd798907d7713346c22b48aee272d38248ae714ea7ec5b82561ad2311fd201458f45a4dd86e7a0f108886af9c8d7613617ef0163f18e25aa9ecb792929c4b0889000b9a49cbc9fb16aa12d3cfc54184f17e50144038d3a2a3626f31e2d9fbc165df3f9fcd75d9e99f535022ec91b19bf7c24a033acc8944dbe79ccf224ce84f0ab04273fd6974069d53931a3a69ba7714be5da0f234df46855e054e8299b8a573817dda6b09843956df7a0e2e21d4ff9d91853431e11061482a315f001d434871e69df4e1f24275172d544c130a1c6d40b3bd6b1d7a3d4520217577129eb8a792342940a31d20af3a99f0f4e005da9e561e5237598bed6ee3ee3820a170ba23dcdec74b1b3b461944639305c1596d3b64c83582a758a345624f51be201d7688c69fddc0ff0eceebb2de6d06dfd6cbb7047857b1ff42f680eccd1ac212b73a863059add2efe748ac8971207921c1195f099f9ab6eb43dd55a303e7cf52525392301fc899dfbe7408424a67c509243e5eccd4cfeeeb00b78288506331f06eaa5fd76a09b44f56feaf2d7af4d23b05308b70ccd0c1d5ad8ad1d47b6ed200fc31fa90f5a3102d27b3b1245948561a7259fef448d208a4d87472bb58b647024fa6e040e10f43ebfa76dff924cd8eb7b20dd80bd5e8cf3253fc75ba2921ba21a0ec8828f4e0b8b951041f4e6b816ba41c45a187c8a6434614b24a67aad33d81226a98970af6c1c254981f8fd1d3325244b579ba13038c2e15e670049d7add31e5883b5055d27d3764f707a699a7c34dedbdc2dfa2388b865e81f2f476a9d74033cf6829ede66868d1df503a99b0ab65dcc9ff4581d674e3cc0edd62f6144551a124eabc55b48029f4d416c598c41215d2e3517fc86598aee3d3876d356fea301e68d91f485409a6939dd9136e8ec513ec47d57cfb3f3e0c130160725b15d712c4d57fb83fce70a48b1f42a06f7652f13a403c42e096aeffd06aa22ababfa6f16f60d110b6e2b66ea8828bff298724e5b5fcf493b2106050b85f98ed06491ac17b4c24d508d47a33aeff7a156692b0f923db58fae1b5cc154be223e28cf7085008215ea995ef6c42fc4c9fbd66a6bcb70b2b38709054ea35cd475bb49de59e10956147508ba2e4fb0382e90998b369f03ec4b14d8d41369fbac5544b4139cbc2bd1cb184c504f95bd229f7df496b1e8148eab68ff7a47356fcb4370c00f9a452fad6ce685e37ef2fbe60c09063c8269b6f4a4f58501bcdd6516d59ff13bc307194265fc4a499426ae6b3d0dbbd38289a438005d3a1230768fe7f22a6591d73c1897db709e4dddee2ffea8f9cf5f7505c38eee0e056bb84b077f668fa3fe29441212919a9819f2e3e22e177096168d5e245ef96e5c116cf5c79748d55620b9901ef44b6da68ac3effcce28cf482c7117c35f4bef183e4bbbc96512a7fdbfe0381833ea263ebec528a88e53d624614b2be689b4755ffb1d27f661b4f5a41301b90dbebf58ff3eb42dbd35814ea7a002d1e718e722d9adad207374586887a5224a2e1c83282cc07d6cd0aa8d1c5758ba79462ddc323bc3bbb930373ef1c53b92ed2d96d4d238155532d1953410af79f3d08aa233e2fb256778a04dbdd925e7bdbc182a8858a15071189ed105aa6a222a7a4ffccd9aed35c4d7f7ba647273e2393025bcc927bc2fd289d1e434e8d15d038ecef09f44680b726df17fe0aab28e386d24fa7843e6fa06f472c82dfaca32d85fd582afd60ad817bfb11b3cae843c751e02776d66f8bf51a55acfa283bc6442d185512af1be7154b7a2da03abbd4a60c4127af50b915ec98859d5c684edf56b08cfe66418f2a5889f9b3a87aef425f6950fe98c14c6fe622d1d1c2bc47cfea2b721e97c8dbb1d9cb37577cd019545b71f0285121e51f77094251805dbd8d085ecfe8ccea6723dc062bb3fedf7c50593b0205922a540423bc8c3d5e42569bb2e7247ea76f0336bcbccbd1186dc9ce7482d03da45465c43bd0de56532970355c7ef777b177c7fe6a7532f317a18f136fde2224e443ab209e43f772d8074fdfea3b067c5381c65bb75025ee3f9dee77ce4dc03c743c2c27d44ef52d099e299389080c52600286711e9e1c734dcdebff96c9219ba0fc80d6ea186e6c29dc5c3191ebcddb75f9a6fa142abb71b0eb24ea3fb870d74ad181209cf52fb62d6a0b7c45d9f539812c01d85dee2e3de2131e9fc0e9e2df8e785877d96f7453353cd8e66536472753c38f34c924a11f9bcd3e1df5b24225211c57d2be13d95cd10a32f573bd85de9b70bda007117fd932d6670a44a0206cebe7808618526d6bc0230034e66ce9f7e8f7696a54be414b4caa9cd0855400c5b7787ab19599dffb8d491cab2af3858179c4829812ccfa8950148db8b0925224e70668ec89f91317e477701835166eeac74a894791d8eb76b1baaa550f11216c0fd4163f586a4e16ea766eeeda37ace01ec98c628056398c52e154fb4fa782f2af6aceeebd78d7f15b25ad97c9903deecb86333fab6be68bd8c9ff9facfe4214f0826fa40d3f55a50d102bcdcfa14680605bf36c2d142623c49239b8c22c31977245235b6d40d8c19937dd89007a42e79bc006ca2dbd5457f812fa1f32d9f1029f5a1a4d325d1518f606530e4b5d112c7fe4fd991d78467c24a0487c346a3258eb48dbc8290f47244f0dfd8152f2c2b6c12d1825bd4ef6c35da4a958ad6db192114ee30ab3d73821882eb27c746bd064c8d29a5f970c77faa3b11299f4bde099787744f327baf3422124943d9662f27c114be514e8c81cf618c21a009e2f82331c0ce3f8705e19f585abb4fd7adf1b9718854ad54a8bff4281e2dbeea99271874da9862988c3799ddd9031aaf478420767989fb32ad7577fa16523d27518e0a961ab41d2f1a80097e95d8c03919749c46f05967906ae8cc3ea5de2d4f25d8110ada472dc029c62964550f9ce1372c049f582e33fad78b81872c25d5e7c0521a3f7c7a4873e16b9def6fc5cb6b8bd7d918e64498de20f4de19f6d0c344e526175ab4d28c8c1f400c5b7b8cc871003b1d5cdcd40bb673a700a1edf8281ebc4a0e3721c6515c27adbc7da9925914ebab3eb9dae0cf2200cfbde8e446c38d7bb4295bcad28c370cbdd42eaac458f3ebe5cb7fa2ef98f984babcbfdf06f34b8f65091ee205e13701a1c2ea8a843f5c4b6efd809fcfabead21b10bde2d146aee526215a4fe1159a4d459d3e0016eaf546adab9cdf32bc4379606278bade85a725f7158a13d111c9446a19f6b0bce14bf1651b10bc0123a2a09faaf6919b112dddaa0a0ea3a4ecce723e76ff8831e4cd13d7424c4be81605104116740d58fb086a712e326db739292746d1985c1f9ae8899358e00d533a75efb5d7de1ad2742836322d49011ef90a17d991fcea02ac3274e6b2a9d8ac45e7227708a6ff1b1434586a11db76e8211ddca3020b2850fb31e09acc20b25a225d945840db8f189168aaed18b1ffa314189d1a899b0bde3931abf4178309c5e553cd375db69e22ba0131d8234633d63ff52a14b8ee82edebff56b20612aaa1828f1836d47cd48a889358a31c2ed3975a00706170f68e5c4fcf468d90ef43d57ea3f28b737ead30045fc1be2f085a00fca043219f011f86030f7f33ac46e1f9796a788f6b1c600c0cd7f74d21781ea6582c1001799f2d348f46f6a81f723560d7e920c1c8fcbda35d6dd4560fbcc1e3fe95963b4b591935b7506b55e309523f6ef0372aa53f6f6f39a8fced3033a3b0ff7bf32b9347d397c052d1114065d98e7a107ca39c1ebb71d52d79f101b2e9d8bfa85029b731263a28b39c9f0e9400d3dc6dc1c9328a022a74b704f2000bf3cb1c7232b14fed08b9c620894f038b79fa0dcd99081b21527561ef27b71531fbc148df29328c03a958ae4a00e803eac930ffcffab30209fff34b7d3f79102a1b45d43dee8dcff85bda9102cb809b22e2e10f32f6af247f3cd2b5db032c29d5334d06da44474e388dba32fef58f6f41b64ac8c0ec6cfcd4dc3e0f2673f92e5b3ff63c00f9d5296e18b42d1abd074dac590e7c6e16d339e714a8168fe9dc14582423af2f47b9078fea487c501377206684605bcb5724e6dc63c1e7822abb0855c33f180b5b20ebb2b40c27267d315c4c2bc75dd5cf4a2a5bceadea37ed78153883fb91a526e6f2a716b7139fe0b86b2a8900372f0172f3aaf9ee4a2019ff06e9f15dcfbba8dbb9dd9f3a28e9f54bfd43de7e0f8482a383ed5b608df6cbb6107cbdb223a442c91a27b79c4bebfab136990c609a006f94a4b4aa357bf3b4d70581cb1e022e7beb4fec5b5fb12d0c964ae273eb8ab4dbc0ca9e38768d621b831eb161ad789abe47c91993aafa4250b09fbac7fcb9f489d93a0be0cc4980ac561a170026532a309839237bfa1081eae9a778f6b16665de3237f00c8124fa1fd3253636290e6dbe6eeae74358d67aec6b012104749f53bd345b362b75ab3b549d088599bea97a0c7955ee2b01338bda7d05c5579e6822b583147e1d0958e70eee1b1d6559c7b4a21947d81d6d7f82d511133b9ce051588ce4a1a3e381ab5775ad0a93dbe6e14e6f4d040a4aacb7864a1468b61fde0d2aad5d57f75c6f9679afe9", + "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441124e9634ac86d5322a89fe272dd95ec8f0910e46f753f89c72c622ae351ae9ed00000000000000000000000000000000d50b7cdf578f4412a219947e71659c0f00000000000000000000000000000000585506e2fc08284102cd3ce553aa726a29012c2b59ed2e47dbf67687e99852bec5d63ca1680e3ad65cb5c747a9c37eb900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002240e1f1fe5145cc75fe7b253dd853cded77fb484b8be9d52aaf0a49098afcc7d24e0b65d370477cc168e835d8143177b582294e4a47357f372f960754b56b54f17b852c2d0067302ffa20e6f7068292fa3304e6e20e60a0c51ed55a2e0c2a2a615de98a2794725029dd283936e25dbbb2d8cf00dc4401eac6e834b094e5efd8e0000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } } diff --git a/circuits/benchmarks/results_secure/report.md b/circuits/benchmarks/results_secure/report.md index 0f232b173a..c12e1bd71c 100644 --- a/circuits/benchmarks/results_secure/report.md +++ b/circuits/benchmarks/results_secure/report.md @@ -1,9 +1,9 @@ # Enclave ZK Circuit Benchmarks -**Generated:** 2026-04-29 13:43:47 UTC +**Generated:** 2026-05-20 09:19:34 UTC -**Git Branch:** `feat/benches` -**Git Commit:** `36c01c62b86e2527279842280337f2f4724d2487` +**Git Branch:** `feat/1525` +**Git Commit:** `e0d477e9e98185779250f4092947741e84169b02` **Committee Size:** `H=3`, `N=3`, `T=1` @@ -15,36 +15,36 @@ | Circuit | Constraints | Prove time (s) | Verify time (ms) | Proof size (KB) | | -------------------- | ----------- | -------------- | ---------------- | --------------- | -| C0 | 287764 | 1.46 | 25.10 | 15.88 | -| C1 | 2432074 | 9.37 | 27.22 | 15.88 | -| C2a | 3879330 | 10.95 | 26.13 | 15.88 | -| C2b | 5739750 | 19.54 | 26.31 | 15.88 | -| C3a | 3764144 | 11.16 | 27.82 | 15.88 | -| C3b | 3764144 | 11.16 | 27.82 | 15.88 | -| C4a | 2564001 | 9.30 | 27.21 | 15.88 | -| C4b | 2564001 | 9.30 | 27.21 | 15.88 | -| C5 | 4395328 | 17.68 | 27.28 | 15.88 | -| user_data_encryption | 1678200 | 5.81 | 25.70 | 15.88 | -| C6 | 3001847 | 10.47 | 27.29 | 15.88 | -| C7 | 128310 | 0.53 | 27.59 | 15.88 | +| C0 | 287764 | 1.47 | 26.17 | 15.88 | +| C1 | 2432074 | 9.49 | 26.53 | 15.88 | +| C2a | 3879330 | 10.88 | 25.37 | 15.88 | +| C2b | 5739750 | 19.44 | 25.98 | 15.88 | +| C3a | 3764144 | 11.33 | 26.23 | 15.88 | +| C3b | 3764144 | 11.33 | 26.23 | 15.88 | +| C4a | 2564001 | 9.30 | 26.50 | 15.88 | +| C4b | 2564001 | 9.30 | 26.50 | 15.88 | +| C5 | 4395328 | 17.56 | 26.87 | 15.88 | +| user_data_encryption | 1678200 | 5.98 | 25.90 | 15.88 | +| C6 | 3001847 | 10.47 | 27.66 | 15.88 | +| C7 | 128310 | 0.54 | 26.29 | 15.88 | ### Artifacts | Artifact | Proof size | Public input size | Verify gas | Calldata gas | Total gas | | -------- | ---------- | ----------------- | ---------- | ------------ | --------- | -| Π_DKG | 10.69 KB | 0.41 KB | 3037922 | 175556 | 3213538 | -| Π_user | 15.88 KB | 0.12 KB | 2972869 | 193468 | 3166337 | -| Π_dec | 10.69 KB | 3.41 KB | 3549077 | 186764 | 3735841 | +| Π_DKG | 10.69 KB | 0.47 KB | 3042688 | 176160 | 3218848 | +| Π_user | 15.88 KB | 0.12 KB | 2972893 | 193336 | 3166229 | +| Π_dec | 10.69 KB | 3.47 KB | 3553795 | 187260 | 3741055 | ### Role / Phase / Activity | Role | Phase | Activity | Prove time | Proof size | Bandwidth | | --------------- | ----- | -------------------------------- | ---------- | ---------- | --------- | -| Each ciphernode | P1 | one-time DKG participation | 7204.02 s | 127.00 KB | 128.56 KB | -| Aggregator | P2 | combine folds + C5 | 17.68 s | 10.69 KB | 11.09 KB | -| User | P3 | per user input | 11.23 s | 15.88 KB | 16.00 KB | +| Each ciphernode | P1 | one-time DKG participation | 5158.13 s | 127.00 KB | 128.56 KB | +| Aggregator | P2 | combine folds + C5 | 17.56 s | 10.69 KB | 11.16 KB | +| User | P3 | per user input | 11.40 s | 15.88 KB | 16.00 KB | | Each ciphernode | P4 | per computation output (C6) | 10.47 s | 15.88 KB | 16.00 KB | -| Aggregator | P4 | per computation output (C7+fold) | 814.17 s | 10.69 KB | 14.09 KB | +| Aggregator | P4 | per computation output (C7+fold) | 835.14 s | 10.69 KB | 14.16 KB | ## Integration test (`test_trbfv_actor`) @@ -54,14 +54,14 @@ | ------------------------------------------- | ------------ | | Starting trbfv actor test | 0.00 | | Setup completed | 3.27 | -| Committee Setup Completed | 20.26 | +| Committee Setup Completed | 20.28 | | Committee Finalization Complete | 0.01 | -| ThresholdShares -> PublicKeyAggregated | 7204.02 | -| E3Request -> PublicKeyAggregated | 7211.07 | -| Application CT Gen | 7.75 | -| Running FHE Application | 0.09 | -| Ciphertext published -> PlaintextAggregated | 814.17 | -| Entire Test | 8056.62 | +| ThresholdShares -> PublicKeyAggregated | 5158.13 | +| E3Request -> PublicKeyAggregated | 5165.21 | +| Application CT Gen | 7.71 | +| Running FHE Application | 0.07 | +| Ciphertext published -> PlaintextAggregated | 835.14 | +| Entire Test | 6031.70 | ### Thread pool (same process as integration test) @@ -75,26 +75,26 @@ | Name | Avg (s) | Runs | Total (s) | | ----------------------------- | ------- | ---- | --------- | -| CalculateDecryptionKey | 0.60 | 3 | 1.80 | -| CalculateDecryptionShare | 2.12 | 3 | 6.37 | -| CalculateThresholdDecryption | 1.94 | 1 | 1.94 | +| CalculateDecryptionKey | 0.61 | 3 | 1.84 | +| CalculateDecryptionShare | 2.12 | 3 | 6.36 | +| CalculateThresholdDecryption | 1.96 | 1 | 1.96 | | GenEsiSss | 0.76 | 3 | 2.27 | -| GenPkShareAndSkSss | 1.23 | 3 | 3.69 | -| ZkDecryptedSharesAggregation | 18.90 | 1 | 18.90 | -| ZkDecryptionAggregation | 48.06 | 1 | 48.06 | -| ZkDkgAggregation | 20.90 | 1 | 20.90 | -| ZkDkgShareDecryption | 30.16 | 6 | 180.96 | -| ZkNodeDkgFold | 102.34 | 3 | 307.01 | -| ZkPkAggregation | 49.02 | 1 | 49.02 | -| ZkPkBfv | 3.84 | 3 | 11.52 | -| ZkPkGeneration | 65.13 | 3 | 195.40 | -| ZkShareComputation | 52.43 | 6 | 314.56 | -| ZkShareEncryption | 112.96 | 54 | 6100.05 | -| ZkThresholdShareDecryption | 244.37 | 3 | 733.10 | +| GenPkShareAndSkSss | 1.24 | 3 | 3.73 | +| ZkDecryptedSharesAggregation | 18.98 | 1 | 18.98 | +| ZkDecryptionAggregation | 48.34 | 1 | 48.34 | +| ZkDkgAggregation | 20.01 | 1 | 20.01 | +| ZkDkgShareDecryption | 30.28 | 6 | 181.67 | +| ZkNodeDkgFold | 78.31 | 3 | 234.93 | +| ZkPkAggregation | 49.05 | 1 | 49.05 | +| ZkPkBfv | 3.85 | 3 | 11.55 | +| ZkPkGeneration | 66.06 | 3 | 198.17 | +| ZkShareComputation | 52.53 | 6 | 315.20 | +| ZkShareEncryption | 114.61 | 36 | 4125.90 | +| ZkThresholdShareDecryption | 251.23 | 3 | 753.69 | | ZkVerifyShareDecryptionProofs | 0.09 | 3 | 0.28 | -| ZkVerifyShareProofs | 0.27 | 5 | 1.33 | +| ZkVerifyShareProofs | 0.26 | 5 | 1.32 | -Sum of tracked operation wall time: **7997.16 s** (often much larger than end-to-end wall clock +Sum of tracked operation wall time: **5975.27 s** (often much larger than end-to-end wall clock because work runs in parallel). ## Raw circuit benchmark JSON (Nargo) diff --git a/circuits/benchmarks/scripts/check_circuit_preset_artifacts.sh b/circuits/benchmarks/scripts/check_circuit_preset_artifacts.sh new file mode 100755 index 0000000000..20ecf8ad72 --- /dev/null +++ b/circuits/benchmarks/scripts/check_circuit_preset_artifacts.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Verify dist + circuits/bin artifacts exist for a benchmark preset. +# Exit 0 if ready, 1 if not (prints missing paths on stderr). +# +# Usage: ./check_circuit_preset_artifacts.sh + +set -e + +PRESET="${1:-}" +if [ -z "$PRESET" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi +if [ "$PRESET" != "insecure-512" ] && [ "$PRESET" != "secure-8192" ]; then + echo "Error: preset must be insecure-512 or secure-8192" >&2 + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" +DIST="${REPO_ROOT}/dist/circuits/${PRESET}" +BIN="${REPO_ROOT}/circuits/bin" +STAMP="${DIST}/.build-stamp.json" + +MARKERS=( + "${DIST}/default/recursive_aggregation/dkg_aggregator/dkg_aggregator.json" + "${DIST}/default/recursive_aggregation/decryption_aggregator/decryption_aggregator.json" + "${BIN}/recursive_aggregation/dkg_aggregator/target/dkg_aggregator.json" + "${BIN}/recursive_aggregation/dkg_aggregator/target/dkg_aggregator.vk_recursive" + "${BIN}/recursive_aggregation/decryption_aggregator/target/decryption_aggregator.json" + "${BIN}/recursive_aggregation/decryption_aggregator/target/decryption_aggregator.vk_recursive" + "${BIN}/dkg/target/pk.json" + "${BIN}/threshold/target/pk_aggregation.json" +) + +missing=() +for path in "${MARKERS[@]}"; do + if [ ! -f "$path" ]; then + missing+=("$path") + fi +done + +if [ ! -f "$STAMP" ]; then + missing+=("$STAMP") +elif ! jq -e --arg p "$PRESET" '.preset == $p' "$STAMP" >/dev/null 2>&1; then + echo "Error: ${STAMP} is for a different preset (expected ${PRESET})." >&2 + echo " Run: pnpm build:circuits --preset ${PRESET}" >&2 + exit 1 +fi + +if [ ${#missing[@]} -gt 0 ]; then + echo "Error: circuit artifacts for preset '${PRESET}' are missing or stale." >&2 + echo " circuits/bin/target reflects the last preset built; dist/circuits// must exist for this mode." >&2 + echo " Fix: pnpm build:circuits --preset ${PRESET}" >&2 + echo " Or run this script without --skip-build." >&2 + echo "Missing:" >&2 + printf ' %s\n' "${missing[@]}" >&2 + exit 1 +fi + +exit 0 diff --git a/circuits/benchmarks/scripts/ensure_circuit_preset_built.sh b/circuits/benchmarks/scripts/ensure_circuit_preset_built.sh new file mode 100755 index 0000000000..8def1bf787 --- /dev/null +++ b/circuits/benchmarks/scripts/ensure_circuit_preset_built.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Ensure Noir circuit artifacts exist for a benchmark preset (insecure-512 | secure-8192). +# +# Usage (from repo root): +# ./circuits/benchmarks/scripts/ensure_circuit_preset_built.sh [--force-build] [--verbose] +# +# Default: pnpm build:circuits --skip-if-built --no-clean --no-clean-targets (fast re-runs). +# --force-build: full rebuild (wipes dist/circuits and circuits/bin targets via build:circuits). + +set -e + +PRESET="" +FORCE_BUILD=false +VERBOSE=false + +while [[ $# -gt 0 ]]; do + case $1 in + --force-build) + FORCE_BUILD=true + shift + ;; + --verbose|-v) + VERBOSE=true + shift + ;; + -*) + echo "Unknown option: $1" + echo "Usage: $0 [--force-build] [--verbose]" + exit 1 + ;; + *) + if [ -z "$PRESET" ]; then + PRESET="$1" + else + echo "Unexpected argument: $1" + exit 1 + fi + shift + ;; + esac +done + +if [ -z "$PRESET" ]; then + echo "Usage: $0 [--force-build] [--verbose]" + exit 1 +fi +if [ "$PRESET" != "insecure-512" ] && [ "$PRESET" != "secure-8192" ]; then + echo "Error: preset must be insecure-512 or secure-8192" + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" + +BUILD_ARGS=(--preset "$PRESET") +if [ "$FORCE_BUILD" = true ]; then + echo " [circuits] Full rebuild: pnpm build:circuits --preset ${PRESET}" +else + BUILD_ARGS+=(--skip-if-built --no-clean --no-clean-targets) + echo " [circuits] Ensuring preset ${PRESET} (skip-if-built; use --force-build to recompile)..." +fi + +if [ "$VERBOSE" = true ]; then + echo " [circuits] Running: pnpm build:circuits ${BUILD_ARGS[*]}" + (cd "$REPO_ROOT" && pnpm build:circuits "${BUILD_ARGS[@]}") +else + (cd "$REPO_ROOT" && pnpm build:circuits "${BUILD_ARGS[@]}" >/dev/null) +fi diff --git a/circuits/benchmarks/scripts/extract_crisp_verify_gas.sh b/circuits/benchmarks/scripts/extract_crisp_verify_gas.sh index 1ebf458474..d4a6df7cf4 100755 --- a/circuits/benchmarks/scripts/extract_crisp_verify_gas.sh +++ b/circuits/benchmarks/scripts/extract_crisp_verify_gas.sh @@ -2,12 +2,15 @@ # extract_crisp_verify_gas.sh - Runs CRISP verifier test with gas reporter and emits JSON. # Usage: ./extract_crisp_verify_gas.sh --output [--mode insecure|secure] [--verbose] +# [--skip-build] [--force-build] set -e OUTPUT_JSON="" MODE="insecure" VERBOSE=false +SKIP_BUILD=false +FORCE_BUILD=false while [[ $# -gt 0 ]]; do case $1 in @@ -23,16 +26,28 @@ while [[ $# -gt 0 ]]; do VERBOSE=true shift ;; + --skip-build|--no-build) + SKIP_BUILD=true + shift + ;; + --force-build) + FORCE_BUILD=true + shift + ;; *) echo "Unknown option: $1" - echo "Usage: $0 --output [--mode insecure|secure] [--verbose]" + echo "Usage: $0 --output [--mode insecure|secure] [--verbose] [--skip-build] [--force-build]" exit 1 ;; esac done if [ -z "$OUTPUT_JSON" ]; then - echo "Usage: $0 --output [--mode insecure|secure] [--verbose]" + echo "Usage: $0 --output [--mode insecure|secure] [--verbose] [--skip-build] [--force-build]" + exit 1 +fi +if [ "$SKIP_BUILD" = true ] && [ "$FORCE_BUILD" = true ]; then + echo "Error: --skip-build and --force-build are mutually exclusive" exit 1 fi if [ "$MODE" != "insecure" ] && [ "$MODE" != "secure" ]; then @@ -77,20 +92,43 @@ if [ "$MODE" = "secure" ]; then else PRESET_NAME="insecure-512" fi -echo " [gas] Preparing recursive verifier artifacts (build:circuits ${PRESET_NAME})..." -if [ "$VERBOSE" = true ]; then - echo " [gas] [verbose] Running: pnpm build:circuits --preset ${PRESET_NAME}" - ( - cd "$REPO_ROOT" && \ - pnpm build:circuits --preset "$PRESET_NAME" - ) + +require_preset_artifacts() { + if ! "${SCRIPT_DIR}/check_circuit_preset_artifacts.sh" "$PRESET_NAME"; then + exit 1 + fi +} + +if [ "$SKIP_BUILD" = true ]; then + echo " [gas] Skipping circuit build and Honk verifier generation (--skip-build)." + require_preset_artifacts else - ( - cd "$REPO_ROOT" && \ - pnpm build:circuits --preset "$PRESET_NAME" >/dev/null - ) + ENSURE_ARGS=("$PRESET_NAME") + if [ "$FORCE_BUILD" = true ]; then + ENSURE_ARGS+=(--force-build) + fi + if [ "$VERBOSE" = true ]; then + ENSURE_ARGS+=(--verbose) + fi + "${SCRIPT_DIR}/ensure_circuit_preset_built.sh" "${ENSURE_ARGS[@]}" + echo " [gas] Build artifacts ready." + + echo " [gas] Regenerating Honk Solidity verifiers (dkg_aggregator, decryption_aggregator)..." + if [ "$VERBOSE" = true ]; then + echo " [gas] [verbose] Running: pnpm generate:verifiers --no-compile" + ( + cd "$REPO_ROOT" && \ + pnpm generate:verifiers --no-compile + ) + else + ( + cd "$REPO_ROOT" && \ + pnpm generate:verifiers --no-compile >/dev/null + ) + fi + echo " [gas] Honk verifiers ready." + require_preset_artifacts fi -echo " [gas] Build artifacts ready." set +e echo " [gas] Running CRISP verifier test for Pi_user gas..." @@ -100,6 +138,7 @@ echo " [gas] Running CRISP verifier test for Pi_user gas..." ) 2>&1 | tee "$TMP_LOG_CRISP" CRISP_TEST_EXIT_CODE=${PIPESTATUS[0]} echo " [gas] CRISP test completed (exit=${CRISP_TEST_EXIT_CODE})." +require_preset_artifacts echo " [gas] Running integration test (test_trbfv_actor) for folded proofs + timings..." ( cd "$REPO_ROOT" && \ diff --git a/circuits/benchmarks/scripts/replay_folded_verify_gas.sh b/circuits/benchmarks/scripts/replay_folded_verify_gas.sh index 4ff10956a8..76e0b95940 100755 --- a/circuits/benchmarks/scripts/replay_folded_verify_gas.sh +++ b/circuits/benchmarks/scripts/replay_folded_verify_gas.sh @@ -17,6 +17,8 @@ set -e SUMMARY_JSON="" GAS_JSON="" BUILD_PRESET="" +FORCE_BUILD=false +SKIP_BUILD=false SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" ENCLAVE_CONTRACTS="${REPO_ROOT}/packages/enclave-contracts" @@ -29,6 +31,14 @@ while [[ $# -gt 0 ]]; do BUILD_PRESET="$2" shift 2 ;; + --force-build) + FORCE_BUILD=true + shift + ;; + --skip-build|--no-build) + SKIP_BUILD=true + shift + ;; *) echo "Unknown option: $1" echo "Usage: $0 --summary --gas-json [--build ]" @@ -68,8 +78,18 @@ trap 'rm -f "$TMP_FOLDED" "$TMP_GAS_PARTIAL"' EXIT jq -c '.folded_artifacts' "$SUMMARY_JSON" >"$TMP_FOLDED" if [ -n "$BUILD_PRESET" ]; then - echo " [replay-gas] Building verifier artifacts: pnpm build:circuits --preset ${BUILD_PRESET}" - (cd "$REPO_ROOT" && pnpm build:circuits --preset "$BUILD_PRESET") + if [ "$SKIP_BUILD" = true ]; then + echo " [replay-gas] Skipping circuit build (--skip-build)." + "${SCRIPT_DIR}/check_circuit_preset_artifacts.sh" "$BUILD_PRESET" + else + ENSURE_ARGS=("$BUILD_PRESET") + if [ "$FORCE_BUILD" = true ]; then + ENSURE_ARGS+=(--force-build) + fi + "${SCRIPT_DIR}/ensure_circuit_preset_built.sh" "${ENSURE_ARGS[@]}" + echo " [replay-gas] Regenerating Honk Solidity verifiers (pnpm generate:verifiers --no-compile)..." + (cd "$REPO_ROOT" && pnpm generate:verifiers --no-compile) + fi fi echo " [replay-gas] Running Hardhat benchmarkGasFromRaw.ts (folded proofs)..." diff --git a/circuits/benchmarks/scripts/run_benchmarks.sh b/circuits/benchmarks/scripts/run_benchmarks.sh index 84d1b219db..c5a9a9f5d8 100755 --- a/circuits/benchmarks/scripts/run_benchmarks.sh +++ b/circuits/benchmarks/scripts/run_benchmarks.sh @@ -1,7 +1,7 @@ #!/bin/bash # run_benchmarks.sh - Main orchestration script for benchmarking circuits -# Usage: ./run_benchmarks.sh [--config ] [--mode insecure|secure] [--circuit ] [--skip-compile] [--clean] [--verbose] +# Usage: ./run_benchmarks.sh [--config ] [--mode insecure|secure] [--circuit ] [--skip-compile] [--bench-compile] [--clean] [--verbose] set -e @@ -11,8 +11,10 @@ CONFIG_FILE="${BENCHMARKS_DIR}/config.json" CLEAN_ARTIFACTS=false MODE_OVERRIDE="" SKIP_COMPILE=false +BENCH_COMPILE=false CIRCUIT_FILTER="" VERBOSE=false +PRESET_ARTIFACTS_READY=false # Parse arguments while [[ $# -gt 0 ]]; do @@ -37,6 +39,10 @@ while [[ $# -gt 0 ]]; do SKIP_COMPILE=true shift ;; + --bench-compile) + BENCH_COMPILE=true + shift + ;; --clean) CLEAN_ARTIFACTS=true shift @@ -47,7 +53,7 @@ while [[ $# -gt 0 ]]; do ;; *) echo "Unknown option: $1" - echo "Usage: $0 [--config ] [--mode insecure|secure] [--circuit ] [--skip-compile] [--clean] [--verbose]" + echo "Usage: $0 [--config ] [--mode insecure|secure] [--circuit ] [--skip-compile] [--bench-compile] [--clean] [--verbose]" exit 1 ;; esac @@ -125,6 +131,10 @@ if [ -n "$CIRCUIT_FILTER" ]; then fi if [ "$SKIP_COMPILE" = true ]; then echo " Skip Compilation: Yes (using existing artifacts)" +elif [ "$BENCH_COMPILE" = true ]; then + echo " Per-circuit compile: Yes (--bench-compile)" +elif [ "$PRESET_ARTIFACTS_READY" = true ]; then + echo " Per-circuit compile: No (preset artifacts ready; use --bench-compile to measure compile time)" fi if [ "$VERBOSE" = true ]; then echo " Verbose Logging: Yes" @@ -145,17 +155,13 @@ if [ "$SKIP_COMPILE" = false ]; then else PRESET_NAME="insecure-512" fi - echo "Preflight: pnpm build:circuits --preset ${PRESET_NAME}" + ENSURE_ARGS=("$PRESET_NAME") if [ "$VERBOSE" = true ]; then - ( - cd "$REPO_ROOT" && \ - pnpm build:circuits --preset "$PRESET_NAME" - ) - else - ( - cd "$REPO_ROOT" && \ - pnpm build:circuits --preset "$PRESET_NAME" >/dev/null - ) + ENSURE_ARGS+=(--verbose) + fi + "${SCRIPT_DIR}/ensure_circuit_preset_built.sh" "${ENSURE_ARGS[@]}" + if "${SCRIPT_DIR}/check_circuit_preset_artifacts.sh" "$PRESET_NAME"; then + PRESET_ARTIFACTS_READY=true fi echo "Preflight build complete." echo "" @@ -231,8 +237,10 @@ for CIRCUIT in $RUN_CIRCUITS; do # Run benchmark BENCHMARK_ARGS=("$CIRCUIT_PATH" "$ORACLE" "$OUTPUT_FILE" "$MODE") - if [ "$SKIP_COMPILE" = true ]; then - BENCHMARK_ARGS+=("--skip-compile") + if [ "$BENCH_COMPILE" != true ]; then + if [ "$SKIP_COMPILE" = true ] || [ "$PRESET_ARTIFACTS_READY" = true ]; then + BENCHMARK_ARGS+=("--skip-compile") + fi fi "${SCRIPT_DIR}/benchmark_circuit.sh" "${BENCHMARK_ARGS[@]}" @@ -276,6 +284,10 @@ if [ -f "${GAS_JSON_FILE}" ] && jq -e '.integration_summary != null' "${GAS_JSON echo "✓ Wrote integration summary snapshot: ${INTEGRATION_SNAPSHOT}" fi +if [ "${OUTPUT_DIR}" = "results_insecure" ] && [ -f "${INTEGRATION_SNAPSHOT}" ]; then + "${SCRIPT_DIR}/sync_bfv_vk_binding_fixture.sh" "${INTEGRATION_SNAPSHOT}" +fi + echo "Stage 3/3: Finalizing outputs..." echo "✓ Report generated: ${REPORT_FILE}" echo "" diff --git a/circuits/benchmarks/scripts/sync_bfv_vk_binding_fixture.sh b/circuits/benchmarks/scripts/sync_bfv_vk_binding_fixture.sh new file mode 100755 index 0000000000..353a68b3e8 --- /dev/null +++ b/circuits/benchmarks/scripts/sync_bfv_vk_binding_fixture.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Sync packages/enclave-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json +# from circuits/benchmarks/results_insecure/integration_summary.json (.folded_artifacts). + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" + +INTEGRATION_JSON="${1:-${REPO_ROOT}/circuits/benchmarks/results_insecure/integration_summary.json}" +FIXTURE="${REPO_ROOT}/packages/enclave-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json" + +if [ ! -f "${INTEGRATION_JSON}" ]; then + echo "Skipping BFV VK binding fixture sync: ${INTEGRATION_JSON} not found" + exit 0 +fi + +if ! jq -e ' + .folded_artifacts.dkg_aggregator.proof_hex + and .folded_artifacts.dkg_aggregator.public_inputs_hex + and .folded_artifacts.decryption_aggregator.proof_hex + and .folded_artifacts.decryption_aggregator.public_inputs_hex +' "${INTEGRATION_JSON}" >/dev/null 2>&1; then + echo "Skipping BFV VK binding fixture sync: no valid .folded_artifacts in ${INTEGRATION_JSON}" + exit 0 +fi + +mkdir -p "$(dirname "${FIXTURE}")" +jq '.folded_artifacts' "${INTEGRATION_JSON}" >"${FIXTURE}.tmp" +mv "${FIXTURE}.tmp" "${FIXTURE}" +echo "✓ Synced BFV VK binding fixture: ${FIXTURE}" diff --git a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr index 7bd53501f1..67f6a513b6 100644 --- a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr +++ b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr @@ -7,11 +7,19 @@ //! Decryption aggregator: non-ZK `c6_fold` (folded C6 column) + non-ZK `decrypted_shares_aggregation` //! (C7, both `noir-recursive-no-zk`). The final `bb prove -t evm` proof of this circuit is what the //! contract verifies on-chain. +//! `committee_hash_hi` / `committee_hash_lo` bind the proof to the full on-chain committee ordering. +//! +//! Committee sizing: `committee_members` covers the **full registered committee** of size +//! `N_PARTIES`, matching `topNodes` on-chain. The `T + 1` participating `party_ids` (extracted +//! from the inner C7 proof) are indices into that full committee. `committee_members` must be +//! supplied in the same order as on-chain `topNodes`; the hash equality pins that order. use bb_proof_verification::{UltraHonkProof, UltraHonkVerificationKey, verify_honk_proof_non_zk}; use lib::configs::default::MAX_MSG_NON_ZERO_COEFFS; +use lib::configs::default::N_PARTIES; use lib::configs::default::T; use lib::math::commitments::compute_vk_hash; +use lib::math::committee_hash::committee_hash_limbs; /// Must match `c6_fold::C6_FOLD_PUBLIC_LEN`: pub params + flattened `(out_sk, out_esm, out_ct, out_d)`. pub global C6_FOLD_PUBLIC_LEN: u32 = 4 + (4 * (T + 1)); @@ -42,7 +50,14 @@ fn main( c7_public: [Field; C7_PUBLIC_LEN], c6_fold_key_hash: pub Field, c7_key_hash: pub Field, + committee_members: [Field; N_PARTIES], + committee_hash_hi: pub Field, + committee_hash_lo: pub Field, ) -> pub (Field, [Field; T + 1], [Field; T + 1], [Field; T + 1], [Field; MAX_MSG_NON_ZERO_COEFFS]) { + let (expected_hi, expected_lo) = committee_hash_limbs(committee_members); + assert(expected_hi == committee_hash_hi); + assert(expected_lo == committee_hash_lo); + verify_honk_proof_non_zk(c6_fold_vk, c6_fold_proof, c6_fold_public, c6_fold_key_hash); verify_honk_proof_non_zk(c7_vk, c7_proof, c7_public, c7_key_hash); @@ -67,6 +82,12 @@ fn main( party_ids[i] = c7_public[C7_PARTY_ID_OFFSET + i]; expected_sk[i] = c6_fold_public[C6_FOLD_PREFIX_LEN + C6_FOLD_SK_COL_OFFSET + i]; expected_esm[i] = c6_fold_public[C6_FOLD_PREFIX_LEN + C6_FOLD_ESM_COL_OFFSET + i]; + + // Range-check each participating `party_ids[i]` against the full committee size + // `N_PARTIES`, so `committee_members[party_ids[i]]` is a well-defined committee slot. + // Structural pre-condition for future per-party signer/identity constraints. + let id = party_ids[i] as u32; + assert(id < N_PARTIES); } let mut message: [Field; MAX_MSG_NON_ZERO_COEFFS] = [0; MAX_MSG_NON_ZERO_COEFFS]; diff --git a/circuits/bin/recursive_aggregation/dkg_aggregator/src/main.nr b/circuits/bin/recursive_aggregation/dkg_aggregator/src/main.nr index f82707dbe7..c7b395c1c1 100644 --- a/circuits/bin/recursive_aggregation/dkg_aggregator/src/main.nr +++ b/circuits/bin/recursive_aggregation/dkg_aggregator/src/main.nr @@ -6,11 +6,20 @@ //! DKG aggregator: non-ZK `nodes_fold` and non-ZK `pk_aggregation` (both `noir-recursive-no-zk`). //! The final `bb prove -t evm` proof of this circuit is what the contract verifies on-chain. +//! `committee_hash_hi` / `committee_hash_lo` bind the proof to `keccak256(abi.encodePacked(topNodes))` +//! (128-bit limbs); the contract recomputes the hash from on-chain `topNodes`. +//! +//! Committee sizing: `committee_members` covers the **full registered committee** of size +//! `N_PARTIES`, matching `topNodes` on-chain. The H folded `party_ids` are indices into that +//! full committee (today `H == N_PARTIES`; after future honest-set selection `H` may be smaller +//! than `N_PARTIES`). `committee_members` must be supplied in the same order as on-chain +//! `topNodes`; the hash equality is what pins that order. use bb_proof_verification::{UltraHonkProof, UltraHonkVerificationKey, verify_honk_proof_non_zk}; use lib::configs::default::dkg::L_THRESHOLD; use lib::configs::default::{H, N_PARTIES}; use lib::math::commitments::compute_vk_hash; +use lib::math::committee_hash::committee_hash_limbs; /// Must match `node_fold::NODE_FOLD_PUBLIC_LEN`. pub global NODE_FOLD_PUBLIC_LEN: u32 = 11 + N_PARTIES + (2 * (N_PARTIES + H) * L_THRESHOLD); @@ -50,7 +59,23 @@ fn main( nodes_fold_key_hash: pub Field, c5_key_hash: pub Field, party_ids: pub [Field; H], + committee_members: [Field; N_PARTIES], + committee_hash_hi: pub Field, + committee_hash_lo: pub Field, ) -> pub (Field, [Field; H], [Field; H], Field) { + let (expected_hi, expected_lo) = committee_hash_limbs(committee_members); + assert(expected_hi == committee_hash_hi); + assert(expected_lo == committee_hash_lo); + + // Range-check each folded `party_ids[i]` against the full committee size `N_PARTIES`. + // This makes `committee_members[party_ids[i]]` a well-defined committee slot (today + // `H == N_PARTIES`; preserves soundness once `H < N_PARTIES`) and is the structural + // pre-condition for future per-party signer/identity constraints. + for i in 0..H { + let id = party_ids[i] as u32; + assert(id < N_PARTIES); + } + verify_honk_proof_non_zk( nodes_fold_vk, nodes_fold_proof, diff --git a/circuits/lib/src/configs/default/mod.nr b/circuits/lib/src/configs/default/mod.nr index 70e6219e5c..f29df7cd84 100644 --- a/circuits/lib/src/configs/default/mod.nr +++ b/circuits/lib/src/configs/default/mod.nr @@ -4,8 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. // -// Only place where we change param-set: re-export insecure or production. -// (in future any other param-set). All circuits use lib::configs::default::*. +// Auto-generated by build-circuits.ts for preset: insecure-512 pub use super::committee::micro::{H, N_PARTIES, T}; pub use super::insecure::dkg; diff --git a/circuits/lib/src/math/committee_hash.nr b/circuits/lib/src/math/committee_hash.nr new file mode 100644 index 0000000000..c4b6b7f88f --- /dev/null +++ b/circuits/lib/src/math/committee_hash.nr @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +//! `keccak256(abi.encodePacked(addresses))` split into hi/lo 128-bit limbs. +//! Must match `CommitteeHashLib.sol` and `e3_utils::committee_hash`. +//! +//! The hash is taken over the **full registered committee** of size `N_PARTIES` +//! (matches `topNodes` on-chain). It is not parameterised by `H` (the +//! folded honest-set size) because `topNodes` always carries the full committee. + +// Same value as `configs::default::N_PARTIES` (`committee::micro`, via build-circuits). +// `default::N_PARTIES` is not importable here: math -> default -> insecure::threshold -> math. +use crate::configs::committee::micro::N_PARTIES; +use keccak256::keccak256; + +global ADDRESS_BYTES: u32 = 20; +global COMMITTEE_PACKED_BYTES: u32 = N_PARTIES * ADDRESS_BYTES; + +fn field_to_address_bytes(member: Field) -> [u8; 20] { + let be: [u8; 32] = member.to_be_bytes(); + let mut out = [0u8; 20]; + for i in 0..20 { + out[i] = be[12 + i]; + } + out +} + +fn bytes32_to_field(bytes: [u8; 32]) -> Field { + let mut value: Field = 0; + for i in 0..32 { + value = value * 256 + bytes[i] as Field; + } + value +} + +/// Hash the ordered full committee (`N_PARTIES` members, matching on-chain `topNodes`) and +/// return `(committee_hash_hi, committee_hash_lo)` public limbs. +pub fn committee_hash_limbs(members: [Field; N_PARTIES]) -> (Field, Field) { + let mut packed = [0u8; COMMITTEE_PACKED_BYTES]; + for i in 0..N_PARTIES { + let addr = field_to_address_bytes(members[i]); + for j in 0..20 { + packed[i * 20 + j] = addr[j]; + } + } + + let hash_bytes = keccak256(packed, COMMITTEE_PACKED_BYTES); + + // Match `CommitteeHashLib.hi` / `lo`: each limb is a bytes32 with its 128 bits + // right-aligned (same as `bytes32(uint256(hash) >> 128)` and `& _LO_MASK`). + let mut hi_bytes = [0u8; 32]; + let mut lo_bytes = [0u8; 32]; + for i in 0..16 { + hi_bytes[16 + i] = hash_bytes[i]; + lo_bytes[16 + i] = hash_bytes[16 + i]; + } + + (bytes32_to_field(hi_bytes), bytes32_to_field(lo_bytes)) +} diff --git a/circuits/lib/src/math/mod.nr b/circuits/lib/src/math/mod.nr index b03c54f7ff..c0eb2cc3a9 100644 --- a/circuits/lib/src/math/mod.nr +++ b/circuits/lib/src/math/mod.nr @@ -9,3 +9,4 @@ pub mod safe; pub mod helpers; pub mod modulo; pub mod commitments; +pub mod committee_hash; diff --git a/crates/aggregator/Cargo.toml b/crates/aggregator/Cargo.toml index 66132a7498..078dc82ccb 100644 --- a/crates/aggregator/Cargo.toml +++ b/crates/aggregator/Cargo.toml @@ -7,6 +7,7 @@ description = "E3 - Enclave Ciphernode Aggregators" repository = "https://github.com/gnosisguild/enclave/crates/aggregator" [dependencies] +alloy = { workspace = true } actix = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } @@ -27,6 +28,7 @@ e3-request = { workspace = true } e3-sortition = { workspace = true } e3-zk-helpers = { workspace = true } e3-utils = { workspace = true } +futures = { workspace = true } serde = { workspace = true } tracing = { workspace = true } diff --git a/crates/aggregator/src/committee.rs b/crates/aggregator/src/committee.rs new file mode 100644 index 0000000000..f77289debd --- /dev/null +++ b/crates/aggregator/src/committee.rs @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +use alloy::primitives::Address; +use anyhow::{anyhow, Result}; +use e3_events::OrderedSet; +use std::str::FromStr; + +/// Parse ordered committee node strings (`topNodes` / `PublicKeyAggregated.nodes`) once at ingress. +pub fn committee_addresses_from_nodes(nodes: &OrderedSet) -> Result> { + nodes + .iter() + .map(|s| { + Address::from_str(s).map_err(|e| anyhow!("invalid committee node address {s}: {e}")) + }) + .collect() +} diff --git a/crates/aggregator/src/committee_hash.rs b/crates/aggregator/src/committee_hash.rs new file mode 100644 index 0000000000..9fa41132bf --- /dev/null +++ b/crates/aggregator/src/committee_hash.rs @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +pub use e3_utils::committee_hash::*; diff --git a/crates/aggregator/src/ext.rs b/crates/aggregator/src/ext.rs index 1c794e4db6..c2fdc5e1f2 100644 --- a/crates/aggregator/src/ext.rs +++ b/crates/aggregator/src/ext.rs @@ -6,6 +6,7 @@ use std::sync::Arc; +use crate::committee::committee_addresses_from_nodes; use crate::decryptionshare_created_buffer::DecryptionshareCreatedBuffer; use crate::keyshare_created_filter_buffer::KeyshareCreatedFilterBuffer; use crate::{ @@ -14,6 +15,7 @@ use crate::{ ThresholdPlaintextAggregatorState, TrBfvPlaintextRepositoryFactory, }; use actix::{Actor, Addr, Recipient}; +use alloy::primitives::Address; use anyhow::{anyhow, Result}; use async_trait::async_trait; use e3_data::{AutoPersist, Persistable, RepositoriesFactory}; @@ -22,9 +24,12 @@ use e3_events::{BusHandle, EType, EnclaveEvent, EnclaveEventData}; use e3_fhe::ext::FHE_KEY; use e3_fhe::Fhe; use e3_fhe_params::BfvPreset; -use e3_request::{E3Context, E3ContextSnapshot, E3Extension, META_KEY}; +use e3_request::{E3Context, E3ContextSnapshot, E3Extension, TypedKey, META_KEY}; use e3_sortition::Sortition; +/// Finalized committee (`PublicKeyAggregated.nodes`) parsed once for downstream ZK requests. +pub const COMMITTEE_ADDRESSES_KEY: TypedKey> = TypedKey::new("committee_addresses"); + pub struct PublicKeyAggregatorExtension { bus: BusHandle, } @@ -168,10 +173,40 @@ impl ThresholdPlaintextAggregatorExtension { } const ERROR_TRBFV_PLAINTEXT_META_MISSING:&str = "Could not create ThresholdPlaintextAggregator because the meta instance it depends on was not set on the context."; +const ERROR_TRBFV_PLAINTEXT_COMMITTEE_MISSING: &str = + "Could not create ThresholdPlaintextAggregator because committee addresses were not set (expected PublicKeyAggregated before CiphertextOutputPublished)."; + +fn load_committee_addresses(ctx: &E3Context, e3_id: &E3id) -> Result> { + if let Some(addrs) = ctx.get_dependency(COMMITTEE_ADDRESSES_KEY) { + return Ok(addrs.clone()); + } + // Restart/hydrate path: read from persisted public-key aggregator state. + let repo = ctx.repositories().publickey(e3_id); + let state = futures::executor::block_on(repo.read())?; + let Some(state) = state else { + return Err(anyhow!(ERROR_TRBFV_PLAINTEXT_COMMITTEE_MISSING)); + }; + let nodes = state + .committee_nodes() + .ok_or_else(|| anyhow!(ERROR_TRBFV_PLAINTEXT_COMMITTEE_MISSING))?; + committee_addresses_from_nodes(nodes) +} #[async_trait] impl E3Extension for ThresholdPlaintextAggregatorExtension { fn on_event(&self, ctx: &mut E3Context, evt: &EnclaveEvent) { + if let EnclaveEventData::PublicKeyAggregated(data) = evt.get_data() { + match committee_addresses_from_nodes(&data.nodes) { + Ok(addrs) => { + let _ = ctx.set_dependency(COMMITTEE_ADDRESSES_KEY, addrs); + } + Err(e) => { + self.bus.err(EType::PlaintextAggregation, e); + } + } + return; + } + if ctx.get_event_recipient("threshold_keyshare").is_none() { return; } @@ -194,6 +229,14 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { }; let e3_id = data.e3_id.clone(); + let committee_addresses = match load_committee_addresses(ctx, &e3_id) { + Ok(addrs) => addrs, + Err(e) => { + self.bus.err(EType::PlaintextAggregation, e); + return; + } + }; + let repo = ctx.repositories().trbfv_plaintext(&e3_id); let sync_state = repo.send(Some(ThresholdPlaintextAggregatorState::init( meta.threshold_m as u64, @@ -214,6 +257,7 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { e3_id: e3_id.clone(), params_preset: meta.params_preset, proof_aggregation_enabled: meta.proof_aggregation_enabled, + committee_addresses, }, sync_state, ) @@ -247,6 +291,9 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { return Ok(()); }; + + let committee_addresses = load_committee_addresses(ctx, &ctx.e3_id)?; + let value = ThresholdPlaintextAggregator::new( ThresholdPlaintextAggregatorParams { bus: self.bus.clone(), @@ -254,6 +301,7 @@ impl E3Extension for ThresholdPlaintextAggregatorExtension { e3_id: ctx.e3_id.clone(), params_preset: meta.params_preset, proof_aggregation_enabled: meta.proof_aggregation_enabled, + committee_addresses, }, sync_state, ) diff --git a/crates/aggregator/src/lib.rs b/crates/aggregator/src/lib.rs index 1738a79a6d..2b07b2f48f 100644 --- a/crates/aggregator/src/lib.rs +++ b/crates/aggregator/src/lib.rs @@ -4,7 +4,9 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +mod committee; mod committee_finalizer; +pub mod committee_hash; mod decryptionshare_created_buffer; pub mod ext; mod keyshare_created_filter_buffer; diff --git a/crates/aggregator/src/publickey_aggregator.rs b/crates/aggregator/src/publickey_aggregator.rs index 3f720cbe84..4f9324572f 100644 --- a/crates/aggregator/src/publickey_aggregator.rs +++ b/crates/aggregator/src/publickey_aggregator.rs @@ -4,6 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +use crate::committee::committee_addresses_from_nodes; use actix::prelude::*; use anyhow::Result; use e3_data::Persistable; @@ -96,6 +97,16 @@ pub enum PublicKeyAggregatorState { } impl PublicKeyAggregatorState { + /// Ordered `topNodes` when the committee set is known (post–committee formation). + pub fn committee_nodes(&self) -> Option<&OrderedSet> { + match self { + PublicKeyAggregatorState::Collecting { nodes, .. } if !nodes.is_empty() => Some(nodes), + PublicKeyAggregatorState::GeneratingC5Proof { nodes, .. } => Some(nodes), + PublicKeyAggregatorState::Complete { nodes, .. } => Some(nodes), + _ => None, + } + } + pub fn init(threshold_n: usize, threshold_m: usize, seed: Seed) -> Self { PublicKeyAggregatorState::Collecting { threshold_n, @@ -610,6 +621,7 @@ impl PublicKeyAggregator { fn try_dispatch_dkg_aggregation(&mut self, ec: &EventContext) -> Result<()> { let state = self.state.get(); let Some(PublicKeyAggregatorState::GeneratingC5Proof { + nodes, dkg_node_proofs, honest_party_ids, c5_proof_pending, @@ -725,6 +737,17 @@ impl PublicKeyAggregator { return Ok(()); } + let committee_addresses = committee_addresses_from_nodes(nodes)?; + #[cfg(debug_assertions)] + { + let n_registered = committee_addresses.len(); + debug_assert_eq!( + party_ids.len(), + n_registered, + "honest NodeFold count must equal registered committee size until expulsion enables H < N" + ); + } + let corr = CorrelationId::new(); self.bus.publish( ComputeRequest::zk( @@ -732,6 +755,7 @@ impl PublicKeyAggregator { node_fold_proofs, c5_proof: c5_proof.clone(), party_ids, + committee_addresses, params_preset: self.params_preset, }), corr, @@ -1348,6 +1372,9 @@ mod tests { node_fold_proofs: vec![dummy_proof(CircuitName::PkAggregation)], c5_proof: dummy_proof(CircuitName::PkAggregation), party_ids: vec![0], + committee_addresses: vec!["0x0000000000000000000000000000000000000001" + .parse() + .expect("test address")], params_preset: BfvPreset::InsecureThreshold512, }), correlation_id, diff --git a/crates/aggregator/src/threshold_plaintext_aggregator.rs b/crates/aggregator/src/threshold_plaintext_aggregator.rs index 73cc1ec3bc..a2bd99f044 100644 --- a/crates/aggregator/src/threshold_plaintext_aggregator.rs +++ b/crates/aggregator/src/threshold_plaintext_aggregator.rs @@ -7,6 +7,7 @@ use std::collections::{BTreeMap, BTreeSet}; use actix::prelude::*; +use alloy::primitives::Address; use anyhow::{anyhow, bail, ensure, Result}; use e3_data::Persistable; use e3_events::{ @@ -186,6 +187,8 @@ pub struct ThresholdPlaintextAggregator { decryption_aggregator_proofs: Option>, /// Last event context, reused for ZK and final publish. last_ec: Option>, + /// Ordered committee (`topNodes`) for decryption-aggregator `committee_hash_*` inputs. + committee_addresses: Vec
, } pub struct ThresholdPlaintextAggregatorParams { @@ -194,6 +197,8 @@ pub struct ThresholdPlaintextAggregatorParams { pub e3_id: E3id, pub params_preset: BfvPreset, pub proof_aggregation_enabled: bool, + /// Finalized committee from `PublicKeyAggregated.nodes` (parsed once at construction). + pub committee_addresses: Vec
, } impl ThresholdPlaintextAggregator { @@ -214,6 +219,7 @@ impl ThresholdPlaintextAggregator { c7_proofs_pending: None, decryption_aggregator_proofs: None, last_ec: None, + committee_addresses: params.committee_addresses, } } @@ -483,7 +489,6 @@ impl ThresholdPlaintextAggregator { })?; self.last_ec = Some(ec.clone()); - self.try_publish_complete()?; Ok(()) } @@ -620,6 +625,7 @@ impl ThresholdPlaintextAggregator { pub fn handle_aggregation_proof_signed( &mut self, msg: TypedEvent, + ctx: &mut Context, ) -> Result<()> { let (msg, ec) = msg.into_components(); @@ -652,10 +658,37 @@ impl ThresholdPlaintextAggregator { info!("C7 proof signed — awaiting DecryptionAggregation..."); self.c7_proofs_pending = Some(proofs); self.last_ec = Some(ec.clone()); + self.maybe_start_decryption_aggregation(&ec)?; self.try_publish_complete() } + fn maybe_start_decryption_aggregation(&mut self, ec: &EventContext) -> Result<()> { + if self.c7_proofs_pending.is_none() { + return Ok(()); + } + if self.decryption_aggregator_proofs.is_some() + || self.decryption_aggregation_correlation.is_some() + { + return Ok(()); + } + if !self.proof_aggregation_enabled { + if self.decryption_aggregator_proofs.is_none() { + self.decryption_aggregator_proofs = Some(Vec::new()); + } + return Ok(()); + } + self.dispatch_decryption_aggregation(ec) + } + fn dispatch_decryption_aggregation(&mut self, ec: &EventContext) -> Result<()> { + if self.committee_addresses.is_empty() { + warn!( + e3_id = %self.e3_id, + "DecryptionAggregation: committee addresses missing at aggregator construction" + ); + return self.fail_decryption_round(ec.clone()); + } + let Some(c7_proofs) = self.c7_proofs_pending.as_ref() else { return Ok(()); }; @@ -670,6 +703,10 @@ impl ThresholdPlaintextAggregator { return Ok(()); } let Some(honest_c6) = self.honest_c6_proofs_for_agg.as_ref() else { + warn!( + e3_id = %self.e3_id, + "DecryptionAggregation deferred: honest C6 proofs not retained on aggregator" + ); return Ok(()); }; // With proof aggregation enabled we must have a complete C6 set; otherwise we'd publish @@ -717,11 +754,18 @@ impl ThresholdPlaintextAggregator { }); } let corr = CorrelationId::new(); + info!( + e3_id = %self.e3_id, + num_jobs = num_ct, + c6_slots = c6_total_slots, + "DecryptionAggregation: publishing Zk compute request" + ); self.bus.publish( ComputeRequest::zk( ZkRequest::DecryptionAggregation(DecryptionAggregationRequest { c6_total_slots, jobs, + committee_addresses: self.committee_addresses.clone(), params_preset: self.params_preset, }), corr, @@ -733,7 +777,11 @@ impl ThresholdPlaintextAggregator { Ok(()) } - pub fn handle_compute_response(&mut self, msg: TypedEvent) -> Result<()> { + pub fn handle_compute_response( + &mut self, + msg: TypedEvent, + ctx: &mut Context, + ) -> Result<()> { let (msg, ec) = msg.into_components(); ensure!( msg.e3_id == self.e3_id, @@ -808,7 +856,7 @@ impl ThresholdPlaintextAggregator { // Not a response we handle — ignore } } - + let _ = ctx; Ok(()) } @@ -854,9 +902,6 @@ impl ThresholdPlaintextAggregator { let Some(c7_proofs) = self.c7_proofs_pending.clone() else { return Ok(()); }; - if let Some(ec) = self.last_ec.clone() { - self.dispatch_decryption_aggregation(&ec)?; - } let dec_ready = self.decryption_aggregator_proofs.is_some() && self.decryption_aggregation_correlation.is_none(); if !dec_ready { @@ -1031,11 +1076,15 @@ impl Handler>> impl Handler> for ThresholdPlaintextAggregator { type Result = (); - fn handle(&mut self, msg: TypedEvent, _: &mut Self::Context) -> Self::Result { + fn handle( + &mut self, + msg: TypedEvent, + ctx: &mut Self::Context, + ) -> Self::Result { trap( EType::PlaintextAggregation, &self.bus.with_ec(msg.get_ctx()), - || self.handle_compute_response(msg), + || self.handle_compute_response(msg, ctx), ) } } @@ -1107,12 +1156,12 @@ impl Handler> for ThresholdPlaintextAggregato fn handle( &mut self, msg: TypedEvent, - _ctx: &mut Self::Context, + ctx: &mut Self::Context, ) -> Self::Result { trap( EType::PlaintextAggregation, &self.bus.with_ec(msg.get_ctx()), - || self.handle_aggregation_proof_signed(msg), + || self.handle_aggregation_proof_signed(msg, ctx), ) } } @@ -1214,8 +1263,15 @@ mod tests { .start() } + fn test_committee_address() -> Address { + "0x0000000000000000000000000000000000000001" + .parse() + .expect("test address") + } + async fn build_plaintext_aggregator( initial_state: ThresholdPlaintextAggregatorState, + proof_aggregation_enabled: bool, ) -> Result<( ThresholdPlaintextAggregator, Addr>, @@ -1230,7 +1286,8 @@ mod tests { sortition: start_sortition(&bus), e3_id: e3_id.clone(), params_preset: BfvPreset::InsecureThreshold512, - proof_aggregation_enabled: true, + proof_aggregation_enabled, + committee_addresses: vec![test_committee_address()], }, test_persistable(initial_state), ); @@ -1248,7 +1305,7 @@ mod tests { async fn threshold_decryption_compute_error_emits_e3_failed() -> Result<()> { let correlation_id = CorrelationId::new(); let (mut aggregator, history, e3_id) = - build_plaintext_aggregator(computing_state()).await?; + build_plaintext_aggregator(computing_state(), true).await?; aggregator.threshold_decryption_correlation = Some(correlation_id.clone()); let request = ComputeRequest::trbfv( @@ -1291,7 +1348,7 @@ mod tests { #[actix::test] async fn insufficient_honest_c6_shares_emit_e3_failed() -> Result<()> { let (mut aggregator, history, e3_id) = - build_plaintext_aggregator(verifying_c6_state()).await?; + build_plaintext_aggregator(verifying_c6_state(), true).await?; aggregator.handle_c6_verification_complete(TypedEvent::new( ShareVerificationComplete { @@ -1322,7 +1379,7 @@ mod tests { async fn decryption_aggregation_compute_error_emits_e3_failed() -> Result<()> { let correlation_id = CorrelationId::new(); let (mut aggregator, history, e3_id) = - build_plaintext_aggregator(generating_c7_state()).await?; + build_plaintext_aggregator(generating_c7_state(), true).await?; aggregator.c7_proofs_pending = Some(vec![dummy_proof(CircuitName::PkAggregation)]); aggregator.honest_c6_proofs_for_agg = Some(vec![( 0, @@ -1339,6 +1396,7 @@ mod tests { ZkRequest::DecryptionAggregation(DecryptionAggregationRequest { c6_total_slots: 1, jobs: Vec::new(), + committee_addresses: vec![test_committee_address()], params_preset: BfvPreset::InsecureThreshold512, }), correlation_id, @@ -1374,18 +1432,19 @@ mod tests { #[actix::test] async fn missing_c6_inner_proofs_emit_e3_failed() -> Result<()> { let (mut aggregator, history, e3_id) = - build_plaintext_aggregator(generating_c7_state()).await?; + build_plaintext_aggregator(generating_c7_state(), true).await?; aggregator.c7_proofs_pending = Some(vec![dummy_proof(CircuitName::PkAggregation)]); aggregator.honest_c6_proofs_for_agg = Some(vec![ (0, vec![]), (1, vec![dummy_proof(CircuitName::ThresholdShareDecryption)]), ]); - aggregator.dispatch_decryption_aggregation(&test_ctx(E3Failed { + let ec = test_ctx(E3Failed { e3_id: e3_id.clone(), failed_at_stage: E3Stage::None, reason: FailureReason::None, - }))?; + }); + aggregator.dispatch_decryption_aggregation(&ec)?; let event = next_event(&history).await?; assert!(matches!( @@ -1402,4 +1461,25 @@ mod tests { Ok(()) } + + #[actix::test] + async fn proof_aggregation_disabled_marks_decryption_aggregator_ready() -> Result<()> { + let (mut aggregator, _history, _e3_id) = + build_plaintext_aggregator(generating_c7_state(), false).await?; + aggregator.c7_proofs_pending = Some(vec![dummy_proof(CircuitName::PkAggregation)]); + let ec = test_ctx(E3Failed { + e3_id: aggregator.e3_id.clone(), + failed_at_stage: E3Stage::None, + reason: FailureReason::None, + }); + + aggregator.dispatch_decryption_aggregation(&ec)?; + assert!(aggregator + .decryption_aggregator_proofs + .as_ref() + .is_some_and(|p| p.is_empty())); + assert!(aggregator.decryption_aggregation_correlation.is_none()); + + Ok(()) + } } diff --git a/crates/events/src/enclave_event/compute_request/zk.rs b/crates/events/src/enclave_event/compute_request/zk.rs index dce15a8da2..f08496e2ea 100644 --- a/crates/events/src/enclave_event/compute_request/zk.rs +++ b/crates/events/src/enclave_event/compute_request/zk.rs @@ -76,6 +76,8 @@ pub struct DkgAggregationRequest { pub node_fold_proofs: Vec, pub c5_proof: Proof, pub party_ids: Vec, + /// Ordered committee addresses (`topNodes`) for `committee_hash_*` public inputs. + pub committee_addresses: Vec
, pub params_preset: BfvPreset, } @@ -84,6 +86,8 @@ pub struct DkgAggregationRequest { pub struct DecryptionAggregationRequest { pub c6_total_slots: usize, pub jobs: Vec, + /// Ordered committee addresses (`topNodes`) for `committee_hash_*` public inputs. + pub committee_addresses: Vec
, pub params_preset: BfvPreset, } diff --git a/crates/evm/src/ciphernode_registry_sol.rs b/crates/evm/src/ciphernode_registry_sol.rs index fc5d92f238..65f24ef6fb 100644 --- a/crates/evm/src/ciphernode_registry_sol.rs +++ b/crates/evm/src/ciphernode_registry_sol.rs @@ -489,7 +489,6 @@ impl Handler Handler, contract_address: Address, e3_id: E3id, - nodes: OrderedSet, public_key: ArcBytes, pk_commitment: [u8; 32], dkg_aggregator_proof: Option<&Proof>, @@ -686,15 +683,9 @@ pub async fn publish_committee_to_registry Bytes::new(), }; - let nodes_vec: Vec
= nodes - .into_iter() - .filter_map(|node| node.parse().ok()) - .collect(); - // RPC may not have synced finalization yet send_tx_with_retry("publishCommittee", &["CommitteeNotFinalized"], || { let provider = provider.clone(); - let nodes_vec = nodes_vec.clone(); let public_key_bytes = public_key_bytes.clone(); let proof = proof.clone(); async move { @@ -707,13 +698,7 @@ pub async fn publish_committee_to_registry Result { - let artifacts_dir = req.params_preset.artifacts_dir(); let job_id = zk_bb_work_id(&request); let input = DkgAggregationInput { node_fold_proofs: &req.node_fold_proofs, c5_proof: &req.c5_proof, party_ids: &req.party_ids, + committee_addresses: &req.committee_addresses, }; - let proof = prove_dkg_aggregation(prover, &input, &job_id, &artifacts_dir).map_err(|e| { + let proof = prove_dkg_aggregation(prover, &input, &job_id, req.params_preset).map_err(|e| { ComputeRequestError::new( ComputeRequestErrorKind::Zk(ZkEventError::ProofGenerationFailed(e.to_string())), request.clone(), @@ -752,7 +752,6 @@ fn handle_decryption_aggregation_proof( req: DecryptionAggregationRequest, request: ComputeRequest, ) -> Result { - let artifacts_dir = req.params_preset.artifacts_dir(); let job_id = zk_bb_work_id(&request); let jobs: Vec = req .jobs @@ -767,8 +766,9 @@ fn handle_decryption_aggregation_proof( prover, req.c6_total_slots, &jobs, + &req.committee_addresses, &job_id, - &artifacts_dir, + req.params_preset, ) .map_err(|e| { ComputeRequestError::new( diff --git a/crates/sortition/src/sortition.rs b/crates/sortition/src/sortition.rs index 6a924bedf3..fc93da7ba0 100644 --- a/crates/sortition/src/sortition.rs +++ b/crates/sortition/src/sortition.rs @@ -204,6 +204,22 @@ impl Deref for E3CommitteeContainsResponse { } } +/// Request the ordered finalized committee member list for an E3. +#[derive(Message, Clone, Debug)] +#[rtype(result = "()")] +pub struct GetCommitteeMembersRequest { + pub e3_id: E3id, + pub reply: Recipient, +} + +/// Response with committee members in party-id order (index == party_id). +#[derive(Message, Clone, Debug)] +#[rtype(result = "()")] +pub struct CommitteeMembersResponse { + /// `None` when the E3 committee is not finalized in sortition yet. + pub members: Option>, +} + /// Sortition actor that manages the sortition algorithm and the node state. pub struct Sortition { /// Persistent map of `chain_id -> SortitionBackend`. @@ -716,6 +732,29 @@ impl Handler> for Sortition { } } +impl Handler for Sortition { + type Result = (); + + fn handle(&mut self, msg: GetCommitteeMembersRequest, _: &mut Self::Context) -> Self::Result { + trap(EType::Sortition, &self.bus.clone(), || { + let members = self.get_committee(&msg.e3_id).map(|c| c.members().to_vec()); + let reply = msg.reply; + // `try_send` can drop the reply when the aggregator mailbox is busy (e.g. mid + // `AggregationProofSigned`), leaving decryption stuck after C7 with no ZK job. + actix::spawn(async move { + if reply + .send(CommitteeMembersResponse { members }) + .await + .is_err() + { + tracing::error!("committee members reply failed: aggregator recipient closed"); + } + }); + Ok(()) + }) + } +} + impl Handler> for Sortition where T: Clone + Send + Sync + 'static, diff --git a/crates/utils/src/committee_hash.rs b/crates/utils/src/committee_hash.rs new file mode 100644 index 0000000000..798ecd244e --- /dev/null +++ b/crates/utils/src/committee_hash.rs @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +//! Canonical committee hash for DKG / decryption aggregator proofs. +//! Must match `CommitteeHashLib.sol` (`keccak256(abi.encodePacked(addresses))`). + +use alloy::primitives::{keccak256, Address, B256}; + +/// Hi/lo limbs of `keccak256(abi.encodePacked(addresses))` for Noir public inputs. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct CommitteeHashLimbs { + pub hi: B256, + pub lo: B256, +} + +/// `keccak256(abi.encodePacked(addresses))` for the ordered on-chain committee. +pub fn hash_committee_addresses(addresses: &[Address]) -> B256 { + let packed: Vec = addresses + .iter() + .flat_map(|addr| addr.into_array()) + .collect(); + keccak256(packed) +} + +/// Split a committee hash into 128-bit limbs for BN254 public inputs. +/// Each limb is a bytes32 with its 128 bits right-aligned, matching `CommitteeHashLib`. +pub fn split_committee_hash(hash: B256) -> CommitteeHashLimbs { + let mut hi = [0u8; 32]; + hi[16..].copy_from_slice(&hash.0[..16]); + let mut lo = [0u8; 32]; + lo[16..].copy_from_slice(&hash.0[16..]); + CommitteeHashLimbs { + hi: B256::from(hi), + lo: B256::from(lo), + } +} + +/// Hash and split in one step. +pub fn committee_hash_limbs_from_addresses(addresses: &[Address]) -> CommitteeHashLimbs { + split_committee_hash(hash_committee_addresses(addresses)) +} + +/// Field hex strings (`0x…`, 32 bytes) for Noir witness `committee_hash_hi` / `committee_hash_lo`. +pub fn committee_hash_field_hex(addresses: &[Address]) -> (String, String) { + let limbs = committee_hash_limbs_from_addresses(addresses); + (field_hex_from_b256(limbs.hi), field_hex_from_b256(limbs.lo)) +} + +fn field_hex_from_b256(value: B256) -> String { + format!("0x{}", hex::encode(value)) +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy::primitives::address; + + #[test] + fn encode_packed_matches_solidity_layout() { + let nodes = vec![ + address!("0x0000000000000000000000000000000000000001"), + address!("0x0000000000000000000000000000000000000002"), + ]; + let hash = hash_committee_addresses(&nodes); + let limbs = split_committee_hash(hash); + assert_ne!(limbs.hi, B256::ZERO); + assert_ne!(limbs.lo, B256::ZERO); + } + + /// Limb bytes32 layout must match `CommitteeHashLib.hi` / `lo`. + #[test] + fn split_limbs_match_solidity_bytes32_layout() { + let nodes = vec![ + address!("0x0000000000000000000000000000000000000001"), + address!("0x0000000000000000000000000000000000000002"), + address!("0x0000000000000000000000000000000000000003"), + ]; + let hash = hash_committee_addresses(&nodes); + let limbs = split_committee_hash(hash); + + let mut expected_hi = [0u8; 32]; + expected_hi[16..].copy_from_slice(&hash.0[..16]); + assert_eq!(limbs.hi.0, expected_hi); + + let mut expected_lo = [0u8; 32]; + expected_lo[16..].copy_from_slice(&hash.0[16..]); + assert_eq!(limbs.lo.0, expected_lo); + } +} diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index d76f7b6b5e..b00bbbe2cc 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -7,6 +7,7 @@ extern crate self as e3_utils; // need this for e3_utils_derive to reference this crate pub mod actix; pub mod alloy; +pub mod committee_hash; pub mod constants; pub mod error; pub mod formatters; diff --git a/crates/zk-prover/src/circuits/aggregation/helpers.rs b/crates/zk-prover/src/circuits/aggregation/helpers.rs index e8e4be89cd..93252fd94d 100644 --- a/crates/zk-prover/src/circuits/aggregation/helpers.rs +++ b/crates/zk-prover/src/circuits/aggregation/helpers.rs @@ -42,6 +42,13 @@ pub fn u64_to_field_hex(value: u64) -> String { format!("0x{}", hex::encode(bytes)) } +/// Encode an EVM address as a 32-byte field hex string (20-byte address right-aligned). +pub fn address_to_field_hex(address: &alloy::primitives::Address) -> String { + let mut bytes = [0u8; 32]; + bytes[12..].copy_from_slice(address.as_slice()); + format!("0x{}", hex::encode(bytes)) +} + /// Extract a single 32-byte public input/output by name. `kind` must be `"input"` or `"output"`. pub fn extract_single_field( proof: &Proof, diff --git a/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs b/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs index 0c352bbb03..87ef773a25 100644 --- a/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs +++ b/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs @@ -9,14 +9,16 @@ use crate::circuits::aggregation::c3_accumulator::generate_sequential_c3_fold; use crate::circuits::aggregation::c6_accumulator::generate_sequential_c6_fold; -use crate::circuits::aggregation::helpers::u64_to_field_hex; +use crate::circuits::aggregation::helpers::{address_to_field_hex, u64_to_field_hex}; use crate::circuits::aggregation::nodes_fold_accumulator::generate_sequential_nodes_fold; use crate::circuits::utils::{bytes_to_field_strings, inputs_json_to_input_map}; use crate::circuits::vk; use crate::error::ZkError; use crate::prover::ZkProver; use crate::witness::{CompiledCircuit, WitnessGenerator}; +use alloy::primitives::Address; use e3_events::{CircuitName, CircuitVariant, Proof}; +use e3_fhe_params::BfvPreset; use serde::Serialize; fn proof_field_strings(proof: &Proof) -> Result, ZkError> { @@ -295,6 +297,8 @@ pub struct DkgAggregationInput<'a> { pub c5_proof: &'a Proof, /// Honest party ids in the same order as `node_fold_proofs` (e.g. sorted ascending). pub party_ids: &'a [u64], + /// Ordered committee addresses (`topNodes` / sortition order) for `committee_hash_*` public inputs. + pub committee_addresses: &'a [Address], } #[derive(Serialize)] @@ -308,6 +312,9 @@ struct DkgAggregatorWitness { nodes_fold_key_hash: String, c5_key_hash: String, party_ids: Vec, + committee_members: Vec, + committee_hash_hi: String, + committee_hash_lo: String, } /// [`CircuitName::DkgAggregator`] over sequential [`CircuitName::NodesFold`] + C5, proved with @@ -316,8 +323,10 @@ pub fn prove_dkg_aggregation( prover: &ZkProver, input: &DkgAggregationInput, e3_id: &str, - artifacts_dir: &str, + preset: BfvPreset, ) -> Result { + let artifacts_dir = preset.artifacts_dir(); + let artifacts_dir = artifacts_dir.as_str(); if input.node_fold_proofs.len() != input.party_ids.len() { return Err(ZkError::InvalidInput( "node_fold_proofs and party_ids length mismatch".into(), @@ -329,6 +338,22 @@ pub fn prove_dkg_aggregation( )); } let h = input.node_fold_proofs.len(); + // Full on-chain `topNodes` (must match compiled `N_PARTIES` in the circuit artifact). + // Do not use `preset.metadata().num_parties` — that is BFV search metadata, not circuit size. + let n_registered = input.committee_addresses.len(); + if n_registered == 0 { + return Err(ZkError::InvalidInput( + "prove_dkg_aggregation: committee_addresses must be non-empty (on-chain topNodes)" + .into(), + )); + } + #[cfg(debug_assertions)] + { + debug_assert_eq!( + h, n_registered, + "DkgAggregator honest-set H must equal registered committee size until expulsion enables H < N" + ); + } let slot_indices: Vec = (0u32..h as u32).collect(); let nodes_fold_proof = generate_sequential_nodes_fold( prover, @@ -355,6 +380,15 @@ pub fn prove_dkg_aggregation( .map(u64_to_field_hex) .collect(); + let (committee_hash_hi, committee_hash_lo) = + e3_utils::committee_hash::committee_hash_field_hex(input.committee_addresses); + + let committee_members: Vec = input + .committee_addresses + .iter() + .map(address_to_field_hex) + .collect(); + let witness = DkgAggregatorWitness { nodes_fold_vk: nodes_fold_vk.verification_key.clone(), nodes_fold_proof: proof_field_strings(&nodes_fold_proof)?, @@ -365,6 +399,9 @@ pub fn prove_dkg_aggregation( nodes_fold_key_hash: nodes_fold_vk.key_hash.clone(), c5_key_hash: c5_vk.key_hash.clone(), party_ids: party_id_fields, + committee_members, + committee_hash_hi, + committee_hash_lo, }; let json = @@ -403,6 +440,9 @@ struct DecryptionAggregatorWitness { c7_public: Vec, c6_fold_key_hash: String, c7_key_hash: String, + committee_members: Vec, + committee_hash_hi: String, + committee_hash_lo: String, } /// Prove [`CircuitName::DecryptionAggregator`] for each job (C6 fold + C7), with @@ -411,9 +451,12 @@ pub fn prove_decryption_aggregation_jobs( prover: &ZkProver, c6_total_slots: usize, jobs: &[DecryptionAggregationJob], + committee_addresses: &[Address], e3_id: &str, - artifacts_dir: &str, + preset: BfvPreset, ) -> Result, ZkError> { + let artifacts_dir = preset.artifacts_dir(); + let artifacts_dir = artifacts_dir.as_str(); // VKs and the compiled circuit are job-independent: load once, reuse per ciphertext. let c6_fold_vk = vk::load_vk_artifacts( &prover.circuits_dir(CircuitVariant::Default, artifacts_dir), @@ -430,6 +473,20 @@ pub fn prove_decryption_aggregation_jobs( artifacts_dir, )?; + if committee_addresses.is_empty() { + return Err(ZkError::InvalidInput( + "prove_decryption_aggregation_jobs: committee_addresses must be non-empty (on-chain topNodes)".into(), + )); + } + + let (committee_hash_hi, committee_hash_lo) = + e3_utils::committee_hash::committee_hash_field_hex(committee_addresses); + + let committee_members: Vec = committee_addresses + .iter() + .map(address_to_field_hex) + .collect(); + let mut out = Vec::with_capacity(jobs.len()); for (i, job) in jobs.iter().enumerate() { let c6_fold = generate_sequential_c6_fold( @@ -450,6 +507,9 @@ pub fn prove_decryption_aggregation_jobs( c7_public: proof_public_field_strings(job.c7_proof)?, c6_fold_key_hash: c6_fold_vk.key_hash.clone(), c7_key_hash: c7_vk.key_hash.clone(), + committee_members: committee_members.clone(), + committee_hash_hi: committee_hash_hi.clone(), + committee_hash_lo: committee_hash_lo.clone(), }; let json = serde_json::to_value(&witness) diff --git a/examples/CRISP/enclave.config.yaml b/examples/CRISP/enclave.config.yaml index d5c3c9a26b..ccc6c0d306 100644 --- a/examples/CRISP/enclave.config.yaml +++ b/examples/CRISP/enclave.config.yaml @@ -7,16 +7,16 @@ chains: deploy_block: 37 enclave: address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" - deploy_block: 14 + deploy_block: 13 ciphernode_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 10 + deploy_block: 9 bonding_registry: address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" - deploy_block: 11 + deploy_block: 10 slashing_manager: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - deploy_block: 9 + deploy_block: 8 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" deploy_block: 4 diff --git a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json index 4c1f11b02d..aa9b9976f8 100644 --- a/examples/CRISP/packages/crisp-contracts/deployed_contracts.json +++ b/examples/CRISP/packages/crisp-contracts/deployed_contracts.json @@ -145,5 +145,146 @@ "address": "0xA2Ced5053E66BA1E42583ffC996038A24110fEc7", "blockNumber": 10697384 } + }, + "localhost": { + "PoseidonT3": { + "blockNumber": 3, + "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" + }, + "MockUSDC": { + "constructorArgs": { + "initialSupply": "1000000" + }, + "blockNumber": 4, + "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" + }, + "EnclaveToken": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 5, + "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + }, + "EnclaveTicketToken": { + "constructorArgs": { + "baseToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "registry": "0x0000000000000000000000000000000000000001", + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 7, + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" + }, + "SlashingManager": { + "constructorArgs": { + "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 8, + "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + }, + "CiphernodeRegistryOwnable": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "submissionWindow": "10" + }, + "proxyRecords": { + "initData": "0xcd6dc687000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000a", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", + "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" + }, + "blockNumber": 9, + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + }, + "BondingRegistry": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "ticketToken": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "licenseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "registry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "slashedFundsTreasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "ticketPrice": "10000000", + "licenseRequiredBond": "100000000000000000000", + "minTicketBalance": "1", + "exitDelay": "604800" + }, + "proxyRecords": { + "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c90000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e0000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", + "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + }, + "blockNumber": 10, + "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" + }, + "Enclave": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "registry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "bondingRegistry": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "e3RefundManager": "0x0000000000000000000000000000000000000001", + "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "maxDuration": "2592000", + "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" + }, + "proxyRecords": { + "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", + "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" + }, + "blockNumber": 13, + "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" + }, + "E3RefundManager": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "treasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "proxyRecords": { + "initData": "0xc0c53b8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000b7f8bc63bbcad18155201308c8f3540b07f84f5e000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", + "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + }, + "blockNumber": 15, + "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + }, + "MockComputeProvider": { + "blockNumber": 17, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + }, + "MockDecryptionVerifier": { + "blockNumber": 18, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" + }, + "MockPkVerifier": { + "blockNumber": 19, + "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" + }, + "MockE3Program": { + "blockNumber": 20, + "address": "0x851356ae760d987E095750cCeb3bC6014560891C" + }, + "ZKTranscriptLib": { + "blockNumber": 22, + "address": "0x95401dc811bb5740090279Ba06cfA8fcF6113778" + }, + "HonkVerifier": { + "blockNumber": 23, + "address": "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf" + }, + "CRISPProgram": { + "blockNumber": 25, + "address": "0x0E801D84Fa97b50751Dbf25036d067dCf18858bF" + }, + "MockVotingToken": { + "blockNumber": 26, + "address": "0x9d4454B023096f34B160D6B654540c56A1F81688" + } } } \ No newline at end of file diff --git a/examples/CRISP/server/.env.example b/examples/CRISP/server/.env.example index 5696348a10..ce927ce22b 100644 --- a/examples/CRISP/server/.env.example +++ b/examples/CRISP/server/.env.example @@ -12,12 +12,18 @@ ETHERSCAN_API_KEY="" # Cron-job API key to trigger new rounds CRON_API_KEY=1234567890 -# Based on Default Anvil Deployments (Only for testing) +# Based on default Anvil deployments (mock Enclave stack + CRISPProgram) ENCLAVE_ADDRESS=0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e FEE_TOKEN_ADDRESS=0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 E3_PROGRAM_ADDRESS=0x0E801D84Fa97b50751Dbf25036d067dCf18858bF CIPHERNODE_REGISTRY_ADDRESS=0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 +# Mock contracts registered on Enclave during deploy (reference only) +MOCK_COMPUTE_PROVIDER_ADDRESS=0x9E545E3C0baAB3E08CdfD552C960A1050f373042 +MOCK_DECRYPTION_VERIFIER_ADDRESS=0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9 +MOCK_PK_VERIFIER_ADDRESS=0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8 +MOCK_E3_PROGRAM_ADDRESS=0x851356ae760d987E095750cCeb3bC6014560891C + # E3 Config # Defines the time interval during which users can submit their inputs # After this interval, the computation phase starts automatically diff --git a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json index 767f7b9b74..4eec94d7bf 100644 --- a/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json +++ b/packages/enclave-contracts/artifacts/contracts/Enclave.sol/Enclave.json @@ -2558,11 +2558,11 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615af7806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c806390173a4111610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b80639e57b9341161013c5780639e57b93414610607578063a87f4ab91461061a578063ac3d2f421461076c578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b806390173a41146105705780639117173c146105855780639231238614610598578063929a8faf146105ab57806399c6679d146105cc5780639c8570c8146105f4575f5ffd5b80635d1684181161022f5780637edcd7ab116101e95780637edcd7ab146104e757806381476ec21461050a578063830d71811461051d57806385814243146105305780638da5cb5b146105435780638dcdd86b1461054b5780638e5ce3ad1461055d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e036600461478a565b61092e565b005b61030f6102f53660046147ac565b5f908152600960205260409020546001600160a01b031690565b60405161031c91906147d0565b60405180910390f35b61030f6103333660046147ac565b60096020525f90815260409020546001600160a01b031681565b61036061035b3660046147f7565b6109da565b60405163ffffffff909116815260200161031c565b6102e561038336600461478a565b610a16565b6102e561039636600461482f565b610abb565b6103bd6103a93660046147ac565b5f908152600f602052604090205460ff1690565b60405161031c9190614871565b6103dd6103d83660046147ac565b610acf565b60405161031c9e9d9c9b9a999897969594939291906148bd565b61040a6104053660046147ac565b610c7a565b60405161031c9190614a97565b6104366104253660046147ac565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e5610452366004614ab4565b610ef7565b6102e56104653660046147ac565b611135565b6102e561047836600461478a565b6111c4565b61049061048b366004614b4a565b611257565b60405161031c9190614b63565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ee565b6102e56104cf366004614b75565b611301565b6102e56104e23660046147ac565b6113c1565b6104fa6104f5366004614be0565b6114b4565b604051901515815260200161031c565b6102e5610518366004614c57565b61170a565b6102e561052b366004614c77565b6117fe565b60015461030f906001600160a01b031681565b61030f61190a565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b610578611938565b60405161031c9190614cc5565b6102e56105933660046147ac565b61197e565b6105786105a63660046147ac565b611aec565b6105be6105b93660046147ac565b611b45565b60405161031c929190614ce6565b61030f6105da3660046147ac565b5f908152601060205260409020546001600160a01b031690565b6104fa610602366004614be0565b611b6c565b610436610615366004614cfc565b611e04565b61075f604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614d33565b61030f61077a3660046147ac565b5f908152600a60205260409020546001600160a01b031690565b6102e56107a2366004614e40565b6123ce565b6102e56107b536600461478a565b61248a565b6102e56107c8366004614c57565b612531565b6104fa6107db36600461478a565b60076020525f908152604090205460ff1681565b61043660065481565b6102e5610806366004614b75565b6125ee565b6102e56108193660046147ac565b6126a8565b61084061082c3660046147ac565b5f908152600d602052604090205460ff1690565b60405161031c9190614e7a565b6102e561085b366004614e88565b6126e5565b6102e561086e36600461478a565b612972565b6102e5610881366004614ea2565b612a0c565b60025461030f906001600160a01b031681565b6102e56108a736600461478a565b612cb9565b6108bf6108ba366004614cfc565b612cf3565b60405161031c929190614ed9565b6103bd6108db3660046147ac565b613747565b6102e56108ee36600461478a565b6138e1565b61030f6109013660046147ac565b600a6020525f90815260409020546001600160a01b031681565b6102e561092936600461478a565b613979565b610936613a08565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e613a08565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b815260040161098891906147d0565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab09083906147d0565b60405180910390a150565b610ac3613a08565b610acc81613a3a565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614ef9565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614ef9565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c826145f8565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614849565b6003811115610cd057610cd0614849565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614ef9565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614ef9565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f00613af7565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613b21565b610fa9876126a8565b610fb28b6138e1565b610fbb8a612972565b610fc48961092e565b610fcd88610a16565b610fd686613a3a565b604080516101e081018252620186a080825261c3506020808401829052612710948401859052603260608501819052620493e060808601819052620f424060a0870181905261138860c088018190525f60e089018190526105dc6101008a015261012089018190526109c46101408a018190526101608a018390526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b03191669027104e202710000017760a21b179055805467ffffffffffffffff191690556110c061190a565b6001600160a01b03168c6001600160a01b0316146110e1576110e18c612cb9565b831561112757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113d613a08565b5f8181526009602052604090205481906001600160a01b0316611176576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cc613a08565b6001600160a01b0381165f90815260076020526040902054819060ff16611207576040516321ac7c5f60e01b815260040161098891906147d0565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab09083906147d0565b600b6020525f90815260409020805461126f90614ef9565b80601f016020809104026020016040519081016040528092919081815260200182805461129b90614ef9565b80156112e65780601f106112bd576101008083540402835291602001916112e6565b820191905f5260205f20905b8154815290600101906020018083116112c957829003601f168201915b505050505081565b6112f6613a08565b6112ff5f613b32565b565b611309613a08565b6001600160a01b0381161580159061133a57505f828152600a60205260409020546001600160a01b03828116911614155b829061135c576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409081902080546001600160a01b0319166001600160a01b0384161790555182907f53661e3e12f23eea1e322a5352171ad3e4407d1394f869f53bb148c27e00908a906113b59084906147d0565b60405180910390a25050565b5f546001600160a01b031633146113eb5760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff16600181600681111561141057611410614849565b1461143557816001826040516337e1404160e01b815260040161098893929190614f2b565b5f828152600d60205260409020805460ff1916600217905560155461145a9042614f60565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615acb5f395f51905f52600160026040516113b5929190614f73565b5f5f6114bf87610c7a565b5f888152600d602052604090205490915060ff1660048160068111156114e7576114e7614849565b148860048390919261150f576040516337e1404160e01b815260040161098893929190614f2b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611572576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f898152600860205260409020600c0161158f888a83615001565b505f898152600d60205260409020805460ff191660051790556101c08301511561168957846115d157604051631eae1a4d60e31b815260040160405180910390fd5b8261010001516001600160a01b031663258ae58289896040516115f59291906150b5565b6040519081900381206001600160e01b031960e084901b16825261161f918a908a906004016150ec565b602060405180830381865afa15801561163a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165e919061511b565b935087878561168257604051632f9f8ab960e01b8152600401610988929190615136565b505061168e565b600193505b61169789613ba2565b887f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b898989896040516116cd9493929190615149565b60405180910390a2885f516020615acb5f395f51905f52600460056040516116f6929190614f73565b60405180910390a250505095945050505050565b5f546001600160a01b031633146117345760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff16600281600681111561176457611764614849565b1461178957836002826040516337e1404160e01b815260040161098893929190614f2b565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615acb5f395f51905f52600260036040516117f0929190614f73565b60405180910390a250505050565b611806613a08565b806118425760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b60205260409020805461185e90614ef9565b1590506118ad5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b602052604090206118c9828483615001565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da21958383836040516118fd9392919061517a565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b61195960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff1660068160068111156119a3576119a3614849565b1482906119c657604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c602052604090205482816119f7576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c60205260408120819055611a118461400e565b5f858152601160205260409020546002549192506001600160a01b0390811691611a3e91839116856140fb565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611a749088908790879087906004016151d9565b5f604051808303815f87803b158015611a8b575f5ffd5b505af1158015611a9d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611add929190918252602082015260400190565b60405180910390a25050505050565b611b0d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611b628482614158565b9250925050915091565b5f5f611b7787610c7a565b5f888152600d602052604090205490915060ff166003816006811115611b9f57611b9f614849565b1488600383909192611bc7576040516337e1404160e01b815260040161098893929190614f2b565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611c2b576040516308f3034360e31b815260048101929092526024820152604401610988565b5050606083015160200151899042811115611c625760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611c8d57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611c9f9291906150b5565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611ce19042614f60565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611d2e908d9085908c908c90600401615224565b6020604051808303815f875af1158015611d4a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6e919061511b565b9450888886611d9257604051632f9f8ab960e01b8152600401610988929190615136565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611dc6929190615136565b60405180910390a2895f516020615acb5f395f51905f5260036004604051611def929190614f73565b60405180910390a25050505095945050505050565b5f80600b81611e1960a0860160808701614b4a565b60ff1660ff1681526020019081526020015f208054611e3790614ef9565b905011611e565760405162461bcd60e51b815260040161098890615243565b5f601281611e67602086018661527a565b6003811115611e7857611e78614849565b6003811115611e8957611e89614849565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb0579050505050505090505f81600160028110611f0757611f07615210565b602002015163ffffffff1611835f016020810190611f25919061527a565b90611f445760405163286c068d60e11b81526004016109889190615293565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c08601529283169391909216911561206f576101a081015163ffffffff16846001602002015163ffffffff161015865f01602081019061204e919061527a565b9061206d5760405163010b971d60e31b81526004016109889190615293565b505b6101c081015163ffffffff16156120be576101c081015184519063ffffffff90811690821610156120bc57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b604086013560208701358110156120eb5760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f91612710916121099161ffff16906152a1565b61211391906152b8565b61271061ffff1683610160015161ffff1660156001015461213491906152a1565b61213e91906152b8565b61271061ffff1684610140015161ffff1660155f015461215e91906152a1565b61216891906152b8565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa1580156121b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d891906152d7565b6121e29190614f60565b6121ec91906152ee565b6121f69190614f60565b6122009190614f60565b61220a9190614f60565b90505f6122186001866152ee565b6122239060046152a1565b61222e90600e614f60565b90505f85845f015161224091906152a1565b90508186856020015161225391906152a1565b61225d91906152a1565b6122679082614f60565b905060018611156122af57600261227f6001886152ee565b61228990886152a1565b856040015161229891906152a1565b6122a291906152b8565b6122ac9082614f60565b90505b81868560c001516122c091906152a1565b6122ca91906152a1565b6122d49082614f60565b9050828685606001516122e791906152a1565b6122f191906152a1565b6122fb9082614f60565b905084846080015161230d91906152a1565b6123179082614f60565b9050600185111561235f57600261232f6001876152ee565b61233990876152a1565b856040015161234891906152a1565b61235291906152b8565b61235c9082614f60565b90505b60a084015161236e9082614f60565b610100850151909150612710906123899061ffff1682614f60565b61239390836152a1565b61239d91906152b8565b975087806123c157604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f546001600160a01b03163314806123f057506003546001600160a01b031633145b61240d57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156124235750600d60ff821611155b6124685760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b612486828260ff16600d81111561248157612481614849565b6142e0565b5050565b612492613a08565b6001600160a01b0381166124e85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b0316331461255c576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b1580156125a6575f5ffd5b505af11580156125b8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee542826040516113b591815260200190565b6125f6613a08565b6001600160a01b0381161580159061262757505f828152600960205260409020546001600160a01b03828116911614155b8290612649576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b6126b0613a08565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b6126ed613a08565b6127106127026101208301610100840161531b565b61ffff16111561271a6101208301610100840161531b565b9061273f576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127556101408301610120840161531b565b61ffff16111561276d6101408301610120840161531b565b90612792576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127a86101608301610140840161531b565b61ffff1611156127c06101608301610140840161531b565b906127e557604051633239953960e01b815261ffff9091166004820152602401610988565b506127106127fb6101808301610160840161531b565b61ffff1611156128136101808301610160840161531b565b9061283857604051633239953960e01b815261ffff9091166004820152602401610988565b5061271061284e6101a08301610180840161531b565b61ffff1611156128666101a08301610180840161531b565b9061288b57604051633239953960e01b815261ffff9091166004820152602401610988565b5061289e6101408201610120830161531b565b61ffff1615806128c757505f6128bb610100830160e0840161478a565b6001600160a01b031614155b6128e45760405163015f92ff60e51b815260040160405180910390fd5b6128f66101e082016101c08301615352565b63ffffffff1661290e6101c083016101a08401615352565b63ffffffff161015612933576040516392f55c6560e01b815260040160405180910390fd5b8060186129408282615391565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061554f565b61297a613a08565b6001600160a01b038116158015906129a057506001546001600160a01b03828116911614155b81906129c0576040516320252f0b60e01b815260040161098891906147d0565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab09083906147d0565b612a14613a08565b612a216020820182615352565b63ffffffff16612a376040830160208401615352565b63ffffffff1610158015612a5c57505f612a546020830183615352565b63ffffffff16115b612a7957604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612bb2576101a081015163ffffffff16612b626040840160208501615352565b63ffffffff161015612b7a6040840160208501615352565b826101a001519091612baf57604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612c29576101c081015163ffffffff16612bdc6020840184615352565b63ffffffff161015612bf16020840184615352565b826101c001519091612c265760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612c3f57612c3f614849565b6003811115612c5057612c50614849565b815260208101919091526040015f20612c6a916002614675565b50826003811115612c7d57612c7d614849565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612cac9190615659565b60405180910390a2505050565b612cc1613a08565b6001600160a01b038116612cea575f604051631e4fbdf760e01b815260040161098891906147d0565b610acc81613b32565b5f612cfc6145f8565b5f601281612d0d602087018761527a565b6003811115612d1e57612d1e614849565b6003811115612d2f57612d2f614849565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612d56579050505050505090505f81600160028110612dad57612dad615210565b602002015163ffffffff1611845f016020810190612dcb919061527a565b90612dea5760405163286c068d60e11b81526004016109889190615293565b50602084013542811015612e1457604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612e425760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612e5a4260408901356152ee565b612e649190614f60565b612e6e9190614f60565b905060055481108190612e97576040516313b783af60e21b815260040161098891815260200190565b5060075f612eab608088016060890161478a565b6001600160a01b0316815260208101919091526040015f205460ff16612ed7608087016060880161478a565b90612ef65760405163295a6a6f60e11b815260040161098891906147d0565b505f612f0186611e04565b60068054965090915085905f612f1683615699565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff191660011790556010909452829020805433941693909317909255601654919250612ff19190890135614f60565b5f878152600e60209081526040909120600101919091558186526130179088018861527a565b8560200190600381111561302d5761302d614849565b9081600381111561304057613040614849565b905250436040808701919091528051808201825290602089019060029083908390808284375f920191909152505050606080870191909152613088906080890190890161478a565b6001600160a01b031660a0808701919091526130a990880160808901614b4a565b60ff1660c0808701919091526130c1908801886156b1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261310e9061010089019089016156f3565b15156101c08601525f610140860181905261016086018190526040805160208101909152818152610180870152336101a0870152600b8161315560a08b0160808c01614b4a565b60ff1660ff1681526020019081526020015f20805461317390614ef9565b80601f016020809104026020016040519081016040528092919081815260200182805461319f90614ef9565b80156131ea5780601f106131c1576101008083540402835291602001916131ea565b820191905f5260205f20905b8154815290600101906020018083116131cd57829003601f168201915b505050505090505f8151116132115760405162461bcd60e51b815260040161098890615243565b5f61322260808a0160608b0161478a565b6001600160a01b031663fefd9a8b89858561324060a08f018f6156b1565b8f8060c0019061325091906156b1565b6040518863ffffffff1660e01b8152600401613272979695949392919061570e565b6020604051808303815f875af115801561328e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132b291906152d7565b5f818152600960205260409020549091506001600160a01b031681816132ee576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b03168281613328576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561338657613386614849565b0217905550604082015181600201556060820151816003019060026133ac929190614716565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906134059082615762565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c82019061346d9082615762565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091556004546134b9911633308961443b565b608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561351657613516614849565b02179055506040820151816002015560608201518160030190600261353c929190614716565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906135959082615762565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906135fd9082615762565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90613663908d9089908d90600401615817565b6020604051808303815f875af115801561367f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136a3919061511b565b6136c057604051630d8dbe2560e01b815260040160405180910390fd5b6136d060808c0160608d0161478a565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b60405161370a929190614ed9565b60405180910390a2895f516020615acb5f395f51905f525f6001604051613732929190614f73565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff168181600681111561376b5761376b614849565b0361379057826001826040516337e1404160e01b815260040161098893929190614f2b565b60058160068111156137a4576137a4614849565b036137c55760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156137d9576137d9614849565b036137fa57604051633de16e3560e11b815260048101849052602401610988565b5f6138058483614158565b935090508061382a57604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561387357613873614849565b0217905550835f516020615acb5f395f51905f52836006604051613898929190614f73565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516138d292919061585c565b60405180910390a25050919050565b6138e9613a08565b6001600160a01b0381161580159061390e57505f546001600160a01b03828116911614155b819061392e576040516375ac4eb760e11b815260040161098891906147d0565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab09083906147d0565b6001600160a01b0381165f90815260076020526040902054819060ff16156139b55760405163b29d459560e01b815260040161098891906147d0565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab09083906147d0565b33613a1161190a565b6001600160a01b0316146112ff573360405163118cdaa760e01b815260040161098891906147d0565b8035613a595760405163055f269d60e01b815260040160405180910390fd5b5f816020013511613a7d5760405163055f269d60e01b815260040160405180910390fd5b5f816040013511613aa15760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613b2961447a565b610acc8161449f565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613be7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c0e9190810190615933565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613cad576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613c79908890889086906004016159f8565b5f604051808303815f87803b158015613c90575f5ffd5b505af1158015613ca2573d5f5f3e3d5ffd5b505050505050505050565b825f03613d4e575f858152601060205260409020546001600160a01b03168015613ce557613ce56001600160a01b03831682856140fb565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d19908990899087906004016159f8565b5f604051808303815f87803b158015613d30575f5ffd5b505af1158015613d42573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d8e57506001600160a01b03811615155b15613dca57612710613da461ffff8416876152a1565b613dae91906152b8565b92508215613dca57613dca6001600160a01b03851682856140fb565b5f613dd584876152ee565b90505f876001600160401b03811115613df057613df0614f8e565b604051908082528060200260200182016040528015613e19578160200160208202803683370190505b5090505f613e2789846152b8565b90505f805b8a811015613e665782848281518110613e4757613e47615210565b6020908102919091010152613e5c8383614f60565b9150600101613e2c565b505f613e7282866152ee565b90508015613eaf578084613e8760018e6152ee565b81518110613e9757613e97615210565b60200260200101818151613eab9190614f60565b9052505b600154613ec9906001600160a01b038b81169116876144a7565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f0d93929190615a58565b5f604051808303815f87803b158015613f24575f5ffd5b505af1158015613f36573d5f5f3e3d5ffd5b5050600154613f5492506001600160a01b038c81169250165f6144a7565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613f86929190615a8d565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613fd2939291906159f8565b5f604051808303815f87803b158015613fe9575f5ffd5b505af1158015613ffb573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d81111561403657614036614849565b14806140535750600281600d81111561405157614051614849565b145b1561408b575f5b604051908082528060200260200182016040528015614083578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa9250505080156140f157506040513d5f823e601f3d908101601f191682016040526140ee9190810190615933565b60015b614083575f61405a565b61415383846001600160a01b031663a9059cbb8585604051602401614121929190615ab1565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614533565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa1580156141d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141f691906152d7565b9050600185600681111561420c5761420c614849565b14801561421857508042115b1561422b576001809350935050506142d9565b600285600681111561423f5761423f614849565b14801561424c5750815142115b1561426057600160039350935050506142d9565b600385600681111561427457614274614849565b1480156142845750816020015142115b1561429857600160069350935050506142d9565b60048560068111156142ac576142ac614849565b1480156142bc5750816040015142115b156142d0576001600a9350935050506142d9565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561430457614304614849565b0361432957826001826040516337e1404160e01b815260040161098893929190614f2b565b600581600681111561433d5761433d614849565b0361435e5760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561437257614372614849565b0361439357604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d8111156143dc576143dc614849565b0217905550825f516020615acb5f395f51905f52826006604051614401929190614f73565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612cac92919061585c565b6040516001600160a01b0384811660248301528381166044830152606482018390526144749186918216906323b872dd90608401614121565b50505050565b614482614596565b6112ff57604051631afcd79f60e31b815260040160405180910390fd5b612cc161447a565b5f836001600160a01b031663095ea7b384846040516024016144ca929190615ab1565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061450384826145af565b6144745761452d84856001600160a01b031663095ea7b3865f604051602401614121929190615ab1565b61447484825b5f5f60205f8451602086015f885af180614552576040513d5f823e3d81fd5b50505f513d91508115614569578060011415614576565b6001600160a01b0384163b155b156144745783604051635274afe760e01b815260040161098891906147d0565b5f61459f613af7565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156145ee575081156145e057806001146145ee565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614620614744565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b600183019183908215614706579160200282015f5b838211156146d457833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261468a565b80156147045782816101000a81549063ffffffff02191690556004016020816003010492830192600103026146d4565b505b50614712929150614762565b5090565b8260028101928215614706579160200282015b82811115614706578251825591602001919060010190614729565b60405180604001604052806002906020820280368337509192915050565b5b80821115614712575f8155600101614763565b6001600160a01b0381168114610acc575f5ffd5b5f6020828403121561479a575f5ffd5b81356147a581614776565b9392505050565b5f602082840312156147bc575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147f2575f5ffd5b919050565b5f5f60408385031215614808575f5ffd5b614811836147e4565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f6060828403121561483f575f5ffd5b6147a5838361481f565b634e487b7160e01b5f52602160045260245ffd5b600e811061486d5761486d614849565b9052565b60208101613b1b828461485d565b6004811061486d5761486d614849565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526148cd602082018f61487f565b8c60408201528b60608201526148e6608082018c6147c3565b60ff8a1660a08201526101c060c08201525f6149066101c083018b61488f565b61491360e084018b6147c3565b61492161010084018a6147c3565b8761012084015286610140840152828103610160840152614942818761488f565b9150506149536101808301856147c3565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015614474578151845260209384019390910190600101614972565b805182525f60208201516149a8602085018261487f565b506040820151604084015260608201516149c5606085018261496f565b50608082015160a084015260a08201516149e260c08501826147c3565b5060c082015160ff811660e08501525060e0820151610200610100850152614a0e61020085018261488f565b9050610100830151614a246101208601826147c3565b50610120830151614a396101408601826147c3565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614a6b828261488f565b9150506101a0830151614a826101c08601826147c3565b506101c08301518015156101e0860152614083565b602081525f6147a56020830184614991565b80356147f281614776565b5f5f5f5f5f5f5f610120888a031215614acb575f5ffd5b8735614ad681614776565b96506020880135614ae681614776565b95506040880135614af681614776565b94506060880135614b0681614776565b93506080880135614b1681614776565b925060a08801359150614b2c8960c08a0161481f565b905092959891949750929550565b803560ff811681146147f2575f5ffd5b5f60208284031215614b5a575f5ffd5b6147a582614b3a565b602081525f6147a5602083018461488f565b5f5f60408385031215614b86575f5ffd5b823591506020830135614b9881614776565b809150509250929050565b5f5f83601f840112614bb3575f5ffd5b5081356001600160401b03811115614bc9575f5ffd5b6020830191508360208285010111156142d9575f5ffd5b5f5f5f5f5f60608688031215614bf4575f5ffd5b8535945060208601356001600160401b03811115614c10575f5ffd5b614c1c88828901614ba3565b90955093505060408601356001600160401b03811115614c3a575f5ffd5b614c4688828901614ba3565b969995985093965092949392505050565b5f5f60408385031215614c68575f5ffd5b50508035926020909101359150565b5f5f5f60408486031215614c89575f5ffd5b614c9284614b3a565b925060208401356001600160401b03811115614cac575f5ffd5b614cb886828701614ba3565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613b1b565b8215158152604081016147a5602083018461485d565b5f60208284031215614d0c575f5ffd5b81356001600160401b03811115614d21575f5ffd5b820161010081850312156147a5575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d8d60e08401826147c3565b50610100830151614da561010084018261ffff169052565b50610120830151614dbd61012084018261ffff169052565b50610140830151614dd561014084018261ffff169052565b50610160830151614ded61016084018261ffff169052565b50610180830151614e0561018084018261ffff169052565b506101a0830151614e1f6101a084018263ffffffff169052565b506101c0830151614e396101c084018263ffffffff169052565b5092915050565b5f5f60408385031215614e51575f5ffd5b82359150614e6160208401614b3a565b90509250929050565b6007811061486d5761486d614849565b60208101613b1b8284614e6a565b5f6101e0828403128015614e9a575f5ffd5b509092915050565b5f5f60608385031215614eb3575f5ffd5b614ebc836147e4565b915083606084011115614ecd575f5ffd5b50926020919091019150565b828152604060208201525f614ef16040830184614991565b949350505050565b600181811c90821680614f0d57607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614f3f6020830185614e6a565b614ef16040830184614e6a565b634e487b7160e01b5f52601160045260245ffd5b80820180821115613b1b57613b1b614f4c565b60408101614f818285614e6a565b6147a56020830184614e6a565b634e487b7160e01b5f52604160045260245ffd5b601f82111561415357805f5260205f20601f840160051c81016020851015614fc75750805b601f840160051c820191505b81811015614fe6575f8155600101614fd3565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b0383111561501857615018614f8e565b61502c836150268354614ef9565b83614fa2565b5f601f841160018114615058575f85156150465750838201355b6150508682614fed565b845550614fe6565b5f83815260208120601f198716915b828110156150875786850135825560209485019460019092019101615067565b50868210156150a3575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b838152604060208201525f6151056040830184866150c4565b95945050505050565b8015158114610acc575f5ffd5b5f6020828403121561512b575f5ffd5b81516147a58161510e565b602081525f614ef16020830184866150c4565b604081525f61515c6040830186886150c4565b828103602084015261516f8185876150c4565b979650505050505050565b60ff84168152604060208201525f6151056040830184866150c4565b5f8151808452602084019350602083015f5b828110156151cf5781516001600160a01b03168652602095860195909101906001016151a8565b5093949350505050565b848152836020820152608060408201525f6151f76080830185615196565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b848152836020820152606060408201525f6145ee6060830184866150c4565b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f6020828403121561528a575f5ffd5b6147a5826147e4565b60208101613b1b828461487f565b8082028115828204841417613b1b57613b1b614f4c565b5f826152d257634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156152e7575f5ffd5b5051919050565b81810381811115613b1b57613b1b614f4c565b61ffff81168114610acc575f5ffd5b80356147f281615301565b5f6020828403121561532b575f5ffd5b81356147a581615301565b63ffffffff81168114610acc575f5ffd5b80356147f281615336565b5f60208284031215615362575f5ffd5b81356147a581615336565b5f8135613b1b81614776565b5f8135613b1b81615301565b5f8135613b1b81615336565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016154016153e460e0850161536d565b82546001600160a01b0319166001600160a01b0391909116178255565b6154316154116101008501615379565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154616154416101208501615379565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154916154716101408501615379565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6154c16154a16101608501615379565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6154f16154d16101808501615379565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161551d6155066101a08501615385565b825463ffffffff191663ffffffff91909116178255565b61415361552d6101c08501615385565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016155a060e08401614aa9565b6155ad60e08401826147c3565b506155bb6101008401615310565b61ffff166101008301526155d26101208401615310565b61ffff166101208301526155e96101408401615310565b61ffff166101408301526156006101608401615310565b61ffff166101608301526156176101808401615310565b61ffff1661018083015261562e6101a08401615347565b63ffffffff166101a08301526156476101c08401615347565b63ffffffff81166101c0840152614e39565b6040810181835f5b600281101561569057813561567581615336565b63ffffffff1683526020928301929190910190600101615661565b50505092915050565b5f600182016156aa576156aa614f4c565b5060010190565b5f5f8335601e198436030181126156c6575f5ffd5b8301803591506001600160401b038211156156df575f5ffd5b6020019150368190038213156142d9575f5ffd5b5f60208284031215615703575f5ffd5b81356147a58161510e565b87815286602082015260a060408201525f61572c60a083018861488f565b828103606084015261573f8187896150c4565b905082810360808401526157548185876150c4565b9a9950505050505050505050565b81516001600160401b0381111561577b5761577b614f8e565b61578f816157898454614ef9565b84614fa2565b6020601f8211600181146157bc575f83156157aa5750848201515b6157b48482614fed565b855550614fe6565b5f84815260208120601f198516915b828110156157eb57878501518255602094850194600190920191016157cb565b508482101561580857868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561585157815163ffffffff1683526020928301929091019060010161582c565b505050949350505050565b6040810161586a8285614e6a565b6147a5602083018461485d565b604051601f8201601f191681016001600160401b038111828210171561589f5761589f614f8e565b604052919050565b5f6001600160401b038211156158bf576158bf614f8e565b5060051b60200190565b5f82601f8301126158d8575f5ffd5b81516158eb6158e6826158a7565b615877565b8082825260208201915060208360051b86010192508583111561590c575f5ffd5b602085015b83811015615929578051835260209283019201615911565b5095945050505050565b5f5f60408385031215615944575f5ffd5b82516001600160401b03811115615959575f5ffd5b8301601f81018513615969575f5ffd5b80516159776158e6826158a7565b8082825260208201915060208360051b850101925087831115615998575f5ffd5b6020840193505b828410156159c35783516159b281614776565b82526020938401939091019061599f565b8095505050505060208301516001600160401b038111156159e2575f5ffd5b6159ee858286016158c9565b9150509250929050565b838152606060208201525f615a106060830185615196565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156151cf578151865260209586019590910190600101615a3a565b6001600160a01b03841681526060602082018190525f90615a7b90830185615196565b82810360408401526145ee8185615a28565b604081525f615a9f6040830185615196565b82810360208401526151058185615a28565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c806390173a4111610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b80639e57b9341161013c5780639e57b93414610607578063a87f4ab91461061a578063ac3d2f421461076c578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b806390173a41146105705780639117173c146105855780639231238614610598578063929a8faf146105ab57806399c6679d146105cc5780639c8570c8146105f4575f5ffd5b80635d1684181161022f5780637edcd7ab116101e95780637edcd7ab146104e757806381476ec21461050a578063830d71811461051d57806385814243146105305780638da5cb5b146105435780638dcdd86b1461054b5780638e5ce3ad1461055d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e036600461478a565b61092e565b005b61030f6102f53660046147ac565b5f908152600960205260409020546001600160a01b031690565b60405161031c91906147d0565b60405180910390f35b61030f6103333660046147ac565b60096020525f90815260409020546001600160a01b031681565b61036061035b3660046147f7565b6109da565b60405163ffffffff909116815260200161031c565b6102e561038336600461478a565b610a16565b6102e561039636600461482f565b610abb565b6103bd6103a93660046147ac565b5f908152600f602052604090205460ff1690565b60405161031c9190614871565b6103dd6103d83660046147ac565b610acf565b60405161031c9e9d9c9b9a999897969594939291906148bd565b61040a6104053660046147ac565b610c7a565b60405161031c9190614a97565b6104366104253660046147ac565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e5610452366004614ab4565b610ef7565b6102e56104653660046147ac565b611135565b6102e561047836600461478a565b6111c4565b61049061048b366004614b4a565b611257565b60405161031c9190614b63565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ee565b6102e56104cf366004614b75565b611301565b6102e56104e23660046147ac565b6113c1565b6104fa6104f5366004614be0565b6114b4565b604051901515815260200161031c565b6102e5610518366004614c57565b61170a565b6102e561052b366004614c77565b6117fe565b60015461030f906001600160a01b031681565b61030f61190a565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b610578611938565b60405161031c9190614cc5565b6102e56105933660046147ac565b61197e565b6105786105a63660046147ac565b611aec565b6105be6105b93660046147ac565b611b45565b60405161031c929190614ce6565b61030f6105da3660046147ac565b5f908152601060205260409020546001600160a01b031690565b6104fa610602366004614be0565b611b6c565b610436610615366004614cfc565b611e04565b61075f604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614d33565b61030f61077a3660046147ac565b5f908152600a60205260409020546001600160a01b031690565b6102e56107a2366004614e40565b6123ce565b6102e56107b536600461478a565b61248a565b6102e56107c8366004614c57565b612531565b6104fa6107db36600461478a565b60076020525f908152604090205460ff1681565b61043660065481565b6102e5610806366004614b75565b6125ee565b6102e56108193660046147ac565b6126a8565b61084061082c3660046147ac565b5f908152600d602052604090205460ff1690565b60405161031c9190614e7a565b6102e561085b366004614e88565b6126e5565b6102e561086e36600461478a565b612972565b6102e5610881366004614ea2565b612a0c565b60025461030f906001600160a01b031681565b6102e56108a736600461478a565b612cb9565b6108bf6108ba366004614cfc565b612cf3565b60405161031c929190614ed9565b6103bd6108db3660046147ac565b613747565b6102e56108ee36600461478a565b6138e1565b61030f6109013660046147ac565b600a6020525f90815260409020546001600160a01b031681565b6102e561092936600461478a565b613979565b610936613a08565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e613a08565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b815260040161098891906147d0565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab09083906147d0565b60405180910390a150565b610ac3613a08565b610acc81613a3a565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614ef9565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614ef9565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c826145f8565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614849565b6003811115610cd057610cd0614849565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614ef9565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614ef9565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614ef9565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f00613af7565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613b21565b610fa9876126a8565b610fb28b6138e1565b610fbb8a612972565b610fc48961092e565b610fcd88610a16565b610fd686613a3a565b604080516101e081018252620186a080825261c3506020808401829052612710948401859052603260608501819052620493e060808601819052620f424060a0870181905261138860c088018190525f60e089018190526105dc6101008a015261012089018190526109c46101408a018190526101608a018390526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b03191669027104e202710000017760a21b179055805467ffffffffffffffff191690556110c061190a565b6001600160a01b03168c6001600160a01b0316146110e1576110e18c612cb9565b831561112757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113d613a08565b5f8181526009602052604090205481906001600160a01b0316611176576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cc613a08565b6001600160a01b0381165f90815260076020526040902054819060ff16611207576040516321ac7c5f60e01b815260040161098891906147d0565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab09083906147d0565b600b6020525f90815260409020805461126f90614ef9565b80601f016020809104026020016040519081016040528092919081815260200182805461129b90614ef9565b80156112e65780601f106112bd576101008083540402835291602001916112e6565b820191905f5260205f20905b8154815290600101906020018083116112c957829003601f168201915b505050505081565b6112f6613a08565b6112ff5f613b32565b565b611309613a08565b6001600160a01b0381161580159061133a57505f828152600a60205260409020546001600160a01b03828116911614155b829061135c576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409081902080546001600160a01b0319166001600160a01b0384161790555182907f53661e3e12f23eea1e322a5352171ad3e4407d1394f869f53bb148c27e00908a906113b59084906147d0565b60405180910390a25050565b5f546001600160a01b031633146113eb5760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff16600181600681111561141057611410614849565b1461143557816001826040516337e1404160e01b815260040161098893929190614f2b565b5f828152600d60205260409020805460ff1916600217905560155461145a9042614f60565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f516020615acb5f395f51905f52600160026040516113b5929190614f73565b5f5f6114bf87610c7a565b5f888152600d602052604090205490915060ff1660048160068111156114e7576114e7614849565b148860048390919261150f576040516337e1404160e01b815260040161098893929190614f2b565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611572576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f898152600860205260409020600c0161158f888a83615001565b505f898152600d60205260409020805460ff191660051790556101c08301511561168957846115d157604051631eae1a4d60e31b815260040160405180910390fd5b8261010001516001600160a01b031663258ae58289896040516115f59291906150b5565b6040519081900381206001600160e01b031960e084901b16825261161f918a908a906004016150ec565b602060405180830381865afa15801561163a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165e919061511b565b935087878561168257604051632f9f8ab960e01b8152600401610988929190615136565b505061168e565b600193505b61169789613ba2565b887f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b898989896040516116cd9493929190615149565b60405180910390a2885f516020615acb5f395f51905f52600460056040516116f6929190614f73565b60405180910390a250505095945050505050565b5f546001600160a01b031633146117345760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff16600281600681111561176457611764614849565b1461178957836002826040516337e1404160e01b815260040161098893929190614f2b565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f516020615acb5f395f51905f52600260036040516117f0929190614f73565b60405180910390a250505050565b611806613a08565b806118425760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b60205260409020805461185e90614ef9565b1590506118ad5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b602052604090206118c9828483615001565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da21958383836040516118fd9392919061517a565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b61195960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff1660068160068111156119a3576119a3614849565b1482906119c657604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c602052604090205482816119f7576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c60205260408120819055611a118461400e565b5f858152601160205260409020546002549192506001600160a01b0390811691611a3e91839116856140fb565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611a749088908790879087906004016151d9565b5f604051808303815f87803b158015611a8b575f5ffd5b505af1158015611a9d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611add929190918252602082015260400190565b60405180910390a25050505050565b611b0d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611b628482614158565b9250925050915091565b5f5f611b7787610c7a565b5f888152600d602052604090205490915060ff166003816006811115611b9f57611b9f614849565b1488600383909192611bc7576040516337e1404160e01b815260040161098893929190614f2b565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611c2b576040516308f3034360e31b815260048101929092526024820152604401610988565b5050606083015160200151899042811115611c625760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611c8d57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611c9f9291906150b5565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611ce19042614f60565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611d2e908d9085908c908c90600401615224565b6020604051808303815f875af1158015611d4a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6e919061511b565b9450888886611d9257604051632f9f8ab960e01b8152600401610988929190615136565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611dc6929190615136565b60405180910390a2895f516020615acb5f395f51905f5260036004604051611def929190614f73565b60405180910390a25050505095945050505050565b5f80600b81611e1960a0860160808701614b4a565b60ff1660ff1681526020019081526020015f208054611e3790614ef9565b905011611e565760405162461bcd60e51b815260040161098890615243565b5f601281611e67602086018661527a565b6003811115611e7857611e78614849565b6003811115611e8957611e89614849565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb0579050505050505090505f81600160028110611f0757611f07615210565b602002015163ffffffff1611835f016020810190611f25919061527a565b90611f445760405163286c068d60e11b81526004016109889190615293565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c08601529283169391909216911561206f576101a081015163ffffffff16846001602002015163ffffffff161015865f01602081019061204e919061527a565b9061206d5760405163010b971d60e31b81526004016109889190615293565b505b6101c081015163ffffffff16156120be576101c081015184519063ffffffff90811690821610156120bc57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b604086013560208701358110156120eb5760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f91612710916121099161ffff16906152a1565b61211391906152b8565b61271061ffff1683610160015161ffff1660156001015461213491906152a1565b61213e91906152b8565b61271061ffff1684610140015161ffff1660155f015461215e91906152a1565b61216891906152b8565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa1580156121b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d891906152d7565b6121e29190614f60565b6121ec91906152ee565b6121f69190614f60565b6122009190614f60565b61220a9190614f60565b90505f6122186001866152ee565b6122239060046152a1565b61222e90600e614f60565b90505f85845f015161224091906152a1565b90508186856020015161225391906152a1565b61225d91906152a1565b6122679082614f60565b905060018611156122af57600261227f6001886152ee565b61228990886152a1565b856040015161229891906152a1565b6122a291906152b8565b6122ac9082614f60565b90505b81868560c001516122c091906152a1565b6122ca91906152a1565b6122d49082614f60565b9050828685606001516122e791906152a1565b6122f191906152a1565b6122fb9082614f60565b905084846080015161230d91906152a1565b6123179082614f60565b9050600185111561235f57600261232f6001876152ee565b61233990876152a1565b856040015161234891906152a1565b61235291906152b8565b61235c9082614f60565b90505b60a084015161236e9082614f60565b610100850151909150612710906123899061ffff1682614f60565b61239390836152a1565b61239d91906152b8565b975087806123c157604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f546001600160a01b03163314806123f057506003546001600160a01b031633145b61240d57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156124235750600d60ff821611155b6124685760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b612486828260ff16600d81111561248157612481614849565b6142e0565b5050565b612492613a08565b6001600160a01b0381166124e85760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b0316331461255c576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b1580156125a6575f5ffd5b505af11580156125b8573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee542826040516113b591815260200190565b6125f6613a08565b6001600160a01b0381161580159061262757505f828152600960205260409020546001600160a01b03828116911614155b8290612649576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b6126b0613a08565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b6126ed613a08565b6127106127026101208301610100840161531b565b61ffff16111561271a6101208301610100840161531b565b9061273f576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127556101408301610120840161531b565b61ffff16111561276d6101408301610120840161531b565b90612792576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127a86101608301610140840161531b565b61ffff1611156127c06101608301610140840161531b565b906127e557604051633239953960e01b815261ffff9091166004820152602401610988565b506127106127fb6101808301610160840161531b565b61ffff1611156128136101808301610160840161531b565b9061283857604051633239953960e01b815261ffff9091166004820152602401610988565b5061271061284e6101a08301610180840161531b565b61ffff1611156128666101a08301610180840161531b565b9061288b57604051633239953960e01b815261ffff9091166004820152602401610988565b5061289e6101408201610120830161531b565b61ffff1615806128c757505f6128bb610100830160e0840161478a565b6001600160a01b031614155b6128e45760405163015f92ff60e51b815260040160405180910390fd5b6128f66101e082016101c08301615352565b63ffffffff1661290e6101c083016101a08401615352565b63ffffffff161015612933576040516392f55c6560e01b815260040160405180910390fd5b8060186129408282615391565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061554f565b61297a613a08565b6001600160a01b038116158015906129a057506001546001600160a01b03828116911614155b81906129c0576040516320252f0b60e01b815260040161098891906147d0565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab09083906147d0565b612a14613a08565b612a216020820182615352565b63ffffffff16612a376040830160208401615352565b63ffffffff1610158015612a5c57505f612a546020830183615352565b63ffffffff16115b612a7957604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612bb2576101a081015163ffffffff16612b626040840160208501615352565b63ffffffff161015612b7a6040840160208501615352565b826101a001519091612baf57604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612c29576101c081015163ffffffff16612bdc6020840184615352565b63ffffffff161015612bf16020840184615352565b826101c001519091612c265760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612c3f57612c3f614849565b6003811115612c5057612c50614849565b815260208101919091526040015f20612c6a916002614675565b50826003811115612c7d57612c7d614849565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612cac9190615659565b60405180910390a2505050565b612cc1613a08565b6001600160a01b038116612cea575f604051631e4fbdf760e01b815260040161098891906147d0565b610acc81613b32565b5f612cfc6145f8565b5f601281612d0d602087018761527a565b6003811115612d1e57612d1e614849565b6003811115612d2f57612d2f614849565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612d56579050505050505090505f81600160028110612dad57612dad615210565b602002015163ffffffff1611845f016020810190612dcb919061527a565b90612dea5760405163286c068d60e11b81526004016109889190615293565b50602084013542811015612e1457604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612e425760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612e5a4260408901356152ee565b612e649190614f60565b612e6e9190614f60565b905060055481108190612e97576040516313b783af60e21b815260040161098891815260200190565b5060075f612eab608088016060890161478a565b6001600160a01b0316815260208101919091526040015f205460ff16612ed7608087016060880161478a565b90612ef65760405163295a6a6f60e11b815260040161098891906147d0565b505f612f0186611e04565b60068054965090915085905f612f1683615699565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff191660011790556010909452829020805433941693909317909255601654919250612ff19190890135614f60565b5f878152600e60209081526040909120600101919091558186526130179088018861527a565b8560200190600381111561302d5761302d614849565b9081600381111561304057613040614849565b905250436040808701919091528051808201825290602089019060029083908390808284375f920191909152505050606080870191909152613088906080890190890161478a565b6001600160a01b031660a0808701919091526130a990880160808901614b4a565b60ff1660c0808701919091526130c1908801886156b1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261310e9061010089019089016156f3565b15156101c08601525f610140860181905261016086018190526040805160208101909152818152610180870152336101a0870152600b8161315560a08b0160808c01614b4a565b60ff1660ff1681526020019081526020015f20805461317390614ef9565b80601f016020809104026020016040519081016040528092919081815260200182805461319f90614ef9565b80156131ea5780601f106131c1576101008083540402835291602001916131ea565b820191905f5260205f20905b8154815290600101906020018083116131cd57829003601f168201915b505050505090505f8151116132115760405162461bcd60e51b815260040161098890615243565b5f61322260808a0160608b0161478a565b6001600160a01b031663fefd9a8b89858561324060a08f018f6156b1565b8f8060c0019061325091906156b1565b6040518863ffffffff1660e01b8152600401613272979695949392919061570e565b6020604051808303815f875af115801561328e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132b291906152d7565b5f818152600960205260409020549091506001600160a01b031681816132ee576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b03168281613328576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561338657613386614849565b0217905550604082015181600201556060820151816003019060026133ac929190614716565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906134059082615762565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c82019061346d9082615762565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091556004546134b9911633308961443b565b608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff19919091169083600381111561351657613516614849565b02179055506040820151816002015560608201518160030190600261353c929190614716565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906135959082615762565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906135fd9082615762565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091555f5460405163291a691b60e01b815291169063291a691b90613663908d9089908d90600401615817565b6020604051808303815f875af115801561367f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136a3919061511b565b6136c057604051630d8dbe2560e01b815260040160405180910390fd5b6136d060808c0160608d0161478a565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b60405161370a929190614ed9565b60405180910390a2895f516020615acb5f395f51905f525f6001604051613732929190614f73565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff168181600681111561376b5761376b614849565b0361379057826001826040516337e1404160e01b815260040161098893929190614f2b565b60058160068111156137a4576137a4614849565b036137c55760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156137d9576137d9614849565b036137fa57604051633de16e3560e11b815260048101849052602401610988565b5f6138058483614158565b935090508061382a57604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561387357613873614849565b0217905550835f516020615acb5f395f51905f52836006604051613898929190614f73565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516138d292919061585c565b60405180910390a25050919050565b6138e9613a08565b6001600160a01b0381161580159061390e57505f546001600160a01b03828116911614155b819061392e576040516375ac4eb760e11b815260040161098891906147d0565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab09083906147d0565b6001600160a01b0381165f90815260076020526040902054819060ff16156139b55760405163b29d459560e01b815260040161098891906147d0565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab09083906147d0565b33613a1161190a565b6001600160a01b0316146112ff573360405163118cdaa760e01b815260040161098891906147d0565b8035613a595760405163055f269d60e01b815260040160405180910390fd5b5f816020013511613a7d5760405163055f269d60e01b815260040160405180910390fd5b5f816040013511613aa15760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613b2961447a565b610acc8161449f565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613be7573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613c0e9190810190615933565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613cad576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613c79908890889086906004016159f8565b5f604051808303815f87803b158015613c90575f5ffd5b505af1158015613ca2573d5f5f3e3d5ffd5b505050505050505050565b825f03613d4e575f858152601060205260409020546001600160a01b03168015613ce557613ce56001600160a01b03831682856140fb565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613d19908990899087906004016159f8565b5f604051808303815f87803b158015613d30575f5ffd5b505af1158015613d42573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613d8e57506001600160a01b03811615155b15613dca57612710613da461ffff8416876152a1565b613dae91906152b8565b92508215613dca57613dca6001600160a01b03851682856140fb565b5f613dd584876152ee565b90505f876001600160401b03811115613df057613df0614f8e565b604051908082528060200260200182016040528015613e19578160200160208202803683370190505b5090505f613e2789846152b8565b90505f805b8a811015613e665782848281518110613e4757613e47615210565b6020908102919091010152613e5c8383614f60565b9150600101613e2c565b505f613e7282866152ee565b90508015613eaf578084613e8760018e6152ee565b81518110613e9757613e97615210565b60200260200101818151613eab9190614f60565b9052505b600154613ec9906001600160a01b038b81169116876144a7565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613f0d93929190615a58565b5f604051808303815f87803b158015613f24575f5ffd5b505af1158015613f36573d5f5f3e3d5ffd5b5050600154613f5492506001600160a01b038c81169250165f6144a7565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613f86929190615a8d565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613fd2939291906159f8565b5f604051808303815f87803b158015613fe9575f5ffd5b505af1158015613ffb573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d81111561403657614036614849565b14806140535750600281600d81111561405157614051614849565b145b1561408b575f5b604051908082528060200260200182016040528015614083578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa9250505080156140f157506040513d5f823e601f3d908101601f191682016040526140ee9190810190615933565b60015b614083575f61405a565b61415383846001600160a01b031663a9059cbb8585604051602401614121929190615ab1565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050614533565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa1580156141d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141f691906152d7565b9050600185600681111561420c5761420c614849565b14801561421857508042115b1561422b576001809350935050506142d9565b600285600681111561423f5761423f614849565b14801561424c5750815142115b1561426057600160039350935050506142d9565b600385600681111561427457614274614849565b1480156142845750816020015142115b1561429857600160069350935050506142d9565b60048560068111156142ac576142ac614849565b1480156142bc5750816040015142115b156142d0576001600a9350935050506142d9565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff169081600681111561430457614304614849565b0361432957826001826040516337e1404160e01b815260040161098893929190614f2b565b600581600681111561433d5761433d614849565b0361435e5760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561437257614372614849565b0361439357604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d8111156143dc576143dc614849565b0217905550825f516020615acb5f395f51905f52826006604051614401929190614f73565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612cac92919061585c565b6040516001600160a01b0384811660248301528381166044830152606482018390526144749186918216906323b872dd90608401614121565b50505050565b614482614596565b6112ff57604051631afcd79f60e31b815260040160405180910390fd5b612cc161447a565b5f836001600160a01b031663095ea7b384846040516024016144ca929190615ab1565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050905061450384826145af565b6144745761452d84856001600160a01b031663095ea7b3865f604051602401614121929190615ab1565b61447484825b5f5f60205f8451602086015f885af180614552576040513d5f823e3d81fd5b50505f513d91508115614569578060011415614576565b6001600160a01b0384163b155b156144745783604051635274afe760e01b815260040161098891906147d0565b5f61459f613af7565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156145ee575081156145e057806001146145ee565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f8152602001614620614744565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b600183019183908215614706579160200282015f5b838211156146d457833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261468a565b80156147045782816101000a81549063ffffffff02191690556004016020816003010492830192600103026146d4565b505b50614712929150614762565b5090565b8260028101928215614706579160200282015b82811115614706578251825591602001919060010190614729565b60405180604001604052806002906020820280368337509192915050565b5b80821115614712575f8155600101614763565b6001600160a01b0381168114610acc575f5ffd5b5f6020828403121561479a575f5ffd5b81356147a581614776565b9392505050565b5f602082840312156147bc575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106147f2575f5ffd5b919050565b5f5f60408385031215614808575f5ffd5b614811836147e4565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f6060828403121561483f575f5ffd5b6147a5838361481f565b634e487b7160e01b5f52602160045260245ffd5b600e811061486d5761486d614849565b9052565b60208101613b1b828461485d565b6004811061486d5761486d614849565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526148cd602082018f61487f565b8c60408201528b60608201526148e6608082018c6147c3565b60ff8a1660a08201526101c060c08201525f6149066101c083018b61488f565b61491360e084018b6147c3565b61492161010084018a6147c3565b8761012084015286610140840152828103610160840152614942818761488f565b9150506149536101808301856147c3565b8215156101a08301529f9e505050505050505050505050505050565b805f5b6002811015614474578151845260209384019390910190600101614972565b805182525f60208201516149a8602085018261487f565b506040820151604084015260608201516149c5606085018261496f565b50608082015160a084015260a08201516149e260c08501826147c3565b5060c082015160ff811660e08501525060e0820151610200610100850152614a0e61020085018261488f565b9050610100830151614a246101208601826147c3565b50610120830151614a396101408601826147c3565b506101408301516101608501526101608301516101808501526101808301518482036101a0860152614a6b828261488f565b9150506101a0830151614a826101c08601826147c3565b506101c08301518015156101e0860152614083565b602081525f6147a56020830184614991565b80356147f281614776565b5f5f5f5f5f5f5f610120888a031215614acb575f5ffd5b8735614ad681614776565b96506020880135614ae681614776565b95506040880135614af681614776565b94506060880135614b0681614776565b93506080880135614b1681614776565b925060a08801359150614b2c8960c08a0161481f565b905092959891949750929550565b803560ff811681146147f2575f5ffd5b5f60208284031215614b5a575f5ffd5b6147a582614b3a565b602081525f6147a5602083018461488f565b5f5f60408385031215614b86575f5ffd5b823591506020830135614b9881614776565b809150509250929050565b5f5f83601f840112614bb3575f5ffd5b5081356001600160401b03811115614bc9575f5ffd5b6020830191508360208285010111156142d9575f5ffd5b5f5f5f5f5f60608688031215614bf4575f5ffd5b8535945060208601356001600160401b03811115614c10575f5ffd5b614c1c88828901614ba3565b90955093505060408601356001600160401b03811115614c3a575f5ffd5b614c4688828901614ba3565b969995985093965092949392505050565b5f5f60408385031215614c68575f5ffd5b50508035926020909101359150565b5f5f5f60408486031215614c89575f5ffd5b614c9284614b3a565b925060208401356001600160401b03811115614cac575f5ffd5b614cb886828701614ba3565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613b1b565b8215158152604081016147a5602083018461485d565b5f60208284031215614d0c575f5ffd5b81356001600160401b03811115614d21575f5ffd5b820161010081850312156147a5575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614d8d60e08401826147c3565b50610100830151614da561010084018261ffff169052565b50610120830151614dbd61012084018261ffff169052565b50610140830151614dd561014084018261ffff169052565b50610160830151614ded61016084018261ffff169052565b50610180830151614e0561018084018261ffff169052565b506101a0830151614e1f6101a084018263ffffffff169052565b506101c0830151614e396101c084018263ffffffff169052565b5092915050565b5f5f60408385031215614e51575f5ffd5b82359150614e6160208401614b3a565b90509250929050565b6007811061486d5761486d614849565b60208101613b1b8284614e6a565b5f6101e0828403128015614e9a575f5ffd5b509092915050565b5f5f60608385031215614eb3575f5ffd5b614ebc836147e4565b915083606084011115614ecd575f5ffd5b50926020919091019150565b828152604060208201525f614ef16040830184614991565b949350505050565b600181811c90821680614f0d57607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614f3f6020830185614e6a565b614ef16040830184614e6a565b634e487b7160e01b5f52601160045260245ffd5b80820180821115613b1b57613b1b614f4c565b60408101614f818285614e6a565b6147a56020830184614e6a565b634e487b7160e01b5f52604160045260245ffd5b601f82111561415357805f5260205f20601f840160051c81016020851015614fc75750805b601f840160051c820191505b81811015614fe6575f8155600101614fd3565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b0383111561501857615018614f8e565b61502c836150268354614ef9565b83614fa2565b5f601f841160018114615058575f85156150465750838201355b6150508682614fed565b845550614fe6565b5f83815260208120601f198716915b828110156150875786850135825560209485019460019092019101615067565b50868210156150a3575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818382375f9101908152919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b838152604060208201525f6151056040830184866150c4565b95945050505050565b8015158114610acc575f5ffd5b5f6020828403121561512b575f5ffd5b81516147a58161510e565b602081525f614ef16020830184866150c4565b604081525f61515c6040830186886150c4565b828103602084015261516f8185876150c4565b979650505050505050565b60ff84168152604060208201525f6151056040830184866150c4565b5f8151808452602084019350602083015f5b828110156151cf5781516001600160a01b03168652602095860195909101906001016151a8565b5093949350505050565b848152836020820152608060408201525f6151f76080830185615196565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b848152836020820152606060408201525f6145ee6060830184866150c4565b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f6020828403121561528a575f5ffd5b6147a5826147e4565b60208101613b1b828461487f565b8082028115828204841417613b1b57613b1b614f4c565b5f826152d257634e487b7160e01b5f52601260045260245ffd5b500490565b5f602082840312156152e7575f5ffd5b5051919050565b81810381811115613b1b57613b1b614f4c565b61ffff81168114610acc575f5ffd5b80356147f281615301565b5f6020828403121561532b575f5ffd5b81356147a581615301565b63ffffffff81168114610acc575f5ffd5b80356147f281615336565b5f60208284031215615362575f5ffd5b81356147a581615336565b5f8135613b1b81614776565b5f8135613b1b81615301565b5f8135613b1b81615336565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016154016153e460e0850161536d565b82546001600160a01b0319166001600160a01b0391909116178255565b6154316154116101008501615379565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6154616154416101208501615379565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6154916154716101408501615379565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6154c16154a16101608501615379565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6154f16154d16101808501615379565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b506008810161551d6155066101a08501615385565b825463ffffffff191663ffffffff91909116178255565b61415361552d6101c08501615385565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e081016155a060e08401614aa9565b6155ad60e08401826147c3565b506155bb6101008401615310565b61ffff166101008301526155d26101208401615310565b61ffff166101208301526155e96101408401615310565b61ffff166101408301526156006101608401615310565b61ffff166101608301526156176101808401615310565b61ffff1661018083015261562e6101a08401615347565b63ffffffff166101a08301526156476101c08401615347565b63ffffffff81166101c0840152614e39565b6040810181835f5b600281101561569057813561567581615336565b63ffffffff1683526020928301929190910190600101615661565b50505092915050565b5f600182016156aa576156aa614f4c565b5060010190565b5f5f8335601e198436030181126156c6575f5ffd5b8301803591506001600160401b038211156156df575f5ffd5b6020019150368190038213156142d9575f5ffd5b5f60208284031215615703575f5ffd5b81356147a58161510e565b87815286602082015260a060408201525f61572c60a083018861488f565b828103606084015261573f8187896150c4565b905082810360808401526157548185876150c4565b9a9950505050505050505050565b81516001600160401b0381111561577b5761577b614f8e565b61578f816157898454614ef9565b84614fa2565b6020601f8211600181146157bc575f83156157aa5750848201515b6157b48482614fed565b855550614fe6565b5f84815260208120601f198516915b828110156157eb57878501518255602094850194600190920191016157cb565b508482101561580857868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561585157815163ffffffff1683526020928301929091019060010161582c565b505050949350505050565b6040810161586a8285614e6a565b6147a5602083018461485d565b604051601f8201601f191681016001600160401b038111828210171561589f5761589f614f8e565b604052919050565b5f6001600160401b038211156158bf576158bf614f8e565b5060051b60200190565b5f82601f8301126158d8575f5ffd5b81516158eb6158e6826158a7565b615877565b8082825260208201915060208360051b86010192508583111561590c575f5ffd5b602085015b83811015615929578051835260209283019201615911565b5095945050505050565b5f5f60408385031215615944575f5ffd5b82516001600160401b03811115615959575f5ffd5b8301601f81018513615969575f5ffd5b80516159776158e6826158a7565b8082825260208201915060208360051b850101925087831115615998575f5ffd5b6020840193505b828410156159c35783516159b281614776565b82526020938401939091019061599f565b8095505050505060208301516001600160401b038111156159e2575f5ffd5b6159ee858286016158c9565b9150509250929050565b838152606060208201525f615a106060830185615196565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156151cf578151865260209586019590910190600101615a3a565b6001600160a01b03841681526060602082018190525f90615a7b90830185615196565b82810360408401526145ee8185615a28565b604081525f615a9f6040830185615196565b82810360208401526151058185615a28565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6159d7806100d65f395ff3fe608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c806390173a4111610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b80639e57b9341161013c5780639e57b93414610607578063a87f4ab91461061a578063ac3d2f421461076c578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b806390173a41146105705780639117173c146105855780639231238614610598578063929a8faf146105ab57806399c6679d146105cc5780639c8570c8146105f4575f5ffd5b80635d1684181161022f5780637edcd7ab116101e95780637edcd7ab146104e757806381476ec21461050a578063830d71811461051d57806385814243146105305780638da5cb5b146105435780638dcdd86b1461054b5780638e5ce3ad1461055d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e0366004614683565b61092e565b005b61030f6102f53660046146a5565b5f908152600960205260409020546001600160a01b031690565b60405161031c91906146c9565b60405180910390f35b61030f6103333660046146a5565b60096020525f90815260409020546001600160a01b031681565b61036061035b3660046146f0565b6109da565b60405163ffffffff909116815260200161031c565b6102e5610383366004614683565b610a16565b6102e5610396366004614728565b610abb565b6103bd6103a93660046146a5565b5f908152600f602052604090205460ff1690565b60405161031c919061476a565b6103dd6103d83660046146a5565b610acf565b60405161031c9e9d9c9b9a999897969594939291906147b6565b61040a6104053660046146a5565b610c7a565b60405161031c9190614990565b6104366104253660046146a5565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e56104523660046149ad565b610ef7565b6102e56104653660046146a5565b611135565b6102e5610478366004614683565b6111c4565b61049061048b366004614a43565b611257565b60405161031c9190614a5c565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ee565b6102e56104cf366004614a6e565b611301565b6102e56104e23660046146a5565b6113c1565b6104fa6104f5366004614ad9565b6114b4565b604051901515815260200161031c565b6102e5610518366004614b50565b61177a565b6102e561052b366004614b70565b61186e565b60015461030f906001600160a01b031681565b61030f61197a565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b6105786119a8565b60405161031c9190614bbe565b6102e56105933660046146a5565b6119ee565b6105786105a63660046146a5565b611b5c565b6105be6105b93660046146a5565b611bb5565b60405161031c929190614bdf565b61030f6105da3660046146a5565b5f908152601060205260409020546001600160a01b031690565b6104fa610602366004614ad9565b611bdc565b610436610615366004614bf5565b611e74565b61075f604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614c2c565b61030f61077a3660046146a5565b5f908152600a60205260409020546001600160a01b031690565b6102e56107a2366004614d39565b61243e565b6102e56107b5366004614683565b6124fa565b6102e56107c8366004614b50565b6125a1565b6104fa6107db366004614683565b60076020525f908152604090205460ff1681565b61043660065481565b6102e5610806366004614a6e565b61265e565b6102e56108193660046146a5565b612718565b61084061082c3660046146a5565b5f908152600d602052604090205460ff1690565b60405161031c9190614d73565b6102e561085b366004614d81565b612755565b6102e561086e366004614683565b6129e2565b6102e5610881366004614d9b565b612a7c565b60025461030f906001600160a01b031681565b6102e56108a7366004614683565b612d29565b6108bf6108ba366004614bf5565b612d63565b60405161031c929190614dd2565b6103bd6108db3660046146a5565b613640565b6102e56108ee366004614683565b6137da565b61030f6109013660046146a5565b600a6020525f90815260409020546001600160a01b031681565b6102e5610929366004614683565b613872565b610936613901565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e613901565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b815260040161098891906146c9565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab09083906146c9565b60405180910390a150565b610ac3613901565b610acc81613933565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614df2565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614df2565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c826144f1565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614742565b6003811115610cd057610cd0614742565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614df2565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614df2565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f006139f0565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613a1a565b610fa987612718565b610fb28b6137da565b610fbb8a6129e2565b610fc48961092e565b610fcd88610a16565b610fd686613933565b604080516101e081018252620186a080825261c3506020808401829052612710948401859052603260608501819052620493e060808601819052620f424060a0870181905261138860c088018190525f60e089018190526105dc6101008a015261012089018190526109c46101408a018190526101608a018390526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b03191669027104e202710000017760a21b179055805467ffffffffffffffff191690556110c061197a565b6001600160a01b03168c6001600160a01b0316146110e1576110e18c612d29565b831561112757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113d613901565b5f8181526009602052604090205481906001600160a01b0316611176576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cc613901565b6001600160a01b0381165f90815260076020526040902054819060ff16611207576040516321ac7c5f60e01b815260040161098891906146c9565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab09083906146c9565b600b6020525f90815260409020805461126f90614df2565b80601f016020809104026020016040519081016040528092919081815260200182805461129b90614df2565b80156112e65780601f106112bd576101008083540402835291602001916112e6565b820191905f5260205f20905b8154815290600101906020018083116112c957829003601f168201915b505050505081565b6112f6613901565b6112ff5f613a2b565b565b611309613901565b6001600160a01b0381161580159061133a57505f828152600a60205260409020546001600160a01b03828116911614155b829061135c576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409081902080546001600160a01b0319166001600160a01b0384161790555182907f53661e3e12f23eea1e322a5352171ad3e4407d1394f869f53bb148c27e00908a906113b59084906146c9565b60405180910390a25050565b5f546001600160a01b031633146113eb5760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff16600181600681111561141057611410614742565b1461143557816001826040516337e1404160e01b815260040161098893929190614e24565b5f828152600d60205260409020805460ff1916600217905560155461145a9042614e59565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206159ab5f395f51905f52600160026040516113b5929190614e6c565b5f5f6114bf87610c7a565b5f888152600d602052604090205490915060ff1660048160068111156114e7576114e7614742565b148860048390919261150f576040516337e1404160e01b815260040161098893929190614e24565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611572576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f898152600860205260409020600c0161158f888a83614efa565b505f898152600d60205260409020805460ff191660051790556101c0830151156116f957846115d157604051631eae1a4d60e31b815260040160405180910390fd5b5f80546040516304cd0b0d60e11b8152600481018c90526001600160a01b039091169063099a161a90602401602060405180830381865afa158015611618573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163c9190614fae565b90508361010001516001600160a01b031663de12c6408a8a604051611662929190614fc5565b6040519081900381206001600160e01b031960e084901b16825261168e9185908c908c90600401614ffc565b602060405180830381865afa1580156116a9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116cd9190615028565b94508888866116f157604051632f9f8ab960e01b8152600401610988929190615043565b5050506116fe565b600193505b61170789613a9b565b887f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8989898960405161173d9493929190615056565b60405180910390a2885f5160206159ab5f395f51905f5260046005604051611766929190614e6c565b60405180910390a250505095945050505050565b5f546001600160a01b031633146117a45760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff1660028160068111156117d4576117d4614742565b146117f957836002826040516337e1404160e01b815260040161098893929190614e24565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206159ab5f395f51905f5260026003604051611860929190614e6c565b60405180910390a250505050565b611876613901565b806118b25760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b6020526040902080546118ce90614df2565b15905061191d5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b60205260409020611939828483614efa565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da219583838360405161196d93929190615087565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6119c960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611a1357611a13614742565b148290611a3657604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c60205260409020548281611a67576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c60205260408120819055611a8184613f07565b5f858152601160205260409020546002549192506001600160a01b0390811691611aae9183911685613ff4565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611ae49088908790879087906004016150ef565b5f604051808303815f87803b158015611afb575f5ffd5b505af1158015611b0d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611b4d929190918252602082015260400190565b60405180910390a25050505050565b611b7d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611bd28482614051565b9250925050915091565b5f5f611be787610c7a565b5f888152600d602052604090205490915060ff166003816006811115611c0f57611c0f614742565b1488600383909192611c37576040516337e1404160e01b815260040161098893929190614e24565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611c9b576040516308f3034360e31b815260048101929092526024820152604401610988565b5050606083015160200151899042811115611cd25760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611cfd57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611d0f929190614fc5565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611d519042614e59565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611d9e908d9085908c908c90600401614ffc565b6020604051808303815f875af1158015611dba573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dde9190615028565b9450888886611e0257604051632f9f8ab960e01b8152600401610988929190615043565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611e36929190615043565b60405180910390a2895f5160206159ab5f395f51905f5260036004604051611e5f929190614e6c565b60405180910390a25050505095945050505050565b5f80600b81611e8960a0860160808701614a43565b60ff1660ff1681526020019081526020015f208054611ea790614df2565b905011611ec65760405162461bcd60e51b81526004016109889061513a565b5f601281611ed76020860186615171565b6003811115611ee857611ee8614742565b6003811115611ef957611ef9614742565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f20579050505050505090505f81600160028110611f7757611f77615126565b602002015163ffffffff1611835f016020810190611f959190615171565b90611fb45760405163286c068d60e11b8152600401610988919061518a565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c0860152928316939190921691156120df576101a081015163ffffffff16846001602002015163ffffffff161015865f0160208101906120be9190615171565b906120dd5760405163010b971d60e31b8152600401610988919061518a565b505b6101c081015163ffffffff161561212e576101c081015184519063ffffffff908116908216101561212c57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b6040860135602087013581101561215b5760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f91612710916121799161ffff1690615198565b61218391906151af565b61271061ffff1683610160015161ffff166015600101546121a49190615198565b6121ae91906151af565b61271061ffff1684610140015161ffff1660155f01546121ce9190615198565b6121d891906151af565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612224573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122489190614fae565b6122529190614e59565b61225c91906151ce565b6122669190614e59565b6122709190614e59565b61227a9190614e59565b90505f6122886001866151ce565b612293906004615198565b61229e90600e614e59565b90505f85845f01516122b09190615198565b9050818685602001516122c39190615198565b6122cd9190615198565b6122d79082614e59565b9050600186111561231f5760026122ef6001886151ce565b6122f99088615198565b85604001516123089190615198565b61231291906151af565b61231c9082614e59565b90505b81868560c001516123309190615198565b61233a9190615198565b6123449082614e59565b9050828685606001516123579190615198565b6123619190615198565b61236b9082614e59565b905084846080015161237d9190615198565b6123879082614e59565b905060018511156123cf57600261239f6001876151ce565b6123a99087615198565b85604001516123b89190615198565b6123c291906151af565b6123cc9082614e59565b90505b60a08401516123de9082614e59565b610100850151909150612710906123f99061ffff1682614e59565b6124039083615198565b61240d91906151af565b9750878061243157604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f546001600160a01b031633148061246057506003546001600160a01b031633145b61247d57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156124935750600d60ff821611155b6124d85760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b6124f6828260ff16600d8111156124f1576124f1614742565b6141d9565b5050565b612502613901565b6001600160a01b0381166125585760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146125cc576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612616575f5ffd5b505af1158015612628573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee542826040516113b591815260200190565b612666613901565b6001600160a01b0381161580159061269757505f828152600960205260409020546001600160a01b03828116911614155b82906126b9576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b612720613901565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b61275d613901565b612710612772610120830161010084016151fb565b61ffff16111561278a610120830161010084016151fb565b906127af576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127c5610140830161012084016151fb565b61ffff1611156127dd610140830161012084016151fb565b90612802576040516301027fc160e21b815261ffff9091166004820152602401610988565b50612710612818610160830161014084016151fb565b61ffff161115612830610160830161014084016151fb565b9061285557604051633239953960e01b815261ffff9091166004820152602401610988565b5061271061286b610180830161016084016151fb565b61ffff161115612883610180830161016084016151fb565b906128a857604051633239953960e01b815261ffff9091166004820152602401610988565b506127106128be6101a0830161018084016151fb565b61ffff1611156128d66101a0830161018084016151fb565b906128fb57604051633239953960e01b815261ffff9091166004820152602401610988565b5061290e610140820161012083016151fb565b61ffff16158061293757505f61292b610100830160e08401614683565b6001600160a01b031614155b6129545760405163015f92ff60e51b815260040160405180910390fd5b6129666101e082016101c08301615232565b63ffffffff1661297e6101c083016101a08401615232565b63ffffffff1610156129a3576040516392f55c6560e01b815260040160405180910390fd5b8060186129b08282615271565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061542f565b6129ea613901565b6001600160a01b03811615801590612a1057506001546001600160a01b03828116911614155b8190612a30576040516320252f0b60e01b815260040161098891906146c9565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab09083906146c9565b612a84613901565b612a916020820182615232565b63ffffffff16612aa76040830160208401615232565b63ffffffff1610158015612acc57505f612ac46020830183615232565b63ffffffff16115b612ae957604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612c22576101a081015163ffffffff16612bd26040840160208501615232565b63ffffffff161015612bea6040840160208501615232565b826101a001519091612c1f57604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612c99576101c081015163ffffffff16612c4c6020840184615232565b63ffffffff161015612c616020840184615232565b826101c001519091612c965760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612caf57612caf614742565b6003811115612cc057612cc0614742565b815260208101919091526040015f20612cda91600261456e565b50826003811115612ced57612ced614742565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612d1c9190615539565b60405180910390a2505050565b612d31613901565b6001600160a01b038116612d5a575f604051631e4fbdf760e01b815260040161098891906146c9565b610acc81613a2b565b5f612d6c6144f1565b5f601281612d7d6020870187615171565b6003811115612d8e57612d8e614742565b6003811115612d9f57612d9f614742565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612dc6579050505050505090505f81600160028110612e1d57612e1d615126565b602002015163ffffffff1611845f016020810190612e3b9190615171565b90612e5a5760405163286c068d60e11b8152600401610988919061518a565b50602084013542811015612e8457604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612eb25760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612eca4260408901356151ce565b612ed49190614e59565b612ede9190614e59565b905060055481108190612f07576040516313b783af60e21b815260040161098891815260200190565b5060075f612f1b6080880160608901614683565b6001600160a01b0316815260208101919091526040015f205460ff16612f476080870160608801614683565b90612f665760405163295a6a6f60e11b815260040161098891906146c9565b505f612f7186611e74565b60068054965090915085905f612f8683615579565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506130619190890135614e59565b5f878152600e602090815260409091206001019190915581865261308790880188615171565b8560200190600381111561309d5761309d614742565b908160038111156130b0576130b0614742565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526130f89060808901908901614683565b6001600160a01b031660a08087019190915261311990880160808901614a43565b60ff1660c08087019190915261313190880188615591565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261317e9061010089019089016155d3565b15156101c08601525f610140860181905261016086018190526040805160208101909152818152610180870152336101a0870152600b816131c560a08b0160808c01614a43565b60ff1660ff1681526020019081526020015f2080546131e390614df2565b80601f016020809104026020016040519081016040528092919081815260200182805461320f90614df2565b801561325a5780601f106132315761010080835404028352916020019161325a565b820191905f5260205f20905b81548152906001019060200180831161323d57829003601f168201915b505050505090505f8151116132815760405162461bcd60e51b81526004016109889061513a565b5f61329260808a0160608b01614683565b6001600160a01b031663fefd9a8b8985856132b060a08f018f615591565b8f8060c001906132c09190615591565b6040518863ffffffff1660e01b81526004016132e297969594939291906155ee565b6020604051808303815f875af11580156132fe573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133229190614fae565b5f818152600960205260409020549091506001600160a01b0316818161335e576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b03168281613398576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff1991909116908360038111156133f6576133f6614742565b02179055506040820151816002015560608201518160030190600261341c92919061460f565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906134759082615642565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906134dd9082615642565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091556004546135299116333089614334565b5f5460405163291a691b60e01b81526001600160a01b039091169063291a691b9061355c908d9089908d906004016156f7565b6020604051808303815f875af1158015613578573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061359c9190615028565b6135b957604051630d8dbe2560e01b815260040160405180910390fd5b6135c960808c0160608d01614683565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b604051613603929190614dd2565b60405180910390a2895f5160206159ab5f395f51905f525f600160405161362b929190614e6c565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff168181600681111561366457613664614742565b0361368957826001826040516337e1404160e01b815260040161098893929190614e24565b600581600681111561369d5761369d614742565b036136be5760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156136d2576136d2614742565b036136f357604051633de16e3560e11b815260048101849052602401610988565b5f6136fe8483614051565b935090508061372357604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561376c5761376c614742565b0217905550835f5160206159ab5f395f51905f52836006604051613791929190614e6c565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516137cb92919061573c565b60405180910390a25050919050565b6137e2613901565b6001600160a01b0381161580159061380757505f546001600160a01b03828116911614155b8190613827576040516375ac4eb760e11b815260040161098891906146c9565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab09083906146c9565b6001600160a01b0381165f90815260076020526040902054819060ff16156138ae5760405163b29d459560e01b815260040161098891906146c9565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab09083906146c9565b3361390a61197a565b6001600160a01b0316146112ff573360405163118cdaa760e01b815260040161098891906146c9565b80356139525760405163055f269d60e01b815260040160405180910390fd5b5f8160200135116139765760405163055f269d60e01b815260040160405180910390fd5b5f81604001351161399a5760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613a22614373565b610acc81614398565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613ae0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613b079190810190615813565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ba6576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613b72908890889086906004016158d8565b5f604051808303815f87803b158015613b89575f5ffd5b505af1158015613b9b573d5f5f3e3d5ffd5b505050505050505050565b825f03613c47575f858152601060205260409020546001600160a01b03168015613bde57613bde6001600160a01b0383168285613ff4565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613c12908990899087906004016158d8565b5f604051808303815f87803b158015613c29575f5ffd5b505af1158015613c3b573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613c8757506001600160a01b03811615155b15613cc357612710613c9d61ffff841687615198565b613ca791906151af565b92508215613cc357613cc36001600160a01b0385168285613ff4565b5f613cce84876151ce565b90505f876001600160401b03811115613ce957613ce9614e87565b604051908082528060200260200182016040528015613d12578160200160208202803683370190505b5090505f613d2089846151af565b90505f805b8a811015613d5f5782848281518110613d4057613d40615126565b6020908102919091010152613d558383614e59565b9150600101613d25565b505f613d6b82866151ce565b90508015613da8578084613d8060018e6151ce565b81518110613d9057613d90615126565b60200260200101818151613da49190614e59565b9052505b600154613dc2906001600160a01b038b81169116876143a0565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613e0693929190615938565b5f604051808303815f87803b158015613e1d575f5ffd5b505af1158015613e2f573d5f5f3e3d5ffd5b5050600154613e4d92506001600160a01b038c81169250165f6143a0565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613e7f92919061596d565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613ecb939291906158d8565b5f604051808303815f87803b158015613ee2575f5ffd5b505af1158015613ef4573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613f2f57613f2f614742565b1480613f4c5750600281600d811115613f4a57613f4a614742565b145b15613f84575f5b604051908082528060200260200182016040528015613f7c578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613fea57506040513d5f823e601f3d908101601f19168201604052613fe79190810190615813565b60015b613f7c575f613f53565b61404c83846001600160a01b031663a9059cbb858560405160240161401a929190615991565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061442c565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa1580156140cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140ef9190614fae565b9050600185600681111561410557614105614742565b14801561411157508042115b15614124576001809350935050506141d2565b600285600681111561413857614138614742565b1480156141455750815142115b1561415957600160039350935050506141d2565b600385600681111561416d5761416d614742565b14801561417d5750816020015142115b1561419157600160069350935050506141d2565b60048560068111156141a5576141a5614742565b1480156141b55750816040015142115b156141c9576001600a9350935050506141d2565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff16908160068111156141fd576141fd614742565b0361422257826001826040516337e1404160e01b815260040161098893929190614e24565b600581600681111561423657614236614742565b036142575760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561426b5761426b614742565b0361428c57604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d8111156142d5576142d5614742565b0217905550825f5160206159ab5f395f51905f528260066040516142fa929190614e6c565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612d1c92919061573c565b6040516001600160a01b03848116602483015283811660448301526064820183905261436d9186918216906323b872dd9060840161401a565b50505050565b61437b61448f565b6112ff57604051631afcd79f60e31b815260040160405180910390fd5b612d31614373565b5f836001600160a01b031663095ea7b384846040516024016143c3929190615991565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506143fc84826144a8565b61436d5761442684856001600160a01b031663095ea7b3865f60405160240161401a929190615991565b61436d84825b5f5f60205f8451602086015f885af18061444b576040513d5f823e3d81fd5b50505f513d9150811561446257806001141561446f565b6001600160a01b0384163b155b1561436d5783604051635274afe760e01b815260040161098891906146c9565b5f6144986139f0565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156144e7575081156144d957806001146144e7565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161451961463d565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b6001830191839082156145ff579160200282015f5b838211156145cd57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614583565b80156145fd5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026145cd565b505b5061460b92915061465b565b5090565b82600281019282156145ff579160200282015b828111156145ff578251825591602001919060010190614622565b60405180604001604052806002906020820280368337509192915050565b5b8082111561460b575f815560010161465c565b6001600160a01b0381168114610acc575f5ffd5b5f60208284031215614693575f5ffd5b813561469e8161466f565b9392505050565b5f602082840312156146b5575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106146eb575f5ffd5b919050565b5f5f60408385031215614701575f5ffd5b61470a836146dd565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f60608284031215614738575f5ffd5b61469e8383614718565b634e487b7160e01b5f52602160045260245ffd5b600e811061476657614766614742565b9052565b60208101613a148284614756565b6004811061476657614766614742565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526147c6602082018f614778565b8c60408201528b60608201526147df608082018c6146bc565b60ff8a1660a08201526101c060c08201525f6147ff6101c083018b614788565b61480c60e084018b6146bc565b61481a61010084018a6146bc565b876101208401528661014084015282810361016084015261483b8187614788565b91505061484c6101808301856146bc565b8215156101a08301529f9e505050505050505050505050505050565b805f5b600281101561436d57815184526020938401939091019060010161486b565b805182525f60208201516148a16020850182614778565b506040820151604084015260608201516148be6060850182614868565b50608082015160a084015260a08201516148db60c08501826146bc565b5060c082015160ff811660e08501525060e0820151610200610100850152614907610200850182614788565b905061010083015161491d6101208601826146bc565b506101208301516149326101408601826146bc565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149648282614788565b9150506101a083015161497b6101c08601826146bc565b506101c08301518015156101e0860152613f7c565b602081525f61469e602083018461488a565b80356146eb8161466f565b5f5f5f5f5f5f5f610120888a0312156149c4575f5ffd5b87356149cf8161466f565b965060208801356149df8161466f565b955060408801356149ef8161466f565b945060608801356149ff8161466f565b93506080880135614a0f8161466f565b925060a08801359150614a258960c08a01614718565b905092959891949750929550565b803560ff811681146146eb575f5ffd5b5f60208284031215614a53575f5ffd5b61469e82614a33565b602081525f61469e6020830184614788565b5f5f60408385031215614a7f575f5ffd5b823591506020830135614a918161466f565b809150509250929050565b5f5f83601f840112614aac575f5ffd5b5081356001600160401b03811115614ac2575f5ffd5b6020830191508360208285010111156141d2575f5ffd5b5f5f5f5f5f60608688031215614aed575f5ffd5b8535945060208601356001600160401b03811115614b09575f5ffd5b614b1588828901614a9c565b90955093505060408601356001600160401b03811115614b33575f5ffd5b614b3f88828901614a9c565b969995985093965092949392505050565b5f5f60408385031215614b61575f5ffd5b50508035926020909101359150565b5f5f5f60408486031215614b82575f5ffd5b614b8b84614a33565b925060208401356001600160401b03811115614ba5575f5ffd5b614bb186828701614a9c565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613a14565b82151581526040810161469e6020830184614756565b5f60208284031215614c05575f5ffd5b81356001600160401b03811115614c1a575f5ffd5b8201610100818503121561469e575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8660e08401826146bc565b50610100830151614c9e61010084018261ffff169052565b50610120830151614cb661012084018261ffff169052565b50610140830151614cce61014084018261ffff169052565b50610160830151614ce661016084018261ffff169052565b50610180830151614cfe61018084018261ffff169052565b506101a0830151614d186101a084018263ffffffff169052565b506101c0830151614d326101c084018263ffffffff169052565b5092915050565b5f5f60408385031215614d4a575f5ffd5b82359150614d5a60208401614a33565b90509250929050565b6007811061476657614766614742565b60208101613a148284614d63565b5f6101e0828403128015614d93575f5ffd5b509092915050565b5f5f60608385031215614dac575f5ffd5b614db5836146dd565b915083606084011115614dc6575f5ffd5b50926020919091019150565b828152604060208201525f614dea604083018461488a565b949350505050565b600181811c90821680614e0657607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614e386020830185614d63565b614dea6040830184614d63565b634e487b7160e01b5f52601160045260245ffd5b80820180821115613a1457613a14614e45565b60408101614e7a8285614d63565b61469e6020830184614d63565b634e487b7160e01b5f52604160045260245ffd5b601f82111561404c57805f5260205f20601f840160051c81016020851015614ec05750805b601f840160051c820191505b81811015614edf575f8155600101614ecc565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b03831115614f1157614f11614e87565b614f2583614f1f8354614df2565b83614e9b565b5f601f841160018114614f51575f8515614f3f5750838201355b614f498682614ee6565b845550614edf565b5f83815260208120601f198716915b82811015614f805786850135825560209485019460019092019101614f60565b5086821015614f9c575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215614fbe575f5ffd5b5051919050565b818382375f9101908152919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f6144e7606083018486614fd4565b8015158114610acc575f5ffd5b5f60208284031215615038575f5ffd5b815161469e8161501b565b602081525f614dea602083018486614fd4565b604081525f615069604083018688614fd4565b828103602084015261507c818587614fd4565b979650505050505050565b60ff84168152604060208201525f6150a3604083018486614fd4565b95945050505050565b5f8151808452602084019350602083015f5b828110156150e55781516001600160a01b03168652602095860195909101906001016150be565b5093949350505050565b848152836020820152608060408201525f61510d60808301856150ac565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f60208284031215615181575f5ffd5b61469e826146dd565b60208101613a148284614778565b8082028115828204841417613a1457613a14614e45565b5f826151c957634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115613a1457613a14614e45565b61ffff81168114610acc575f5ffd5b80356146eb816151e1565b5f6020828403121561520b575f5ffd5b813561469e816151e1565b63ffffffff81168114610acc575f5ffd5b80356146eb81615216565b5f60208284031215615242575f5ffd5b813561469e81615216565b5f8135613a148161466f565b5f8135613a14816151e1565b5f8135613a1481615216565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152e16152c460e0850161524d565b82546001600160a01b0319166001600160a01b0391909116178255565b6153116152f16101008501615259565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6153416153216101208501615259565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6153716153516101408501615259565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6153a16153816101608501615259565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6153d16153b16101808501615259565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b50600881016153fd6153e66101a08501615265565b825463ffffffff191663ffffffff91909116178255565b61404c61540d6101c08501615265565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161548060e084016149a2565b61548d60e08401826146bc565b5061549b61010084016151f0565b61ffff166101008301526154b261012084016151f0565b61ffff166101208301526154c961014084016151f0565b61ffff166101408301526154e061016084016151f0565b61ffff166101608301526154f761018084016151f0565b61ffff1661018083015261550e6101a08401615227565b63ffffffff166101a08301526155276101c08401615227565b63ffffffff81166101c0840152614d32565b6040810181835f5b600281101561557057813561555581615216565b63ffffffff1683526020928301929190910190600101615541565b50505092915050565b5f6001820161558a5761558a614e45565b5060010190565b5f5f8335601e198436030181126155a6575f5ffd5b8301803591506001600160401b038211156155bf575f5ffd5b6020019150368190038213156141d2575f5ffd5b5f602082840312156155e3575f5ffd5b813561469e8161501b565b87815286602082015260a060408201525f61560c60a0830188614788565b828103606084015261561f818789614fd4565b90508281036080840152615634818587614fd4565b9a9950505050505050505050565b81516001600160401b0381111561565b5761565b614e87565b61566f816156698454614df2565b84614e9b565b6020601f82116001811461569c575f831561568a5750848201515b6156948482614ee6565b855550614edf565b5f84815260208120601f198516915b828110156156cb57878501518255602094850194600190920191016156ab565b50848210156156e857868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561573157815163ffffffff1683526020928301929091019060010161570c565b505050949350505050565b6040810161574a8285614d63565b61469e6020830184614756565b604051601f8201601f191681016001600160401b038111828210171561577f5761577f614e87565b604052919050565b5f6001600160401b0382111561579f5761579f614e87565b5060051b60200190565b5f82601f8301126157b8575f5ffd5b81516157cb6157c682615787565b615757565b8082825260208201915060208360051b8601019250858311156157ec575f5ffd5b602085015b838110156158095780518352602092830192016157f1565b5095945050505050565b5f5f60408385031215615824575f5ffd5b82516001600160401b03811115615839575f5ffd5b8301601f81018513615849575f5ffd5b80516158576157c682615787565b8082825260208201915060208360051b850101925087831115615878575f5ffd5b6020840193505b828410156158a35783516158928161466f565b82526020938401939091019061587f565b8095505050505060208301516001600160401b038111156158c2575f5ffd5b6158ce858286016157a9565b9150509250929050565b838152606060208201525f6158f060608301856150ac565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156150e557815186526020958601959091019060010161591a565b6001600160a01b03841681526060602082018190525f9061595b908301856150ac565b82810360408401526144e78185615908565b604081525f61597f60408301856150ac565b82810360208401526150a38185615908565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b50600436106102ce575f3560e01c806390173a4111610182578063cb649617116100e0578063f0691cba1161008f578063f0691cba14610886578063f2fde38b14610899578063f3ceba3a146108ac578063f81b8ef6146108cd578063fad8e111146108e0578063fbdb3237146108f3578063fd2f3d011461091b575f5ffd5b8063cb649617146107ef578063cbd16872146107f8578063cf0f34c41461080b578063cfbdc98d1461081e578063d8afed3e1461084d578063e59e469514610860578063ea71aa5714610873575f5ffd5b80639e57b9341161013c5780639e57b93414610607578063a87f4ab91461061a578063ac3d2f421461076c578063bb2d1b8214610794578063bff232c1146107a7578063c1ab0f1f146107ba578063c4ccafa2146107cd575f5ffd5b806390173a41146105705780639117173c146105855780639231238614610598578063929a8faf146105ab57806399c6679d146105cc5780639c8570c8146105f4575f5ffd5b80635d1684181161022f5780637edcd7ab116101e95780637edcd7ab146104e757806381476ec21461050a578063830d71811461051d57806385814243146105305780638da5cb5b146105435780638dcdd86b1461054b5780638e5ce3ad1461055d575f5ffd5b80635d1684181461047d578063647846a51461049d5780636db5c8fd146104b0578063715018a6146104b95780637c8c3b4d146104c15780637cfa9d74146104d4575f5ffd5b806336c5d38a1161028b57806336c5d38a1461039b5780634017daf0146103ca578063406ed35c146103f75780634147a360146104175780634d600e5d146104445780634e92ec63146104575780634fc772641461046a575f5ffd5b806302a3a9c9146102d25780630ef81b2f146102e757806310bc62811461032557806311bd61d91461034d57806315cce224146103755780631ba7294514610388575b5f5ffd5b6102e56102e0366004614683565b61092e565b005b61030f6102f53660046146a5565b5f908152600960205260409020546001600160a01b031690565b60405161031c91906146c9565b60405180910390f35b61030f6103333660046146a5565b60096020525f90815260409020546001600160a01b031681565b61036061035b3660046146f0565b6109da565b60405163ffffffff909116815260200161031c565b6102e5610383366004614683565b610a16565b6102e5610396366004614728565b610abb565b6103bd6103a93660046146a5565b5f908152600f602052604090205460ff1690565b60405161031c919061476a565b6103dd6103d83660046146a5565b610acf565b60405161031c9e9d9c9b9a999897969594939291906147b6565b61040a6104053660046146a5565b610c7a565b60405161031c9190614990565b6104366104253660046146a5565b600c6020525f908152604090205481565b60405190815260200161031c565b6102e56104523660046149ad565b610ef7565b6102e56104653660046146a5565b611135565b6102e5610478366004614683565b6111c4565b61049061048b366004614a43565b611257565b60405161031c9190614a5c565b60045461030f906001600160a01b031681565b61043660055481565b6102e56112ee565b6102e56104cf366004614a6e565b611301565b6102e56104e23660046146a5565b6113c1565b6104fa6104f5366004614ad9565b6114b4565b604051901515815260200161031c565b6102e5610518366004614b50565b61177a565b6102e561052b366004614b70565b61186e565b60015461030f906001600160a01b031681565b61030f61197a565b5f5461030f906001600160a01b031681565b60035461030f906001600160a01b031681565b6105786119a8565b60405161031c9190614bbe565b6102e56105933660046146a5565b6119ee565b6105786105a63660046146a5565b611b5c565b6105be6105b93660046146a5565b611bb5565b60405161031c929190614bdf565b61030f6105da3660046146a5565b5f908152601060205260409020546001600160a01b031690565b6104fa610602366004614ad9565b611bdc565b610436610615366004614bf5565b611e74565b61075f604080516101e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081019190915250604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a0840152640100000000909104166101c082015290565b60405161031c9190614c2c565b61030f61077a3660046146a5565b5f908152600a60205260409020546001600160a01b031690565b6102e56107a2366004614d39565b61243e565b6102e56107b5366004614683565b6124fa565b6102e56107c8366004614b50565b6125a1565b6104fa6107db366004614683565b60076020525f908152604090205460ff1681565b61043660065481565b6102e5610806366004614a6e565b61265e565b6102e56108193660046146a5565b612718565b61084061082c3660046146a5565b5f908152600d602052604090205460ff1690565b60405161031c9190614d73565b6102e561085b366004614d81565b612755565b6102e561086e366004614683565b6129e2565b6102e5610881366004614d9b565b612a7c565b60025461030f906001600160a01b031681565b6102e56108a7366004614683565b612d29565b6108bf6108ba366004614bf5565b612d63565b60405161031c929190614dd2565b6103bd6108db3660046146a5565b613640565b6102e56108ee366004614683565b6137da565b61030f6109013660046146a5565b600a6020525f90815260409020546001600160a01b031681565b6102e5610929366004614683565b613872565b610936613901565b6001600160a01b0381166109915760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964204533526566756e644d616e6167657220616464726573730060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517f9557d04c1c0b16f93f13b69aed23b3b6ab935bff3c53ac81d17896d3583542ed905f90a250565b6012602052815f5260405f2081600281106109f3575f80fd5b60089182820401919006600402915091509054906101000a900463ffffffff1681565b610a1e613901565b6001600160a01b03811615801590610a4457506004546001600160a01b03828116911614155b8190610a645760405163eddf07f560e01b815260040161098891906146c9565b50600480546001600160a01b0319166001600160a01b0383161790556040517f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f390610ab09083906146c9565b60405180910390a150565b610ac3613901565b610acc81613933565b50565b60086020525f9081526040902080546001820154600283015460058401546006850154600786018054959660ff95861696949593946001600160a01b03841694600160a01b90940490931692909190610b2790614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5390614df2565b8015610b9e5780601f10610b7557610100808354040283529160200191610b9e565b820191905f5260205f20905b815481529060010190602001808311610b8157829003601f168201915b50505060088401546009850154600a860154600b870154600c8801805497986001600160a01b03958616989490951696509194509291610bdd90614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0990614df2565b8015610c545780601f10610c2b57610100808354040283529160200191610c54565b820191905f5260205f20905b815481529060010190602001808311610c3757829003601f168201915b505050600d90930154919250506001600160a01b0381169060ff600160a01b909104168e565b610c826144f1565b5f8281526008602090815260409182902082516101e08101909352805483526001810154909183019060ff166003811115610cbf57610cbf614742565b6003811115610cd057610cd0614742565b8152600282810154602083015260408051808201808352919093019291600385019182845b815481526020019060010190808311610cf55750505091835250506005820154602082015260068201546001600160a01b0381166040830152600160a01b900460ff166060820152600782018054608090920191610d5290614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7e90614df2565b8015610dc95780601f10610da057610100808354040283529160200191610dc9565b820191905f5260205f20905b815481529060010190602001808311610dac57829003601f168201915b505050918352505060088201546001600160a01b0390811660208301526009830154166040820152600a8201546060820152600b8201546080820152600c8201805460a090920191610e1a90614df2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4690614df2565b8015610e915780601f10610e6857610100808354040283529160200191610e91565b820191905f5260205f20905b815481529060010190602001808311610e7457829003601f168201915b5050509183525050600d91909101546001600160a01b038082166020840152600160a01b90910460ff16151560409092019190915260a0820151919250839116610ef15760405163cd6f4a4f60e01b815260040161098891815260200190565b50919050565b5f610f006139f0565b805490915060ff600160401b82041615906001600160401b03165f81158015610f265750825b90505f826001600160401b03166001148015610f415750303b155b905081158015610f4f575080155b15610f6d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610f9757845460ff60401b1916600160401b1785555b610fa033613a1a565b610fa987612718565b610fb28b6137da565b610fbb8a6129e2565b610fc48961092e565b610fcd88610a16565b610fd686613933565b604080516101e081018252620186a080825261c3506020808401829052612710948401859052603260608501819052620493e060808601819052620f424060a0870181905261138860c088018190525f60e089018190526105dc6101008a015261012089018190526109c46101408a018190526101608a018390526101808a01526101a089018190526101c090980197909752601895909555601993909355601a95909555601b94909455601c55601d55601e55601f80546001600160f01b03191669027104e202710000017760a21b179055805467ffffffffffffffff191690556110c061197a565b6001600160a01b03168c6001600160a01b0316146110e1576110e18c612d29565b831561112757845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050505050565b61113d613901565b5f8181526009602052604090205481906001600160a01b0316611176576040516381c4951960e01b815260040161098891815260200190565b505f818152600960205260409081902080546001600160a01b0319169055517f104eb329a192aef26eddea07c2af5ad2587792e62b37ed4045b6ba59bc5540fc90610ab09083815260200190565b6111cc613901565b6001600160a01b0381165f90815260076020526040902054819060ff16611207576040516321ac7c5f60e01b815260040161098891906146c9565b506001600160a01b0381165f9081526007602052604090819020805460ff19169055517f56070b80bd617fcd2f7a284861edb488830a38f9dedcd77b2cb2f4eac17743e790610ab09083906146c9565b600b6020525f90815260409020805461126f90614df2565b80601f016020809104026020016040519081016040528092919081815260200182805461129b90614df2565b80156112e65780601f106112bd576101008083540402835291602001916112e6565b820191905f5260205f20905b8154815290600101906020018083116112c957829003601f168201915b505050505081565b6112f6613901565b6112ff5f613a2b565b565b611309613901565b6001600160a01b0381161580159061133a57505f828152600a60205260409020546001600160a01b03828116911614155b829061135c576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409081902080546001600160a01b0319166001600160a01b0384161790555182907f53661e3e12f23eea1e322a5352171ad3e4407d1394f869f53bb148c27e00908a906113b59084906146c9565b60405180910390a25050565b5f546001600160a01b031633146113eb5760405163b56831db60e01b815260040160405180910390fd5b5f818152600d602052604090205460ff16600181600681111561141057611410614742565b1461143557816001826040516337e1404160e01b815260040161098893929190614e24565b5f828152600d60205260409020805460ff1916600217905560155461145a9042614e59565b5f838152600e602052604080822092909255905183917fc44405af9078047712501f519e1fb900c2896c62b488336f84529c72ae16e6f191a2815f5160206159ab5f395f51905f52600160026040516113b5929190614e6c565b5f5f6114bf87610c7a565b5f888152600d602052604090205490915060ff1660048160068111156114e7576114e7614742565b148860048390919261150f576040516337e1404160e01b815260040161098893929190614e24565b5050505f888152600e60209081526040918290208251606081018452815481526001820154928101929092526002015491810182905290899042811015611572576040516308f3034360e31b815260048101929092526024820152604401610988565b50505f898152600860205260409020600c0161158f888a83614efa565b505f898152600d60205260409020805460ff191660051790556101c0830151156116f957846115d157604051631eae1a4d60e31b815260040160405180910390fd5b5f80546040516304cd0b0d60e11b8152600481018c90526001600160a01b039091169063099a161a90602401602060405180830381865afa158015611618573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061163c9190614fae565b90508361010001516001600160a01b031663de12c6408a8a604051611662929190614fc5565b6040519081900381206001600160e01b031960e084901b16825261168e9185908c908c90600401614ffc565b602060405180830381865afa1580156116a9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116cd9190615028565b94508888866116f157604051632f9f8ab960e01b8152600401610988929190615043565b5050506116fe565b600193505b61170789613a9b565b887f3a140076c461ebc41d74833ae0ee8bbc8079a135a63392098cd381e84350b69b8989898960405161173d9493929190615056565b60405180910390a2885f5160206159ab5f395f51905f5260046005604051611766929190614e6c565b60405180910390a250505095945050505050565b5f546001600160a01b031633146117a45760405163b56831db60e01b815260040160405180910390fd5b5f828152600860209081526040808320600d9092529091205460ff1660028160068111156117d4576117d4614742565b146117f957836002826040516337e1404160e01b815260040161098893929190614e24565b5f848152600d6020526040808220805460ff19166003179055600a84018590555185917f11df18edb9bc9cd90a79068e0e208b630202148643d797d6150e7bacb733e63c91a2835f5160206159ab5f395f51905f5260026003604051611860929190614e6c565b60405180910390a250505050565b611876613901565b806118b25760405162461bcd60e51b815260206004820152600c60248201526b456d70747920706172616d7360a01b6044820152606401610988565b60ff83165f908152600b6020526040902080546118ce90614df2565b15905061191d5760405162461bcd60e51b815260206004820152601b60248201527f506172616d53657420616c7265616479207265676973746572656400000000006044820152606401610988565b60ff83165f908152600b60205260409020611939828483614efa565b507f6e4a4ea7f38fc775e616080b155744337e6216848e886a69c918b4ab84da219583838360405161196d93929190615087565b60405180910390a1505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6119c960405180606001604052805f81526020015f81526020015f81525090565b5060408051606081018252601554815260165460208201526017549181019190915290565b5f818152600d602052604090205460ff166006816006811115611a1357611a13614742565b148290611a3657604051637cb2d48360e11b815260040161098891815260200190565b505f828152600c60205260409020548281611a67576040516345ba89d560e11b815260040161098891815260200190565b505f838152600c60205260408120819055611a8184613f07565b5f858152601160205260409020546002549192506001600160a01b0390811691611aae9183911685613ff4565b60025460405163da19b69760e01b81526001600160a01b039091169063da19b69790611ae49088908790879087906004016150ef565b5f604051808303815f87803b158015611afb575f5ffd5b505af1158015611b0d573d5f5f3e3d5ffd5b50505050847f5297818f48a66292b8b3e2caab83eec531b669bb20807fd38cf006adb2a07317848451604051611b4d929190918252602082015260400190565b60405180910390a25050505050565b611b7d60405180606001604052805f81526020015f81526020015f81525090565b505f908152600e6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b5f818152600d6020526040812054819060ff16611bd28482614051565b9250925050915091565b5f5f611be787610c7a565b5f888152600d602052604090205490915060ff166003816006811115611c0f57611c0f614742565b1488600383909192611c37576040516337e1404160e01b815260040161098893929190614e24565b5050505f888152600e6020908152604091829020825160608101845281548152600182015492810183905260029091015492810192909252899042811015611c9b576040516308f3034360e31b815260048101929092526024820152604401610988565b5050606083015160200151899042811115611cd25760405163017e35e560e71b815260048101929092526024820152604401610988565b5050610160830151899015611cfd57604051637eb9cea960e11b815260040161098891815260200190565b505f8888604051611d0f929190614fc5565b60408051918290039091205f8c815260086020908152838220600b01839055600d905291909120805460ff19166004179055601754909150611d519042614e59565b5f8b8152600e6020526040908190206002019190915560a08501519051632f0e1bbf60e01b81526001600160a01b0390911690632f0e1bbf90611d9e908d9085908c908c90600401614ffc565b6020604051808303815f875af1158015611dba573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dde9190615028565b9450888886611e0257604051632f9f8ab960e01b8152600401610988929190615043565b5050897f7cc27e4a5626cbc4f8ba1a927b0448de55e6a114bc87660331270c5109ade0718a8a604051611e36929190615043565b60405180910390a2895f5160206159ab5f395f51905f5260036004604051611e5f929190614e6c565b60405180910390a25050505095945050505050565b5f80600b81611e8960a0860160808701614a43565b60ff1660ff1681526020019081526020015f208054611ea790614df2565b905011611ec65760405162461bcd60e51b81526004016109889061513a565b5f601281611ed76020860186615171565b6003811115611ee857611ee8614742565b6003811115611ef957611ef9614742565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f20579050505050505090505f81600160028110611f7757611f77615126565b602002015163ffffffff1611835f016020810190611f959190615171565b90611fb45760405163286c068d60e11b8152600401610988919061518a565b506020808201518251604080516101e081018252601854815260195481860152601a5491810191909152601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e0830152600160a01b810461ffff908116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152925463ffffffff8181166101a0860181905264010000000090920481166101c0860152928316939190921691156120df576101a081015163ffffffff16846001602002015163ffffffff161015865f0160208101906120be9190615171565b906120dd5760405163010b971d60e31b8152600401610988919061518a565b505b6101c081015163ffffffff161561212e576101c081015184519063ffffffff908116908216101561212c57604051630a4b6b6360e11b815263ffffffff9091166004820152602401610988565b505b6040860135602087013581101561215b5760405163174b5a0760e21b815260040161098891815260200190565b506101808101516017545f91612710916121799161ffff1690615198565b61218391906151af565b61271061ffff1683610160015161ffff166015600101546121a49190615198565b6121ae91906151af565b61271061ffff1684610140015161ffff1660155f01546121ce9190615198565b6121d891906151af565b5f5460408051634f87c3a560e11b8152815160208e81013594938f0135936001600160a01b031692639f0f874a92600480830193928290030181865afa158015612224573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122489190614fae565b6122529190614e59565b61225c91906151ce565b6122669190614e59565b6122709190614e59565b61227a9190614e59565b90505f6122886001866151ce565b612293906004615198565b61229e90600e614e59565b90505f85845f01516122b09190615198565b9050818685602001516122c39190615198565b6122cd9190615198565b6122d79082614e59565b9050600186111561231f5760026122ef6001886151ce565b6122f99088615198565b85604001516123089190615198565b61231291906151af565b61231c9082614e59565b90505b81868560c001516123309190615198565b61233a9190615198565b6123449082614e59565b9050828685606001516123579190615198565b6123619190615198565b61236b9082614e59565b905084846080015161237d9190615198565b6123879082614e59565b905060018511156123cf57600261239f6001876151ce565b6123a99087615198565b85604001516123b89190615198565b6123c291906151af565b6123cc9082614e59565b90505b60a08401516123de9082614e59565b610100850151909150612710906123f99061ffff1682614e59565b6124039083615198565b61240d91906151af565b9750878061243157604051638c4fcd9360e01b815260040161098891815260200190565b5050505050505050919050565b5f546001600160a01b031633148061246057506003546001600160a01b031633145b61247d57604051639e75a8b560e01b815260040160405180910390fd5b5f8160ff161180156124935750600d60ff821611155b6124d85760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b2103330b4b63ab932903932b0b9b7b760511b6044820152606401610988565b6124f6828260ff16600d8111156124f1576124f1614742565b6141d9565b5050565b612502613901565b6001600160a01b0381166125585760405162461bcd60e51b815260206004820152601f60248201527f496e76616c696420536c617368696e674d616e616765722061646472657373006044820152606401610988565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b6003546001600160a01b031633146125cc576040516357d6948d60e11b815260040160405180910390fd5b60025460405163c1ab0f1f60e01b815260048101849052602481018390526001600160a01b039091169063c1ab0f1f906044015f604051808303815f87803b158015612616575f5ffd5b505af1158015612628573d5f5f3e3d5ffd5b50505050817f4f41a3b0a032ebcae925f2ace77d507435840ca4b2dbaffdd7723fa8d72ee542826040516113b591815260200190565b612666613901565b6001600160a01b0381161580159061269757505f828152600960205260409020546001600160a01b03828116911614155b82906126b9576040516381c4951960e01b815260040161098891815260200190565b505f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03851617905590518381527ff4041a3f914dac3bc9bf5f003ba41f28dbb84abe42f4e07c76266f5c8ceecb69910160405180910390a15050565b612720613901565b60058190556040518181527fba0716ba1ee2ea8ecc4c64119b4537cdb42a99d82acf92af5b87607b8b52355290602001610ab0565b61275d613901565b612710612772610120830161010084016151fb565b61ffff16111561278a610120830161010084016151fb565b906127af576040516301027fc160e21b815261ffff9091166004820152602401610988565b506127106127c5610140830161012084016151fb565b61ffff1611156127dd610140830161012084016151fb565b90612802576040516301027fc160e21b815261ffff9091166004820152602401610988565b50612710612818610160830161014084016151fb565b61ffff161115612830610160830161014084016151fb565b9061285557604051633239953960e01b815261ffff9091166004820152602401610988565b5061271061286b610180830161016084016151fb565b61ffff161115612883610180830161016084016151fb565b906128a857604051633239953960e01b815261ffff9091166004820152602401610988565b506127106128be6101a0830161018084016151fb565b61ffff1611156128d66101a0830161018084016151fb565b906128fb57604051633239953960e01b815261ffff9091166004820152602401610988565b5061290e610140820161012083016151fb565b61ffff16158061293757505f61292b610100830160e08401614683565b6001600160a01b031614155b6129545760405163015f92ff60e51b815260040160405180910390fd5b6129666101e082016101c08301615232565b63ffffffff1661297e6101c083016101a08401615232565b63ffffffff1610156129a3576040516392f55c6560e01b815260040160405180910390fd5b8060186129b08282615271565b9050507fbf3951313e980027eb48ce363fdb707286195ec6a0f802ac153927cf929c3fc681604051610ab0919061542f565b6129ea613901565b6001600160a01b03811615801590612a1057506001546001600160a01b03828116911614155b8190612a30576040516320252f0b60e01b815260040161098891906146c9565b50600180546001600160a01b0319166001600160a01b0383161790556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a790610ab09083906146c9565b612a84613901565b612a916020820182615232565b63ffffffff16612aa76040830160208401615232565b63ffffffff1610158015612acc57505f612ac46020830183615232565b63ffffffff16115b612ae957604051634564ab9b60e01b815260040160405180910390fd5b604080516101e0810182526018548152601954602080830191909152601a5492820192909252601b546060820152601c546080820152601d5460a0820152601e5460c0820152601f546001600160a01b03811660e083015261ffff600160a01b82048116610100840152600160b01b82048116610120840152600160c01b82048116610140840152600160d01b82048116610160840152600160e01b90910416610180820152905463ffffffff8082166101a08401819052640100000000909204166101c083015215612c22576101a081015163ffffffff16612bd26040840160208501615232565b63ffffffff161015612bea6040840160208501615232565b826101a001519091612c1f57604051633ccc4c2160e21b815263ffffffff928316600482015291166024820152604401610988565b50505b6101c081015163ffffffff1615612c99576101c081015163ffffffff16612c4c6020840184615232565b63ffffffff161015612c616020840184615232565b826101c001519091612c965760405163156c4e5b60e11b815263ffffffff928316600482015291166024820152604401610988565b50505b8160125f856003811115612caf57612caf614742565b6003811115612cc057612cc0614742565b815260208101919091526040015f20612cda91600261456e565b50826003811115612ced57612ced614742565b7f8b56fae526eee054f0849759a99fc7d4ff3823824ebf097a56f7d78adb6b34fa83604051612d1c9190615539565b60405180910390a2505050565b612d31613901565b6001600160a01b038116612d5a575f604051631e4fbdf760e01b815260040161098891906146c9565b610acc81613a2b565b5f612d6c6144f1565b5f601281612d7d6020870187615171565b6003811115612d8e57612d8e614742565b6003811115612d9f57612d9f614742565b8152602081019190915260409081015f20815180830190925260028282826020028201915f905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612dc6579050505050505090505f81600160028110612e1d57612e1d615126565b602002015163ffffffff1611845f016020810190612e3b9190615171565b90612e5a5760405163286c068d60e11b8152600401610988919061518a565b50602084013542811015612e8457604051630b99e87960e01b815260040161098891815260200190565b5060408401356020850135811015612eb25760405163174b5a0760e21b815260040161098891815260200190565b506017546016545f9190612eca4260408901356151ce565b612ed49190614e59565b612ede9190614e59565b905060055481108190612f07576040516313b783af60e21b815260040161098891815260200190565b5060075f612f1b6080880160608901614683565b6001600160a01b0316815260208101919091526040015f205460ff16612f476080870160608801614683565b90612f665760405163295a6a6f60e11b815260040161098891906146c9565b505f612f7186611e74565b60068054965090915085905f612f8683615579565b9091555050604080514460208201529081018690525f9060600160408051601f1981840301815291815281516020928301205f898152600c84528281208690556004546011855283822080546001600160a01b03199081166001600160a01b0393841617909155601f805460138852868520805461ffff191661ffff600160b01b909304929092169190911790555460148752858420805483169190931617909155600d8552838220805460ff1916600117905560109094528290208054339416939093179092556016549192506130619190890135614e59565b5f878152600e602090815260409091206001019190915581865261308790880188615171565b8560200190600381111561309d5761309d614742565b908160038111156130b0576130b0614742565b905250436040808701919091528051808201825290602089019060029083908390808284375f9201919091525050506060808701919091526130f89060808901908901614683565b6001600160a01b031660a08087019190915261311990880160808901614a43565b60ff1660c08087019190915261313190880188615591565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060e08087019190915261317e9061010089019089016155d3565b15156101c08601525f610140860181905261016086018190526040805160208101909152818152610180870152336101a0870152600b816131c560a08b0160808c01614a43565b60ff1660ff1681526020019081526020015f2080546131e390614df2565b80601f016020809104026020016040519081016040528092919081815260200182805461320f90614df2565b801561325a5780601f106132315761010080835404028352916020019161325a565b820191905f5260205f20905b81548152906001019060200180831161323d57829003601f168201915b505050505090505f8151116132815760405162461bcd60e51b81526004016109889061513a565b5f61329260808a0160608b01614683565b6001600160a01b031663fefd9a8b8985856132b060a08f018f615591565b8f8060c001906132c09190615591565b6040518863ffffffff1660e01b81526004016132e297969594939291906155ee565b6020604051808303815f875af11580156132fe573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133229190614fae565b5f818152600960205260409020549091506001600160a01b0316818161335e576040516381c4951960e01b815260040161098891815260200190565b505f828152600a60205260409020546001600160a01b03168281613398576040516381c4951960e01b815260040161098891815260200190565b50608089018390526001600160a01b038083166101008b015281166101208a01525f8a81526008602090815260409091208a518155908a0151600180830180548d94939260ff1991909116908360038111156133f6576133f6614742565b02179055506040820151816002015560608201518160030190600261341c92919061460f565b506080820151600582015560a082015160068201805460c085015160ff16600160a01b026001600160a81b03199091166001600160a01b039093169290921791909117905560e082015160078201906134759082615642565b506101008201516008820180546001600160a01b039283166001600160a01b031991821617909155610120840151600984018054919093169116179055610140820151600a820155610160820151600b820155610180820151600c8201906134dd9082615642565b506101a0820151600d90910180546101c0909301511515600160a01b026001600160a81b03199093166001600160a01b0392831617929092179091556004546135299116333089614334565b5f5460405163291a691b60e01b81526001600160a01b039091169063291a691b9061355c908d9089908d906004016156f7565b6020604051808303815f875af1158015613578573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061359c9190615028565b6135b957604051630d8dbe2560e01b815260040160405180910390fd5b6135c960808c0160608d01614683565b6001600160a01b03167f5090c9764b5cd13df7afc0013f733dfbe6eaf1b6ddc22a5e291fa387efd4c15e8b8b604051613603929190614dd2565b60405180910390a2895f5160206159ab5f395f51905f525f600160405161362b929190614e6c565b60405180910390a25050505050505050915091565b5f818152600d602052604081205460ff168181600681111561366457613664614742565b0361368957826001826040516337e1404160e01b815260040161098893929190614e24565b600581600681111561369d5761369d614742565b036136be5760405163462c7bed60e01b815260048101849052602401610988565b60068160068111156136d2576136d2614742565b036136f357604051633de16e3560e11b815260048101849052602401610988565b5f6136fe8483614051565b935090508061372357604051639f65d93560e01b815260048101859052602401610988565b5f848152600d6020526040902080546006919060ff191660018302179055505f848152600f60205260409020805484919060ff1916600183600d81111561376c5761376c614742565b0217905550835f5160206159ab5f395f51905f52836006604051613791929190614e6c565b60405180910390a2837fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb83856040516137cb92919061573c565b60405180910390a25050919050565b6137e2613901565b6001600160a01b0381161580159061380757505f546001600160a01b03828116911614155b8190613827576040516375ac4eb760e11b815260040161098891906146c9565b505f80546001600160a01b0319166001600160a01b0383161790556040517f80052b810d39120cf6c976cca504a21703f585521dc7a41c6d241090e6c579b690610ab09083906146c9565b6001600160a01b0381165f90815260076020526040902054819060ff16156138ae5760405163b29d459560e01b815260040161098891906146c9565b506001600160a01b0381165f9081526007602052604090819020805460ff19166001179055517fb8d368517268f297fff00825d67d098763117d061360d31027be5b2e1a59d46790610ab09083906146c9565b3361390a61197a565b6001600160a01b0316146112ff573360405163118cdaa760e01b815260040161098891906146c9565b80356139525760405163055f269d60e01b815260040160405180910390fd5b5f8160200135116139765760405163055f269d60e01b815260040160405180910390fd5b5f81604001351161399a5760405163055f269d60e01b815260040160405180910390fd5b80356015819055602080830135601681905560408085013560178190558151948552928401919091528201527f7e86ba16b805e2835af5c5b7aa5a942ced8bcc1fb95a05fbe42dae3862350a1690606001610ab0565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b613a22614373565b610acc81614398565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f805460405162beb08960e51b8152600481018490526001600160a01b03909116906317d61120906024015f60405180830381865afa158015613ae0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052613b079190810190615813565b5080515f848152600c60209081526040808320805490849055601190925282205493945091926001600160a01b031690829003613ba6576002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613b72908890889086906004016158d8565b5f604051808303815f87803b158015613b89575f5ffd5b505af1158015613b9b573d5f5f3e3d5ffd5b505050505050505050565b825f03613c47575f858152601060205260409020546001600160a01b03168015613bde57613bde6001600160a01b0383168285613ff4565b6002546040516341489f1560e01b81526001600160a01b03909116906341489f1590613c12908990899087906004016158d8565b5f604051808303815f87803b158015613c29575f5ffd5b505af1158015613c3b573d5f5f3e3d5ffd5b50505050505050505050565b5f85815260136020908152604080832054601490925282205461ffff909116906001600160a01b03168115801590613c8757506001600160a01b03811615155b15613cc357612710613c9d61ffff841687615198565b613ca791906151af565b92508215613cc357613cc36001600160a01b0385168285613ff4565b5f613cce84876151ce565b90505f876001600160401b03811115613ce957613ce9614e87565b604051908082528060200260200182016040528015613d12578160200160208202803683370190505b5090505f613d2089846151af565b90505f805b8a811015613d5f5782848281518110613d4057613d40615126565b6020908102919091010152613d558383614e59565b9150600101613d25565b505f613d6b82866151ce565b90508015613da8578084613d8060018e6151ce565b81518110613d9057613d90615126565b60200260200101818151613da49190614e59565b9052505b600154613dc2906001600160a01b038b81169116876143a0565b60015f9054906101000a90046001600160a01b03166001600160a01b031663dd8c818e8a8e876040518463ffffffff1660e01b8152600401613e0693929190615938565b5f604051808303815f87803b158015613e1d575f5ffd5b505af1158015613e2f573d5f5f3e3d5ffd5b5050600154613e4d92506001600160a01b038c81169250165f6143a0565b8c7fac9fe8ad7f55eac03284399116ecafc104f10459773f4cdf47063c46e5be335a8d86604051613e7f92919061596d565b60405180910390a260025f9054906101000a90046001600160a01b03166001600160a01b03166341489f158e8e8c6040518463ffffffff1660e01b8152600401613ecb939291906158d8565b5f604051808303815f87803b158015613ee2575f5ffd5b505af1158015613ef4573d5f5f3e3d5ffd5b5050505050505050505050505050505050565b5f818152600f602052604090205460609060ff16600181600d811115613f2f57613f2f614742565b1480613f4c5750600281600d811115613f4a57613f4a614742565b145b15613f84575f5b604051908082528060200260200182016040528015613f7c578160200160208202803683370190505b509392505050565b5f5460405162beb08960e51b8152600481018590526001600160a01b03909116906317d61120906024015f60405180830381865afa925050508015613fea57506040513d5f823e601f3d908101601f19168201604052613fe79190810190615813565b60015b613f7c575f613f53565b61404c83846001600160a01b031663a9059cbb858560405160240161401a929190615991565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061442c565b505050565b5f828152600e60209081526040808320815160608101835281548152600182015493810193909352600201548282015282549051632800d82960e01b81526004810186905283929183916001600160a01b0390911690632800d82990602401602060405180830381865afa1580156140cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140ef9190614fae565b9050600185600681111561410557614105614742565b14801561411157508042115b15614124576001809350935050506141d2565b600285600681111561413857614138614742565b1480156141455750815142115b1561415957600160039350935050506141d2565b600385600681111561416d5761416d614742565b14801561417d5750816020015142115b1561419157600160069350935050506141d2565b60048560068111156141a5576141a5614742565b1480156141b55750816040015142115b156141c9576001600a9350935050506141d2565b5f5f9350935050505b9250929050565b5f828152600d602052604081205460ff16908160068111156141fd576141fd614742565b0361422257826001826040516337e1404160e01b815260040161098893929190614e24565b600581600681111561423657614236614742565b036142575760405163462c7bed60e01b815260048101849052602401610988565b600681600681111561426b5761426b614742565b0361428c57604051633de16e3560e11b815260048101849052602401610988565b5f838152600d6020526040902080546006919060ff191660018302179055505f838152600f60205260409020805483919060ff1916600183600d8111156142d5576142d5614742565b0217905550825f5160206159ab5f395f51905f528260066040516142fa929190614e6c565b60405180910390a2827fe20209be7caae6e76291267cfa711353981274bf127e94f16eb9ec44b68582bb8284604051612d1c92919061573c565b6040516001600160a01b03848116602483015283811660448301526064820183905261436d9186918216906323b872dd9060840161401a565b50505050565b61437b61448f565b6112ff57604051631afcd79f60e31b815260040160405180910390fd5b612d31614373565b5f836001600160a01b031663095ea7b384846040516024016143c3929190615991565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505090506143fc84826144a8565b61436d5761442684856001600160a01b031663095ea7b3865f60405160240161401a929190615991565b61436d84825b5f5f60205f8451602086015f885af18061444b576040513d5f823e3d81fd5b50505f513d9150811561446257806001141561446f565b6001600160a01b0384163b155b1561436d5783604051635274afe760e01b815260040161098891906146c9565b5f6144986139f0565b54600160401b900460ff16919050565b5f5f5f5f60205f8651602088015f8a5af192503d91505f5190508280156144e7575081156144d957806001146144e7565b5f866001600160a01b03163b115b9695505050505050565b604080516101e081019091525f808252602082019081526020015f815260200161451961463d565b81525f602082018190526040820181905260608083018290526080830181905260a0830182905260c0830182905260e08301829052610100830182905261012083015261014082018190526101609091015290565b6001830191839082156145ff579160200282015f5b838211156145cd57833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614583565b80156145fd5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026145cd565b505b5061460b92915061465b565b5090565b82600281019282156145ff579160200282015b828111156145ff578251825591602001919060010190614622565b60405180604001604052806002906020820280368337509192915050565b5b8082111561460b575f815560010161465c565b6001600160a01b0381168114610acc575f5ffd5b5f60208284031215614693575f5ffd5b813561469e8161466f565b9392505050565b5f602082840312156146b5575f5ffd5b5035919050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b8035600481106146eb575f5ffd5b919050565b5f5f60408385031215614701575f5ffd5b61470a836146dd565b946020939093013593505050565b5f60608284031215610ef1575f5ffd5b5f60608284031215614738575f5ffd5b61469e8383614718565b634e487b7160e01b5f52602160045260245ffd5b600e811061476657614766614742565b9052565b60208101613a148284614756565b6004811061476657614766614742565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8e81526147c6602082018f614778565b8c60408201528b60608201526147df608082018c6146bc565b60ff8a1660a08201526101c060c08201525f6147ff6101c083018b614788565b61480c60e084018b6146bc565b61481a61010084018a6146bc565b876101208401528661014084015282810361016084015261483b8187614788565b91505061484c6101808301856146bc565b8215156101a08301529f9e505050505050505050505050505050565b805f5b600281101561436d57815184526020938401939091019060010161486b565b805182525f60208201516148a16020850182614778565b506040820151604084015260608201516148be6060850182614868565b50608082015160a084015260a08201516148db60c08501826146bc565b5060c082015160ff811660e08501525060e0820151610200610100850152614907610200850182614788565b905061010083015161491d6101208601826146bc565b506101208301516149326101408601826146bc565b506101408301516101608501526101608301516101808501526101808301518482036101a08601526149648282614788565b9150506101a083015161497b6101c08601826146bc565b506101c08301518015156101e0860152613f7c565b602081525f61469e602083018461488a565b80356146eb8161466f565b5f5f5f5f5f5f5f610120888a0312156149c4575f5ffd5b87356149cf8161466f565b965060208801356149df8161466f565b955060408801356149ef8161466f565b945060608801356149ff8161466f565b93506080880135614a0f8161466f565b925060a08801359150614a258960c08a01614718565b905092959891949750929550565b803560ff811681146146eb575f5ffd5b5f60208284031215614a53575f5ffd5b61469e82614a33565b602081525f61469e6020830184614788565b5f5f60408385031215614a7f575f5ffd5b823591506020830135614a918161466f565b809150509250929050565b5f5f83601f840112614aac575f5ffd5b5081356001600160401b03811115614ac2575f5ffd5b6020830191508360208285010111156141d2575f5ffd5b5f5f5f5f5f60608688031215614aed575f5ffd5b8535945060208601356001600160401b03811115614b09575f5ffd5b614b1588828901614a9c565b90955093505060408601356001600160401b03811115614b33575f5ffd5b614b3f88828901614a9c565b969995985093965092949392505050565b5f5f60408385031215614b61575f5ffd5b50508035926020909101359150565b5f5f5f60408486031215614b82575f5ffd5b614b8b84614a33565b925060208401356001600160401b03811115614ba5575f5ffd5b614bb186828701614a9c565b9497909650939450505050565b81518152602080830151908201526040808301519082015260608101613a14565b82151581526040810161469e6020830184614756565b5f60208284031215614c05575f5ffd5b81356001600160401b03811115614c1a575f5ffd5b8201610100818503121561469e575f5ffd5b5f6101e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e0830151614c8660e08401826146bc565b50610100830151614c9e61010084018261ffff169052565b50610120830151614cb661012084018261ffff169052565b50610140830151614cce61014084018261ffff169052565b50610160830151614ce661016084018261ffff169052565b50610180830151614cfe61018084018261ffff169052565b506101a0830151614d186101a084018263ffffffff169052565b506101c0830151614d326101c084018263ffffffff169052565b5092915050565b5f5f60408385031215614d4a575f5ffd5b82359150614d5a60208401614a33565b90509250929050565b6007811061476657614766614742565b60208101613a148284614d63565b5f6101e0828403128015614d93575f5ffd5b509092915050565b5f5f60608385031215614dac575f5ffd5b614db5836146dd565b915083606084011115614dc6575f5ffd5b50926020919091019150565b828152604060208201525f614dea604083018461488a565b949350505050565b600181811c90821680614e0657607f821691505b602082108103610ef157634e487b7160e01b5f52602260045260245ffd5b83815260608101614e386020830185614d63565b614dea6040830184614d63565b634e487b7160e01b5f52601160045260245ffd5b80820180821115613a1457613a14614e45565b60408101614e7a8285614d63565b61469e6020830184614d63565b634e487b7160e01b5f52604160045260245ffd5b601f82111561404c57805f5260205f20601f840160051c81016020851015614ec05750805b601f840160051c820191505b81811015614edf575f8155600101614ecc565b5050505050565b5f19600383901b1c191660019190911b1790565b6001600160401b03831115614f1157614f11614e87565b614f2583614f1f8354614df2565b83614e9b565b5f601f841160018114614f51575f8515614f3f5750838201355b614f498682614ee6565b845550614edf565b5f83815260208120601f198716915b82811015614f805786850135825560209485019460019092019101614f60565b5086821015614f9c575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215614fbe575f5ffd5b5051919050565b818382375f9101908152919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f6144e7606083018486614fd4565b8015158114610acc575f5ffd5b5f60208284031215615038575f5ffd5b815161469e8161501b565b602081525f614dea602083018486614fd4565b604081525f615069604083018688614fd4565b828103602084015261507c818587614fd4565b979650505050505050565b60ff84168152604060208201525f6150a3604083018486614fd4565b95945050505050565b5f8151808452602084019350602083015f5b828110156150e55781516001600160a01b03168652602095860195909101906001016150be565b5093949350505050565b848152836020820152608060408201525f61510d60808301856150ac565b905060018060a01b038316606083015295945050505050565b634e487b7160e01b5f52603260045260245ffd5b6020808252601c908201527f42465620706172616d20736574206e6f74207265676973746572656400000000604082015260600190565b5f60208284031215615181575f5ffd5b61469e826146dd565b60208101613a148284614778565b8082028115828204841417613a1457613a14614e45565b5f826151c957634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115613a1457613a14614e45565b61ffff81168114610acc575f5ffd5b80356146eb816151e1565b5f6020828403121561520b575f5ffd5b813561469e816151e1565b63ffffffff81168114610acc575f5ffd5b80356146eb81615216565b5f60208284031215615242575f5ffd5b813561469e81615216565b5f8135613a148161466f565b5f8135613a14816151e1565b5f8135613a1481615216565b813581556020820135600182015560408201356002820155606082013560038201556080820135600482015560a0820135600582015560c08201356006820155600781016152e16152c460e0850161524d565b82546001600160a01b0319166001600160a01b0391909116178255565b6153116152f16101008501615259565b82805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b6153416153216101208501615259565b82805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b6153716153516101408501615259565b82805461ffff60c01b191660c09290921b61ffff60c01b16919091179055565b6153a16153816101608501615259565b82805461ffff60d01b191660d09290921b61ffff60d01b16919091179055565b6153d16153b16101808501615259565b82805461ffff60e01b191660e09290921b61ffff60e01b16919091179055565b50600881016153fd6153e66101a08501615265565b825463ffffffff191663ffffffff91909116178255565b61404c61540d6101c08501615265565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b813581526020808301359082015260408083013590820152606080830135908201526080808301359082015260a0808301359082015260c080830135908201526101e0810161548060e084016149a2565b61548d60e08401826146bc565b5061549b61010084016151f0565b61ffff166101008301526154b261012084016151f0565b61ffff166101208301526154c961014084016151f0565b61ffff166101408301526154e061016084016151f0565b61ffff166101608301526154f761018084016151f0565b61ffff1661018083015261550e6101a08401615227565b63ffffffff166101a08301526155276101c08401615227565b63ffffffff81166101c0840152614d32565b6040810181835f5b600281101561557057813561555581615216565b63ffffffff1683526020928301929190910190600101615541565b50505092915050565b5f6001820161558a5761558a614e45565b5060010190565b5f5f8335601e198436030181126155a6575f5ffd5b8301803591506001600160401b038211156155bf575f5ffd5b6020019150368190038213156141d2575f5ffd5b5f602082840312156155e3575f5ffd5b813561469e8161501b565b87815286602082015260a060408201525f61560c60a0830188614788565b828103606084015261561f818789614fd4565b90508281036080840152615634818587614fd4565b9a9950505050505050505050565b81516001600160401b0381111561565b5761565b614e87565b61566f816156698454614df2565b84614e9b565b6020601f82116001811461569c575f831561568a5750848201515b6156948482614ee6565b855550614edf565b5f84815260208120601f198516915b828110156156cb57878501518255602094850194600190920191016156ab565b50848210156156e857868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b838152602081018390526080810160408201835f5b600281101561573157815163ffffffff1683526020928301929091019060010161570c565b505050949350505050565b6040810161574a8285614d63565b61469e6020830184614756565b604051601f8201601f191681016001600160401b038111828210171561577f5761577f614e87565b604052919050565b5f6001600160401b0382111561579f5761579f614e87565b5060051b60200190565b5f82601f8301126157b8575f5ffd5b81516157cb6157c682615787565b615757565b8082825260208201915060208360051b8601019250858311156157ec575f5ffd5b602085015b838110156158095780518352602092830192016157f1565b5095945050505050565b5f5f60408385031215615824575f5ffd5b82516001600160401b03811115615839575f5ffd5b8301601f81018513615849575f5ffd5b80516158576157c682615787565b8082825260208201915060208360051b850101925087831115615878575f5ffd5b6020840193505b828410156158a35783516158928161466f565b82526020938401939091019061587f565b8095505050505060208301516001600160401b038111156158c2575f5ffd5b6158ce858286016157a9565b9150509250929050565b838152606060208201525f6158f060608301856150ac565b905060018060a01b0383166040830152949350505050565b5f8151808452602084019350602083015f5b828110156150e557815186526020958601959091019060010161591a565b6001600160a01b03841681526060602082018190525f9061595b908301856150ac565b82810360408401526144e78185615908565b604081525f61597f60408301856150ac565b82810360208401526150a38185615908565b6001600160a01b0392909216825260208201526040019056fe1b418a230a21d37a078bf8f16decbde8ccceacd77159371f62f0d4ea00d19967a164736f6c634300081c000a", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/Enclave.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-0431dc09dff33382cec136e860cfd8d32d55db8a" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 6946870540..8b843cf8d1 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -1005,5 +1005,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-e33d1cfedc69d8ad74eec5a84c8ef358a020ec1a" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index c2def89b18..59d3b845dd 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -616,6 +616,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "getCommitteeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "committeeHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -781,11 +800,6 @@ "name": "e3Id", "type": "uint256" }, - { - "internalType": "address[]", - "name": "nodes", - "type": "address[]" - }, { "internalType": "bytes", "name": "publicKey", @@ -971,5 +985,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-e33d1cfedc69d8ad74eec5a84c8ef358a020ec1a" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json index 83e49e9f6e..28718e0650 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json @@ -2097,5 +2097,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IEnclave.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-e33d1cfedc69d8ad74eec5a84c8ef358a020ec1a" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 9e5c214eb8..bfc1587e19 100644 --- a/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/enclave-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -1006,5 +1006,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-e33d1cfedc69d8ad74eec5a84c8ef358a020ec1a" } \ No newline at end of file diff --git a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json index 208465867b..50424a3117 100644 --- a/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +++ b/packages/enclave-contracts/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json @@ -806,6 +806,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "e3Id", + "type": "uint256" + } + ], + "name": "getCommitteeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "committeeHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1034,11 +1053,6 @@ "name": "e3Id", "type": "uint256" }, - { - "internalType": "address[]", - "name": "nodes", - "type": "address[]" - }, { "internalType": "bytes", "name": "publicKey", @@ -1283,30 +1297,30 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613db5806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639a7a2ffc11610135578063dbb06c93116100b4578063f165053611610079578063f165053614610578578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063dbb06c9314610525578063e59e469514610537578063e6745e131461054a578063e82f3b701461055d578063ebf0c71714610570575f5ffd5b8063c2b40ae4116100fa578063c2b40ae4146104b0578063c3a0ec30146104cf578063ca2869a0146104e0578063cd6dc687146104ff578063da881e5a14610512575f5ffd5b80639a7a2ffc146104255780639f0f874a14610461578063a01649301461046a578063a8a4d69b1461048a578063bff232c11461049d575f5ffd5b806370e36bbe116101c15780638cb89ecb116101865780638cb89ecb146103c25780638d1ddfb1146103e15780638da5cb5b146103f75780638e5ce3ad146103ff5780639015d37114610412575f5ffd5b806370e36bbe14610347578063715018a61461035a5780637c92f52414610362578063858142431461038f5780638a78bb15146103af575f5ffd5b8063291a691b11610207578063291a691b146102c95780632e7b716d146102ec5780634d6861a6146102ff57806350e6d94c146103125780635d50477614610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780631cc321b5146102955780632800d829146102a8575b5f5ffd5b610256610251366004613303565b61065a565b005b61025661026636600461331e565b6107a6565b61027e61027936600461331e565b6107e9565b60405161028c9291906133a8565b60405180910390f35b6102566102a3366004613419565b610993565b6102bb6102b636600461331e565b610cb7565b60405190815260200161028c565b6102dc6102d73660046134f8565b610d03565b604051901515815260200161028c565b6102dc6102fa366004613303565b610edd565b6102dc61030d36600461331e565b610f90565b6102dc610320366004613303565b60066020525f908152604090205460ff1681565b6102dc610342366004613531565b610fcf565b610256610355366004613303565b611013565b610256611089565b61037561037036600461355f565b61109c565b6040805192835263ffffffff90911660208301520161028c565b6001546103a2906001600160a01b031681565b60405161028c9190613594565b6102566103bd366004613303565b611243565b6102bb6103d036600461331e565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102bb565b6103a2611381565b600b546103a2906001600160a01b031681565b6102dc610420366004613303565b6113af565b61044b610433366004613303565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102bb60035481565b61047d61047836600461331e565b6113cc565b60405161028c91906135a8565b6102dc610498366004613531565b611462565b6102566104ab366004613303565b6114a6565b6102bb6104be36600461331e565b60086020525f908152604090205481565b6001546001600160a01b03166103a2565b6102bb6104ee36600461331e565b5f9081526008602052604090205490565b61025661050d3660046135ba565b61151e565b6102dc61052036600461331e565b61167b565b5f546103a2906001600160a01b031681565b610256610545366004613303565b611955565b6102566105583660046135e4565b6119cd565b6102bb61056b36600461331e565b611b90565b6102bb611bc1565b610580601481565b60405160ff909116815260200161028c565b6102566105a0366004613303565b611bd3565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed36600461331e565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102bb60025481565b610662611381565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b1816113af565b81906106da576040516381e5828960e01b81526004016106d19190613594565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611c0d565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161073583613618565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611eaf565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b038111156108205761082061362d565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b038111156108645761086461362d565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b1613641565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613655565b03610980578088848151811061090f5761090f613641565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f205487848151811061096757610967613641565b60209081029190910101528261097c81613669565b9350505b50600101610893565b5050505050915091565b5f888152600a602052604090206002815460ff1660038111156109b8576109b8613655565b146109d657604051634f4b461f60e11b815260040160405180910390fd5b6004810154156109f95760405163632a22bb60e01b815260040160405180910390fd5b60068101548714610a425760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b83610a875760405162461bcd60e51b81526020600482015260156024820152741c1ad0dbdb5b5a5d1b595b9d081c995c5d5a5c9959605a1b60448201526064016106d1565b5f805460405163101bb4d760e21b8152600481018c90526001600160a01b039091169063406ed35c906024015f60405180830381865afa158015610acd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610af491908101906137d7565b9050806101c0015115610bf35782610b3f5760405162461bcd60e51b815260206004820152600e60248201526d1c1c9bdbd9881c995c5d5a5c995960921b60448201526064016106d1565b8061012001516001600160a01b031663258ae5828686866040518463ffffffff1660e01b8152600401610b749392919061395d565b602060405180830381865afa158015610b8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb39190613976565b610bf35760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2102225a390383937b7b360791b60448201526064016106d1565b60048281018690555f8b815260096020526040808220889055905490516340a3b76160e11b81529182018c9052602482018790526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015610c51575f5ffd5b505af1158015610c63573d5f5f3e3d5ffd5b50505050897fbf0636a312095f6c09c909823813b50e392323588d2d83432e7512c64041e67f8a8a8a8a8a8a8a604051610ca3979695949392919061398f565b60405180910390a250505050505050505050565b5f818152600a6020526040812081815460ff166003811115610cdb57610cdb613655565b03610cf957604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610d2e5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610d5257610d52613655565b14610d70576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610db7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddb9190613a0f565b905080610dee6040860160208701613a39565b63ffffffff161115610e066040860160208701613a39565b829091610e34576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610e5b9042613a52565b6003830155610e6f6005830185600261323a565b50610e78611bc1565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ec9928a928a9291613a65565b60405180910390a250600195945050505050565b5f610ee7826113af565b610ef257505f919050565b6001546001600160a01b0316610f1b576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610f4b908590600401613594565b602060405180830381865afa158015610f66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8a9190613976565b92915050565b5f818152600a602052604081206001815460ff166003811115610fb557610fb5613655565b14610fc257505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561100b5761100b613655565b149392505050565b61101b611eaf565b6001600160a01b0381166110425760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b611091611eaf565b61109a5f611ee1565b565b600b545f9081906001600160a01b031633146110cb5760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff1660038111156110f0576110f0613655565b1461110e57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff16600281111561114e5761114e613655565b1461115e57600a0154915061123b565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a820180549161119283613618565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b84986866040516111e3929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b61124b611381565b6001600160a01b0316336001600160a01b0316148061127457506001546001600160a01b031633145b61129157604051632864c4e160e01b815260040160405180910390fd5b61129a816113af565b61137e5760048054600160281b900464ffffffffff16906112c4906001600160a01b038416611f51565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff19909116179055600280549161131583613669565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906113ff576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561145557602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611437575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561149d5761149d613655565b14159392505050565b6114ae611eaf565b6001600160a01b0381166114d55760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b5f611527612127565b805490915060ff600160401b82041615906001600160401b03165f8115801561154d5750825b90505f826001600160401b031660011480156115685750303b155b905081158015611576575080155b156115945760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156115be57845460ff60401b1916600160401b1785555b6001600160a01b0387166115e55760405163d92e233d60e01b815260040160405180910390fd5b6115ee3361214f565b6115fa60046014612160565b611603866107a6565b61160b611381565b6001600160a01b0316876001600160a01b03161461162c5761162c87611bd3565b831561167257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561169f5761169f613655565b036116bd57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116d5576116d5613655565b146116f357604051631860f69960e31b815260040160405180910390fd5b8060030154421161171757604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806117fc578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156117dd575f5ffd5b505af11580156117ef573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b0381111561182c5761182c61362d565b604051908082528060200260200182016040528015611855578160200160208202803683370190505b5090505f5b828110156118c757846008015f86600601838154811061187c5761187c613641565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106118b4576118b4613641565b602090810291909101015260010161185a565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b15801561190a575f5ffd5b505af115801561191c573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ec9929190613ab5565b61195d611eaf565b6001600160a01b0381166119845760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156119f1576119f1613655565b03611a0f57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff166003811115611a2757611a27613655565b14611a4557604051631860f69960e31b815260040160405180910390fd5b8060030154421115611a6a57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff1615611a9c5760405163257309f160e11b815260040160405180910390fd5b611aa533610edd565b611ac25760405163149fbcfd60e11b815260040160405180910390fd5b611acd3383856121df565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff19166001179055909150611b4c908390836123b0565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611bbc576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611bce600460146125b1565b905090565b611bdb611eaf565b6001600160a01b038116611c04575f604051631e4fbdf760e01b81526004016106d19190613594565b61137e81611ee1565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611c4c5760405162461bcd60e51b81526004016106d190613b18565b825464ffffffffff600160281b90910481169082168111611caa5760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611cbd84886126aa565b64ffffffffff1681526020019081526020015f20819055505f816001611ce39190613b62565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611d185750611ea7565b600185165f03611ddf575f611d3783611d32886001613b7b565b6126aa565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d9891600401613b98565b602060405180830381865af4158015611db3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dd79190613a0f565b935050611e93565b5f611def83611d32600189613bc8565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611e5091600401613b98565b602060405180830381865af4158015611e6b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8f9190613a0f565b9350505b50647fffffffff600194851c169301611cad565b505050505050565b33611eb8611381565b6001600160a01b03161461109a573360405163118cdaa760e01b81526004016106d19190613594565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611fa05760405162461bcd60e51b81526004016106d190613b18565b825464ffffffffff90811690821610611ff35760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611ffe816001613b7b565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f61203584876126aa565b64ffffffffff16815260208101919091526040015f20556001831615612120575f61206582611d32600187613bc8565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe916120c691600401613b98565b602060405180830381865af41580156120e1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121059190613a0f565b647fffffffff600195861c1694909350919091019050612025565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610f8a565b6121576126c7565b61137e816126ec565b602060ff821611156121ae5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b6121bf600160ff831681901b613be5565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121ff5760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b0316612228576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161225e91613be5565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156122a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c99190613a0f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123409190613a0f565b90505f81116123625760405163aeaddff160e01b815260040160405180910390fd5b5f61236d8284613bf8565b90505f811161238f5760405163149fbcfd60e11b815260040160405180910390fd5b808611156116725760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff169081111561242e57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff19168217905590506125aa565b5f5f90505f876008015f855f8154811061244a5761244a613641565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b84548110156124d2575f896008015f87848154811061249457612494613641565b5f9182526020808320909101546001600160a01b031683528201929092526040019020549050828111156124c9578092508193505b50600101612473565b508086106124e6575f9450505050506125aa565b5f886009015f8685815481106124fe576124fe613641565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff1916600183600281111561253b5761253b613655565b02179055508684838154811061255357612553613641565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116126045760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156126285760405162461bcd60e51b81526004016106d190613c17565b8254600160281b900464ffffffffff168061264760ff85166002613d68565b64ffffffffff1610156126975760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b6126a28482856126f4565b949350505050565b5f816126bd60ff851663ffffffff613d81565b6125aa9190613b7b565b6126cf6127bc565b61109a57604051631afcd79f60e31b815260040160405180910390fd5b611bdb6126c7565b5f602060ff831611156127195760405162461bcd60e51b81526004016106d190613c17565b8264ffffffffff165f0361273757612730826127d5565b90506125aa565b5f612743836001613b62565b60ff166001600160401b0381111561275d5761275d61362d565b604051908082528060200260200182016040528015612786578160200160208202803683370190505b50905061279585858584612e6f565b808360ff16815181106127aa576127aa613641565b60200260200101519150509392505050565b5f6127c5612127565b54600160401b900460ff16919050565b5f8160ff165f036127e757505f919050565b8160ff1660010361281957507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff1660020361284b57507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361287d57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff166004036128af57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff166005036128e157507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff1660060361291357507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff1660070361294557507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361297757507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff166009036129a957507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a036129db57507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b03612a0d57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c03612a3f57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a7157507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612aa357507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612ad557507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612b0757507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612b3957507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b6b57507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b9d57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612bcf57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612c0157507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612c3357507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c6557507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c9757507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612cc957507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612cfb57507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612d2d57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d5f57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d9157507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612dc357507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612df557507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612e2757507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e935760405162461bcd60e51b81526004016106d190613c17565b5f8364ffffffffff1611612ef75760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612f03600185613bc8565b9050600181165f03612f5657846001015f612f1e5f846126aa565b64ffffffffff1681526020019081526020015f2054825f81518110612f4557612f45613641565b602002602001018181525050612f7e565b612f5f5f6127d5565b825f81518110612f7157612f71613641565b6020026020010181815250505b5f5b8360ff168160ff161015611ea757600182165f036130765773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612fd257612fd2613641565b60200260200101518152602001612fe8856127d5565b8152506040518263ffffffff1660e01b81526004016130079190613b98565b602060405180830381865af4158015613022573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130469190613a0f565b83613052836001613b62565b60ff168151811061306557613065613641565b602002602001018181525050613227565b5f613082826001613b62565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115613124575f876001015f6130d98560016130c89190613b62565b60018864ffffffffff16901c6126aa565b64ffffffffff1681526020019081526020015f2054905080858460016130ff9190613b62565b60ff168151811061311257613112613641565b60200260200101818152505050613225565b5f876001015f61313b85600188611d329190613bc8565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061319257613192613641565b60200260200101518152506040518263ffffffff1660e01b81526004016131b99190613b98565b602060405180830381865af41580156131d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131f89190613a0f565b85613204856001613b62565b60ff168151811061321757613217613641565b602002602001018181525050505b505b647fffffffff600192831c169101612f80565b6001830191839082156132cb579160200282015f5b8382111561329957833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261324f565b80156132c95782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613299565b505b506132d79291506132db565b5090565b5b808211156132d7575f81556001016132dc565b6001600160a01b038116811461137e575f5ffd5b5f60208284031215613313575f5ffd5b81356125aa816132ef565b5f6020828403121561332e575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561336e5781516001600160a01b0316865260209586019590910190600101613347565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561336e57815186526020958601959091019060010161338a565b604081525f6133ba6040830185613335565b82810360208401526133cc8185613378565b95945050505050565b5f5f83601f8401126133e5575f5ffd5b5081356001600160401b038111156133fb575f5ffd5b602083019150836020828501011115613412575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f60a0898b031215613430575f5ffd5b8835975060208901356001600160401b0381111561344c575f5ffd5b8901601f81018b1361345c575f5ffd5b80356001600160401b03811115613471575f5ffd5b8b60208260051b8401011115613485575f5ffd5b6020919091019750955060408901356001600160401b038111156134a7575f5ffd5b6134b38b828c016133d5565b9096509450506060890135925060808901356001600160401b038111156134d8575f5ffd5b6134e48b828c016133d5565b999c989b5096995094979396929594505050565b5f5f5f6080848603121561350a575f5ffd5b833592506020840135915060808401851015613524575f5ffd5b6040840190509250925092565b5f5f60408385031215613542575f5ffd5b823591506020830135613554816132ef565b809150509250929050565b5f5f5f60608486031215613571575f5ffd5b833592506020840135613583816132ef565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f6125aa6020830184613335565b5f5f604083850312156135cb575f5ffd5b82356135d6816132ef565b946020939093013593505050565b5f5f604083850312156135f5575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161362657613626613604565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f6001820161367a5761367a613604565b5060010190565b6040516101e081016001600160401b03811182821017156136a4576136a461362d565b60405290565b805160048110611bbc575f5ffd5b5f82601f8301126136c7575f5ffd5b604080519081016001600160401b03811182821017156136e9576136e961362d565b80604052508060408401858111156136ff575f5ffd5b845b81811015613719578051835260209283019201613701565b509195945050505050565b8051611bbc816132ef565b805160ff81168114611bbc575f5ffd5b5f82601f83011261374e575f5ffd5b81516001600160401b038111156137675761376761362d565b604051601f8201601f19908116603f011681016001600160401b03811182821017156137955761379561362d565b6040528181528382016020018510156137ac575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b80518015158114611bbc575f5ffd5b5f602082840312156137e7575f5ffd5b81516001600160401b038111156137fc575f5ffd5b8201610200818503121561380e575f5ffd5b613816613681565b81518152613826602083016136aa565b60208201526040828101519082015261384285606084016136b8565b606082015260a0820151608082015261385d60c08301613724565b60a082015261386e60e0830161372f565b60c08201526101008201516001600160401b0381111561388c575f5ffd5b6138988682850161373f565b60e0830152506138ab6101208301613724565b6101008201526138be6101408301613724565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b038111156138f4575f5ffd5b6139008682850161373f565b610180830152506139146101c08301613724565b6101a08201526139276101e083016137c8565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b838152604060208201525f6133cc604083018486613935565b5f60208284031215613986575f5ffd5b6125aa826137c8565b608080825281018790525f8860a08301825b8a8110156139d15782356139b4816132ef565b6001600160a01b03168252602092830192909101906001016139a1565b5083810360208501526139e581898b613935565b9150508560408401528281036060840152613a01818587613935565b9a9950505050505050505050565b5f60208284031215613a1f575f5ffd5b5051919050565b803563ffffffff81168114611bbc575f5ffd5b5f60208284031215613a49575f5ffd5b6125aa82613a26565b80820180821115610f8a57610f8a613604565b84815260a0810160208201855f5b6002811015613aa05763ffffffff613a8a83613a26565b1683526020928301929190910190600101613a73565b50505060608201939093526080015292915050565b604080825283549082018190525f8481526020812090916060840190835b81811015613afa5783546001600160a01b0316835260019384019360209093019201613ad3565b50508381036020850152613b0e8186613378565b9695505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610f8a57610f8a613604565b64ffffffffff8181168382160190811115610f8a57610f8a613604565b6040810181835f5b6002811015613bbf578151835260209283019290910190600101613ba0565b50505092915050565b64ffffffffff8281168282160390811115610f8a57610f8a613604565b81810381811115610f8a57610f8a613604565b5f82613c1257634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b600184111561123b57808504811115613c7957613c79613604565b6001841615613c8757908102905b60019390931c928002613c5e565b5f82613ca357506001610f8a565b81613caf57505f610f8a565b8160018114613cc55760028114613ccf57613d01565b6001915050610f8a565b60ff841115613ce057613ce0613604565b6001841b915064ffffffffff821115613cfb57613cfb613604565b50610f8a565b5060208310610133831016604e8410600b8410161715613d39575081810a64ffffffffff811115613d3457613d34613604565b610f8a565b613d4964ffffffffff8484613c5a565b8064ffffffffff04821115613d6057613d60613604565b029392505050565b5f6125aa64ffffffffff841664ffffffffff8416613c95565b64ffffffffff8181168382160290811690818114613da157613da1613604565b509291505056fea164736f6c634300081c000a", - "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80639a7a2ffc11610135578063dbb06c93116100b4578063f165053611610079578063f165053614610578578063f2fde38b14610592578063f379b0df146105a5578063f52fd803146105df578063f6fc05d514610651575f5ffd5b8063dbb06c9314610525578063e59e469514610537578063e6745e131461054a578063e82f3b701461055d578063ebf0c71714610570575f5ffd5b8063c2b40ae4116100fa578063c2b40ae4146104b0578063c3a0ec30146104cf578063ca2869a0146104e0578063cd6dc687146104ff578063da881e5a14610512575f5ffd5b80639a7a2ffc146104255780639f0f874a14610461578063a01649301461046a578063a8a4d69b1461048a578063bff232c11461049d575f5ffd5b806370e36bbe116101c15780638cb89ecb116101865780638cb89ecb146103c25780638d1ddfb1146103e15780638da5cb5b146103f75780638e5ce3ad146103ff5780639015d37114610412575f5ffd5b806370e36bbe14610347578063715018a61461035a5780637c92f52414610362578063858142431461038f5780638a78bb15146103af575f5ffd5b8063291a691b11610207578063291a691b146102c95780632e7b716d146102ec5780634d6861a6146102ff57806350e6d94c146103125780635d50477614610334575f5ffd5b8063096b810a146102435780630f3e34121461025857806317d611201461026b5780631cc321b5146102955780632800d829146102a8575b5f5ffd5b610256610251366004613303565b61065a565b005b61025661026636600461331e565b6107a6565b61027e61027936600461331e565b6107e9565b60405161028c9291906133a8565b60405180910390f35b6102566102a3366004613419565b610993565b6102bb6102b636600461331e565b610cb7565b60405190815260200161028c565b6102dc6102d73660046134f8565b610d03565b604051901515815260200161028c565b6102dc6102fa366004613303565b610edd565b6102dc61030d36600461331e565b610f90565b6102dc610320366004613303565b60066020525f908152604090205460ff1681565b6102dc610342366004613531565b610fcf565b610256610355366004613303565b611013565b610256611089565b61037561037036600461355f565b61109c565b6040805192835263ffffffff90911660208301520161028c565b6001546103a2906001600160a01b031681565b60405161028c9190613594565b6102566103bd366004613303565b611243565b6102bb6103d036600461331e565b60096020525f908152604090205481565b600454600160281b900464ffffffffff166102bb565b6103a2611381565b600b546103a2906001600160a01b031681565b6102dc610420366004613303565b6113af565b61044b610433366004613303565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff909116815260200161028c565b6102bb60035481565b61047d61047836600461331e565b6113cc565b60405161028c91906135a8565b6102dc610498366004613531565b611462565b6102566104ab366004613303565b6114a6565b6102bb6104be36600461331e565b60086020525f908152604090205481565b6001546001600160a01b03166103a2565b6102bb6104ee36600461331e565b5f9081526008602052604090205490565b61025661050d3660046135ba565b61151e565b6102dc61052036600461331e565b61167b565b5f546103a2906001600160a01b031681565b610256610545366004613303565b611955565b6102566105583660046135e4565b6119cd565b6102bb61056b36600461331e565b611b90565b6102bb611bc1565b610580601481565b60405160ff909116815260200161028c565b6102566105a0366004613303565b611bd3565b6004546105c19064ffffffffff80821691600160281b90041682565b6040805164ffffffffff93841681529290911660208301520161028c565b6106226105ed36600461331e565b5f908152600a6020819052604090912090810154600590910154909163ffffffff80831692600160201b900416908284101590565b60405161028c949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b6102bb60025481565b610662611381565b6001600160a01b0316336001600160a01b0316148061068b57506001546001600160a01b031633145b6106a857604051632864c4e160e01b815260040160405180910390fd5b6106b1816113af565b81906106da576040516381e5828960e01b81526004016106d19190613594565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107089060049083611c0d565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161073583613618565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b6107ae611eaf565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a60208190526040909120600681015491810154606092839291806001600160401b038111156108205761082061362d565b604051908082528060200260200182016040528015610849578160200160208202803683370190505b509450806001600160401b038111156108645761086461362d565b60405190808252806020026020018201604052801561088d578160200160208202803683370190505b5093505f805b83811015610989575f8560060182815481106108b1576108b1613641565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f90815260098801602052604090205460ff1660028111156108f7576108f7613655565b03610980578088848151811061090f5761090f613641565b60200260200101906001600160a01b031690816001600160a01b031681525050856008015f826001600160a01b03166001600160a01b031681526020019081526020015f205487848151811061096757610967613641565b60209081029190910101528261097c81613669565b9350505b50600101610893565b5050505050915091565b5f888152600a602052604090206002815460ff1660038111156109b8576109b8613655565b146109d657604051634f4b461f60e11b815260040160405180910390fd5b6004810154156109f95760405163632a22bb60e01b815260040160405180910390fd5b60068101548714610a425760405162461bcd60e51b815260206004820152601360248201527209cdec8ca40c6deeadce840dad2e6dac2e8c6d606b1b60448201526064016106d1565b83610a875760405162461bcd60e51b81526020600482015260156024820152741c1ad0dbdb5b5a5d1b595b9d081c995c5d5a5c9959605a1b60448201526064016106d1565b5f805460405163101bb4d760e21b8152600481018c90526001600160a01b039091169063406ed35c906024015f60405180830381865afa158015610acd573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610af491908101906137d7565b9050806101c0015115610bf35782610b3f5760405162461bcd60e51b815260206004820152600e60248201526d1c1c9bdbd9881c995c5d5a5c995960921b60448201526064016106d1565b8061012001516001600160a01b031663258ae5828686866040518463ffffffff1660e01b8152600401610b749392919061395d565b602060405180830381865afa158015610b8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bb39190613976565b610bf35760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2102225a390383937b7b360791b60448201526064016106d1565b60048281018690555f8b815260096020526040808220889055905490516340a3b76160e11b81529182018c9052602482018790526001600160a01b0316906381476ec2906044015f604051808303815f87803b158015610c51575f5ffd5b505af1158015610c63573d5f5f3e3d5ffd5b50505050897fbf0636a312095f6c09c909823813b50e392323588d2d83432e7512c64041e67f8a8a8a8a8a8a8a604051610ca3979695949392919061398f565b60405180910390a250505050505050505050565b5f818152600a6020526040812081815460ff166003811115610cdb57610cdb613655565b03610cf957604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610d2e5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610d5257610d52613655565b14610d70576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610db7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddb9190613a0f565b905080610dee6040860160208701613a39565b63ffffffff161115610e066040860160208701613a39565b829091610e34576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106d1565b5050815460ff1916600190811783558201859055436002830155600354610e5b9042613a52565b6003830155610e6f6005830185600261323a565b50610e78611bc1565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610ec9928a928a9291613a65565b60405180910390a250600195945050505050565b5f610ee7826113af565b610ef257505f919050565b6001546001600160a01b0316610f1b576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610f4b908590600401613594565b602060405180830381865afa158015610f66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8a9190613976565b92915050565b5f818152600a602052604081206001815460ff166003811115610fb557610fb5613655565b14610fc257505f92915050565b6003015442111592915050565b5f60015f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561100b5761100b613655565b149392505050565b61101b611eaf565b6001600160a01b0381166110425760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b611091611eaf565b61109a5f611ee1565b565b600b545f9081906001600160a01b031633146110cb5760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff1660038111156110f0576110f0613655565b1461110e57604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f90815260098301602052604090205463ffffffff909116925060019060ff16600281111561114e5761114e613655565b1461115e57600a0154915061123b565b6001600160a01b0385165f9081526009820160205260408120805460ff19166002179055600a820180549161119283613618565b919050555080600a01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b84986866040516111e3929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b61124b611381565b6001600160a01b0316336001600160a01b0316148061127457506001546001600160a01b031633145b61129157604051632864c4e160e01b815260040160405180910390fd5b61129a816113af565b61137e5760048054600160281b900464ffffffffff16906112c4906001600160a01b038416611f51565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff19909116179055600280549161131583613669565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db539060600161079a565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a602052604090206004810154606091906113ff576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561145557602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611437575b5050505050915050919050565b5f805f848152600a602090815260408083206001600160a01b038716845260090190915290205460ff16600281111561149d5761149d613655565b14159392505050565b6114ae611eaf565b6001600160a01b0381166114d55760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b5f611527612127565b805490915060ff600160401b82041615906001600160401b03165f8115801561154d5750825b90505f826001600160401b031660011480156115685750303b155b905081158015611576575080155b156115945760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156115be57845460ff60401b1916600160401b1785555b6001600160a01b0387166115e55760405163d92e233d60e01b815260040160405180910390fd5b6115ee3361214f565b6115fa60046014612160565b611603866107a6565b61160b611381565b6001600160a01b0316876001600160a01b03161461162c5761162c87611bd3565b831561167257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff16600381111561169f5761169f613655565b036116bd57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116d5576116d5613655565b146116f357604051631860f69960e31b815260040160405180910390fd5b8060030154421161171757604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff161115806117fc578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156117dd575f5ffd5b505af11580156117ef573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600a83018190555f816001600160401b0381111561182c5761182c61362d565b604051908082528060200260200182016040528015611855578160200160208202803683370190505b5090505f5b828110156118c757846008015f86600601838154811061187c5761187c613641565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106118b4576118b4613641565b602090810291909101015260010161185a565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b15801561190a575f5ffd5b505af115801561191c573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610ec9929190613ab5565b61195d611eaf565b6001600160a01b0381166119845760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff1660038111156119f1576119f1613655565b03611a0f57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff166003811115611a2757611a27613655565b14611a4557604051631860f69960e31b815260040160405180910390fd5b8060030154421115611a6a57604051639a19114d60e01b815260040160405180910390fd5b335f90815260078201602052604090205460ff1615611a9c5760405163257309f160e11b815260040160405180910390fd5b611aa533610edd565b611ac25760405163149fbcfd60e11b815260040160405180910390fd5b611acd3383856121df565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526007850160205260409020805460ff19166001179055909150611b4c908390836123b0565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611bbc576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611bce600460146125b1565b905090565b611bdb611eaf565b6001600160a01b038116611c04575f604051631e4fbdf760e01b81526004016106d19190613594565b61137e81611ee1565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611c4c5760405162461bcd60e51b81526004016106d190613b18565b825464ffffffffff600160281b90910481169082168111611caa5760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106d1565b825f5b81866001015f611cbd84886126aa565b64ffffffffff1681526020019081526020015f20819055505f816001611ce39190613b62565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611d185750611ea7565b600185165f03611ddf575f611d3783611d32886001613b7b565b6126aa565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611d9891600401613b98565b602060405180830381865af4158015611db3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dd79190613a0f565b935050611e93565b5f611def83611d32600189613bc8565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611e5091600401613b98565b602060405180830381865af4158015611e6b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e8f9190613a0f565b9350505b50647fffffffff600194851c169301611cad565b505050505050565b33611eb8611381565b6001600160a01b03161461109a573360405163118cdaa760e01b81526004016106d19190613594565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611fa05760405162461bcd60e51b81526004016106d190613b18565b825464ffffffffff90811690821610611ff35760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106d1565b611ffe816001613b7b565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f61203584876126aa565b64ffffffffff16815260208101919091526040015f20556001831615612120575f61206582611d32600187613bc8565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe916120c691600401613b98565b602060405180830381865af41580156120e1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121059190613a0f565b647fffffffff600195861c1694909350919091019050612025565b5050505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610f8a565b6121576126c7565b61137e816126ec565b602060ff821611156121ae5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106d1565b6121bf600160ff831681901b613be5565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116121ff5760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b0316612228576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd7191889161225e91613be5565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156122a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122c99190613a0f565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561231c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123409190613a0f565b90505f81116123625760405163aeaddff160e01b815260040160405180910390fd5b5f61236d8284613bf8565b90505f811161238f5760405163149fbcfd60e11b815260040160405180910390fd5b808611156116725760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff169081111561242e57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526008870182526040808420869055600988019092529120805460ff19168217905590506125aa565b5f5f90505f876008015f855f8154811061244a5761244a613641565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b84548110156124d2575f896008015f87848154811061249457612494613641565b5f9182526020808320909101546001600160a01b031683528201929092526040019020549050828111156124c9578092508193505b50600101612473565b508086106124e6575f9450505050506125aa565b5f886009015f8685815481106124fe576124fe613641565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff1916600183600281111561253b5761253b613655565b02179055508684838154811061255357612553613641565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260088a018252604080822089905560098b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116126045760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106d1565b602060ff831611156126285760405162461bcd60e51b81526004016106d190613c17565b8254600160281b900464ffffffffff168061264760ff85166002613d68565b64ffffffffff1610156126975760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106d1565b6126a28482856126f4565b949350505050565b5f816126bd60ff851663ffffffff613d81565b6125aa9190613b7b565b6126cf6127bc565b61109a57604051631afcd79f60e31b815260040160405180910390fd5b611bdb6126c7565b5f602060ff831611156127195760405162461bcd60e51b81526004016106d190613c17565b8264ffffffffff165f0361273757612730826127d5565b90506125aa565b5f612743836001613b62565b60ff166001600160401b0381111561275d5761275d61362d565b604051908082528060200260200182016040528015612786578160200160208202803683370190505b50905061279585858584612e6f565b808360ff16815181106127aa576127aa613641565b60200260200101519150509392505050565b5f6127c5612127565b54600160401b900460ff16919050565b5f8160ff165f036127e757505f919050565b8160ff1660010361281957507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff1660020361284b57507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361287d57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff166004036128af57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff166005036128e157507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff1660060361291357507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff1660070361294557507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff1660080361297757507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff166009036129a957507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a036129db57507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b03612a0d57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c03612a3f57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612a7157507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612aa357507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612ad557507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612b0757507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612b3957507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612b6b57507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612b9d57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612bcf57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612c0157507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612c3357507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612c6557507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612c9757507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612cc957507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612cfb57507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612d2d57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612d5f57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612d9157507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612dc357507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612df557507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612e2757507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106d1565b602060ff83161115612e935760405162461bcd60e51b81526004016106d190613c17565b5f8364ffffffffff1611612ef75760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106d1565b5f612f03600185613bc8565b9050600181165f03612f5657846001015f612f1e5f846126aa565b64ffffffffff1681526020019081526020015f2054825f81518110612f4557612f45613641565b602002602001018181525050612f7e565b612f5f5f6127d5565b825f81518110612f7157612f71613641565b6020026020010181815250505b5f5b8360ff168160ff161015611ea757600182165f036130765773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff1681518110612fd257612fd2613641565b60200260200101518152602001612fe8856127d5565b8152506040518263ffffffff1660e01b81526004016130079190613b98565b602060405180830381865af4158015613022573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130469190613a0f565b83613052836001613b62565b60ff168151811061306557613065613641565b602002602001018181525050613227565b5f613082826001613b62565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff16811115613124575f876001015f6130d98560016130c89190613b62565b60018864ffffffffff16901c6126aa565b64ffffffffff1681526020019081526020015f2054905080858460016130ff9190613b62565b60ff168151811061311257613112613641565b60200260200101818152505050613225565b5f876001015f61313b85600188611d329190613bc8565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061319257613192613641565b60200260200101518152506040518263ffffffff1660e01b81526004016131b99190613b98565b602060405180830381865af41580156131d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131f89190613a0f565b85613204856001613b62565b60ff168151811061321757613217613641565b602002602001018181525050505b505b647fffffffff600192831c169101612f80565b6001830191839082156132cb579160200282015f5b8382111561329957833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030261324f565b80156132c95782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613299565b505b506132d79291506132db565b5090565b5b808211156132d7575f81556001016132dc565b6001600160a01b038116811461137e575f5ffd5b5f60208284031215613313575f5ffd5b81356125aa816132ef565b5f6020828403121561332e575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561336e5781516001600160a01b0316865260209586019590910190600101613347565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561336e57815186526020958601959091019060010161338a565b604081525f6133ba6040830185613335565b82810360208401526133cc8185613378565b95945050505050565b5f5f83601f8401126133e5575f5ffd5b5081356001600160401b038111156133fb575f5ffd5b602083019150836020828501011115613412575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f60a0898b031215613430575f5ffd5b8835975060208901356001600160401b0381111561344c575f5ffd5b8901601f81018b1361345c575f5ffd5b80356001600160401b03811115613471575f5ffd5b8b60208260051b8401011115613485575f5ffd5b6020919091019750955060408901356001600160401b038111156134a7575f5ffd5b6134b38b828c016133d5565b9096509450506060890135925060808901356001600160401b038111156134d8575f5ffd5b6134e48b828c016133d5565b999c989b5096995094979396929594505050565b5f5f5f6080848603121561350a575f5ffd5b833592506020840135915060808401851015613524575f5ffd5b6040840190509250925092565b5f5f60408385031215613542575f5ffd5b823591506020830135613554816132ef565b809150509250929050565b5f5f5f60608486031215613571575f5ffd5b833592506020840135613583816132ef565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f6125aa6020830184613335565b5f5f604083850312156135cb575f5ffd5b82356135d6816132ef565b946020939093013593505050565b5f5f604083850312156135f5575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161362657613626613604565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f6001820161367a5761367a613604565b5060010190565b6040516101e081016001600160401b03811182821017156136a4576136a461362d565b60405290565b805160048110611bbc575f5ffd5b5f82601f8301126136c7575f5ffd5b604080519081016001600160401b03811182821017156136e9576136e961362d565b80604052508060408401858111156136ff575f5ffd5b845b81811015613719578051835260209283019201613701565b509195945050505050565b8051611bbc816132ef565b805160ff81168114611bbc575f5ffd5b5f82601f83011261374e575f5ffd5b81516001600160401b038111156137675761376761362d565b604051601f8201601f19908116603f011681016001600160401b03811182821017156137955761379561362d565b6040528181528382016020018510156137ac575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b80518015158114611bbc575f5ffd5b5f602082840312156137e7575f5ffd5b81516001600160401b038111156137fc575f5ffd5b8201610200818503121561380e575f5ffd5b613816613681565b81518152613826602083016136aa565b60208201526040828101519082015261384285606084016136b8565b606082015260a0820151608082015261385d60c08301613724565b60a082015261386e60e0830161372f565b60c08201526101008201516001600160401b0381111561388c575f5ffd5b6138988682850161373f565b60e0830152506138ab6101208301613724565b6101008201526138be6101408301613724565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b038111156138f4575f5ffd5b6139008682850161373f565b610180830152506139146101c08301613724565b6101a08201526139276101e083016137c8565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b838152604060208201525f6133cc604083018486613935565b5f60208284031215613986575f5ffd5b6125aa826137c8565b608080825281018790525f8860a08301825b8a8110156139d15782356139b4816132ef565b6001600160a01b03168252602092830192909101906001016139a1565b5083810360208501526139e581898b613935565b9150508560408401528281036060840152613a01818587613935565b9a9950505050505050505050565b5f60208284031215613a1f575f5ffd5b5051919050565b803563ffffffff81168114611bbc575f5ffd5b5f60208284031215613a49575f5ffd5b6125aa82613a26565b80820180821115610f8a57610f8a613604565b84815260a0810160208201855f5b6002811015613aa05763ffffffff613a8a83613a26565b1683526020928301929190910190600101613a73565b50505060608201939093526080015292915050565b604080825283549082018190525f8481526020812090916060840190835b81811015613afa5783546001600160a01b0316835260019384019360209093019201613ad3565b50508381036020850152613b0e8186613378565b9695505050505050565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610f8a57610f8a613604565b64ffffffffff8181168382160190811115610f8a57610f8a613604565b6040810181835f5b6002811015613bbf578151835260209283019290910190600101613ba0565b50505092915050565b64ffffffffff8281168282160390811115610f8a57610f8a613604565b81810381811115610f8a57610f8a613604565b5f82613c1257634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b600184111561123b57808504811115613c7957613c79613604565b6001841615613c8757908102905b60019390931c928002613c5e565b5f82613ca357506001610f8a565b81613caf57505f610f8a565b8160018114613cc55760028114613ccf57613d01565b6001915050610f8a565b60ff841115613ce057613ce0613604565b6001841b915064ffffffffff821115613cfb57613cfb613604565b50610f8a565b5060208310610133831016604e8410600b8410161715613d39575081810a64ffffffffff811115613d3457613d34613604565b610f8a565b613d4964ffffffffff8484613c5a565b8064ffffffffff04821115613d6057613d60613604565b029392505050565b5f6125aa64ffffffffff841664ffffffffff8416613c95565b64ffffffffff8181168382160290811690818114613da157613da1613604565b509291505056fea164736f6c634300081c000a", + "bytecode": "0x6080604052348015600e575f5ffd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b613e01806100d65f395ff3fe608060405234801561000f575f5ffd5b506004361061024a575f3560e01c80639a7a2ffc11610140578063da881e5a116100bf578063ebf0c71711610084578063ebf0c7171461058a578063f165053614610592578063f2fde38b146105ac578063f379b0df146105bf578063f52fd803146105f9578063f6fc05d514610669575f5ffd5b8063da881e5a1461052c578063dbb06c931461053f578063e59e469514610551578063e6745e1314610564578063e82f3b7014610577575f5ffd5b8063c2b40ae411610105578063c2b40ae4146104b7578063c3a0ec30146104d6578063c6b2a438146104e7578063ca2869a0146104fa578063cd6dc68714610519575f5ffd5b80639a7a2ffc1461042c5780639f0f874a14610468578063a016493014610471578063a8a4d69b14610491578063bff232c1146104a4575f5ffd5b806370e36bbe116101cc5780638cb89ecb116101915780638cb89ecb146103c95780638d1ddfb1146103e85780638da5cb5b146103fe5780638e5ce3ad146104065780639015d37114610419575f5ffd5b806370e36bbe1461034e578063715018a6146103615780637c92f5241461036957806385814243146103965780638a78bb15146103b6575f5ffd5b8063291a691b11610212578063291a691b146102d05780632e7b716d146102f35780634d6861a61461030657806350e6d94c146103195780635d5047761461033b575f5ffd5b8063096b810a1461024e578063099a161a146102635780630f3e34121461028957806317d611201461029c5780632800d829146102bd575b5f5ffd5b61026161025c3660046133b3565b610672565b005b6102766102713660046133ce565b6107be565b6040519081526020015b60405180910390f35b6102616102973660046133ce565b6107f7565b6102af6102aa3660046133ce565b61083a565b604051610280929190613458565b6102766102cb3660046133ce565b6109e3565b6102e36102de366004613485565b610a2f565b6040519015158152602001610280565b6102e36103013660046133b3565b610c09565b6102e36103143660046133ce565b610cbc565b6102e36103273660046133b3565b60066020525f908152604090205460ff1681565b6102e36103493660046134be565b610cfb565b61026161035c3660046133b3565b610d3e565b610261610db4565b61037c6103773660046134ec565b610dc7565b6040805192835263ffffffff909116602083015201610280565b6001546103a9906001600160a01b031681565b6040516102809190613521565b6102616103c43660046133b3565b610f6e565b6102766103d73660046133ce565b60096020525f908152604090205481565b600454600160281b900464ffffffffff16610276565b6103a96110ac565b600b546103a9906001600160a01b031681565b6102e36104273660046133b3565b6110da565b61045261043a3660046133b3565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff9091168152602001610280565b61027660035481565b61048461047f3660046133ce565b6110f7565b6040516102809190613535565b6102e361049f3660046134be565b61118d565b6102616104b23660046133b3565b6111d0565b6102766104c53660046133ce565b60086020525f908152604090205481565b6001546001600160a01b03166103a9565b6102616104f536600461358b565b611248565b6102766105083660046133ce565b5f9081526008602052604090205490565b61026161052736600461360b565b61153e565b6102e361053a3660046133ce565b61169b565b5f546103a9906001600160a01b031681565b61026161055f3660046133b3565b611975565b610261610572366004613635565b6119ed565b6102766105853660046133ce565b611bb0565b610276611be1565b61059a601481565b60405160ff9091168152602001610280565b6102616105ba3660046133b3565b611bf3565b6004546105db9064ffffffffff80821691600160281b90041682565b6040805164ffffffffff938416815292909116602083015201610280565b61063a6106073660046133ce565b5f908152600a60205260409020600b810154600590910154909163ffffffff80831692600160201b900416908284101590565b604051610280949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b61027660025481565b61067a6110ac565b6001600160a01b0316336001600160a01b031614806106a357506001546001600160a01b031633145b6106c057604051632864c4e160e01b815260040160405180910390fd5b6106c9816110da565b81906106f2576040516381e5828960e01b81526004016106e99190613521565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107209060049083611c2d565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161074d83613669565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b5f818152600a6020526040812060048101546107ed576040516322e679e360e11b815260040160405180910390fd5b6007015492915050565b6107ff611ecf565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602052604090206006810154600b82015460609283929091806001600160401b038111156108705761087061367e565b604051908082528060200260200182016040528015610899578160200160208202803683370190505b509450806001600160401b038111156108b4576108b461367e565b6040519080825280602002602001820160405280156108dd578160200160208202803683370190505b5093505f805b838110156109d9575f85600601828154811061090157610901613692565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f908152600a8801602052604090205460ff166002811115610947576109476136a6565b036109d0578088848151811061095f5761095f613692565b60200260200101906001600160a01b031690816001600160a01b031681525050856009015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109b7576109b7613692565b6020908102919091010152826109cc816136ba565b9350505b506001016108e3565b5050505050915091565b5f818152600a6020526040812081815460ff166003811115610a0757610a076136a6565b03610a2557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a5a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a7e57610a7e6136a6565b14610a9c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0791906136d2565b905080610b1a60408601602087016136fc565b63ffffffff161115610b3260408601602087016136fc565b829091610b60576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106e9565b5050815460ff1916600190811783558201859055436002830155600354610b879042613715565b6003830155610b9b600583018560026132ea565b50610ba4611be1565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610bf5928a928a9291613728565b60405180910390a250600195945050505050565b5f610c13826110da565b610c1e57505f919050565b6001546001600160a01b0316610c47576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c77908590600401613521565b602060405180830381865afa158015610c92573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cb69190613787565b92915050565b5f818152600a602052604081206001815460ff166003811115610ce157610ce16136a6565b14610cee57505f92915050565b6003015442111592915050565b5f60015f848152600a602081815260408084206001600160a01b0388168552909201905290205460ff166002811115610d3657610d366136a6565b149392505050565b610d46611ecf565b6001600160a01b038116610d6d5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610dbc611ecf565b610dc55f611f01565b565b600b545f9081906001600160a01b03163314610df65760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610e1b57610e1b6136a6565b14610e3957604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f908152600a8301602052604090205463ffffffff909116925060019060ff166002811115610e7957610e796136a6565b14610e8957600b01549150610f66565b6001600160a01b0385165f908152600a820160205260408120805460ff19166002179055600b8201805491610ebd83613669565b919050555080600b01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610f0e929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f766110ac565b6001600160a01b0316336001600160a01b03161480610f9f57506001546001600160a01b031633145b610fbc57604051632864c4e160e01b815260040160405180910390fd5b610fc5816110da565b6110a95760048054600160281b900464ffffffffff1690610fef906001600160a01b038416611f71565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491611040836136ba565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db53906060016107b2565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a6020526040902060048101546060919061112a576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561118057602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611162575b5050505050915050919050565b5f805f848152600a602081815260408084206001600160a01b0388168552909201905290205460ff1660028111156111c7576111c76136a6565b14159392505050565b6111d8611ecf565b6001600160a01b0381166111ff5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b5f868152600a602052604090206002815460ff16600381111561126d5761126d6136a6565b1461128b57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156112ae5760405163632a22bb60e01b815260040160405180910390fd5b836112f35760405162461bcd60e51b81526020600482015260156024820152741c1ad0dbdb5b5a5d1b595b9d081c995c5d5a5c9959605a1b60448201526064016106e9565b5f61130082600601612147565b600783018190555f805460405163101bb4d760e21b8152600481018c905292935090916001600160a01b039091169063406ed35c906024015f60405180830381865afa158015611352573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137991908101906138e7565b9050806101c001511561147a57836113c45760405162461bcd60e51b815260206004820152600e60248201526d1c1c9bdbd9881c995c5d5a5c995960921b60448201526064016106e9565b8061012001516001600160a01b031663de12c640878488886040518563ffffffff1660e01b81526004016113fb9493929190613a6d565b602060405180830381865afa158015611416573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143a9190613787565b61147a5760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2102225a390383937b7b360791b60448201526064016106e9565b60048381018790555f8a815260096020526040808220899055905490516340a3b76160e11b81529182018b9052602482018890526001600160a01b0316906381476ec2906044015f604051808303815f87803b1580156114d8575f5ffd5b505af11580156114ea573d5f5f3e3d5ffd5b50505050887fbf0636a312095f6c09c909823813b50e392323588d2d83432e7512c64041e67f846006018a8a8a8a8a60405161152b96959493929190613ad2565b60405180910390a2505050505050505050565b5f6115476121a8565b805490915060ff600160401b82041615906001600160401b03165f8115801561156d5750825b90505f826001600160401b031660011480156115885750303b155b905081158015611596575080155b156115b45760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156115de57845460ff60401b1916600160401b1785555b6001600160a01b0387166116055760405163d92e233d60e01b815260040160405180910390fd5b61160e336121d0565b61161a600460146121e1565b611623866107f7565b61162b6110ac565b6001600160a01b0316876001600160a01b03161461164c5761164c87611bf3565b831561169257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156116bf576116bf6136a6565b036116dd57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116f5576116f56136a6565b1461171357604051631860f69960e31b815260040160405180910390fd5b8060030154421161173757604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061181c578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156117fd575f5ffd5b505af115801561180f573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600b83018190555f816001600160401b0381111561184c5761184c61367e565b604051908082528060200260200182016040528015611875578160200160208202803683370190505b5090505f5b828110156118e757846009015f86600601838154811061189c5761189c613692565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106118d4576118d4613692565b602090810291909101015260010161187a565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b15801561192a575f5ffd5b505af115801561193c573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610bf5929190613b1f565b61197d611ecf565b6001600160a01b0381166119a45760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff166003811115611a1157611a116136a6565b03611a2f57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff166003811115611a4757611a476136a6565b14611a6557604051631860f69960e31b815260040160405180910390fd5b8060030154421115611a8a57604051639a19114d60e01b815260040160405180910390fd5b335f90815260088201602052604090205460ff1615611abc5760405163257309f160e11b815260040160405180910390fd5b611ac533610c09565b611ae25760405163149fbcfd60e11b815260040160405180910390fd5b611aed338385612260565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526008850160205260409020805460ff19166001179055909150611b6c90839083612431565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611bdc576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611bee60046014612632565b905090565b611bfb611ecf565b6001600160a01b038116611c24575f604051631e4fbdf760e01b81526004016106e99190613521565b6110a981611f01565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611c6c5760405162461bcd60e51b81526004016106e990613b31565b825464ffffffffff600160281b90910481169082168111611cca5760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106e9565b825f5b81866001015f611cdd848861272b565b64ffffffffff1681526020019081526020015f20819055505f816001611d039190613b7b565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611d385750611ec7565b600185165f03611dff575f611d5783611d52886001613b94565b61272b565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611db891600401613bb1565b602060405180830381865af4158015611dd3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611df791906136d2565b935050611eb3565b5f611e0f83611d52600189613be1565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611e7091600401613bb1565b602060405180830381865af4158015611e8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eaf91906136d2565b9350505b50647fffffffff600194851c169301611ccd565b505050505050565b33611ed86110ac565b6001600160a01b031614610dc5573360405163118cdaa760e01b81526004016106e99190613521565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611fc05760405162461bcd60e51b81526004016106e990613b31565b825464ffffffffff908116908216106120135760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106e9565b61201e816001613b94565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f612055848761272b565b64ffffffffff16815260208101919091526040015f20556001831615612140575f61208582611d52600187613be1565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe916120e691600401613bb1565b602060405180830381865af4158015612101573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061212591906136d2565b647fffffffff600195861c1694909350919091019050612045565b5050505050565b5f610cb68280548060200260200160405190810160405280929190818152602001828054801561219e57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311612180575b5050505050612748565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610cb6565b6121d8612777565b6110a98161279c565b602060ff8216111561222f5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106e9565b612240600160ff831681901b613bfe565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116122805760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166122a9576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916122df91613bfe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612326573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061234a91906136d2565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561239d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123c191906136d2565b90505f81116123e35760405163aeaddff160e01b815260040160405180910390fd5b5f6123ee8284613c11565b90505f81116124105760405163149fbcfd60e11b815260040160405180910390fd5b808611156116925760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156124af57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526009870182526040808420869055600a88019092529120805460ff191682179055905061262b565b5f5f90505f876009015f855f815481106124cb576124cb613692565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612553575f896009015f87848154811061251557612515613692565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205490508281111561254a578092508193505b506001016124f4565b50808610612567575f94505050505061262b565b5f88600a015f86858154811061257f5761257f613692565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156125bc576125bc6136a6565b0217905550868483815481106125d4576125d4613692565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260098a0182526040808220899055600a8b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116126855760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106e9565b602060ff831611156126a95760405162461bcd60e51b81526004016106e990613c30565b8254600160281b900464ffffffffff16806126c860ff85166002613d81565b64ffffffffff1610156127185760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106e9565b6127238482856127a4565b949350505050565b5f8161273e60ff851663ffffffff613d9a565b61262b9190613b94565b5f8160405160200161275a9190613dc1565b604051602081830303815290604052805190602001209050919050565b61277f61286c565b610dc557604051631afcd79f60e31b815260040160405180910390fd5b611bfb612777565b5f602060ff831611156127c95760405162461bcd60e51b81526004016106e990613c30565b8264ffffffffff165f036127e7576127e082612885565b905061262b565b5f6127f3836001613b7b565b60ff166001600160401b0381111561280d5761280d61367e565b604051908082528060200260200182016040528015612836578160200160208202803683370190505b50905061284585858584612f1f565b808360ff168151811061285a5761285a613692565b60200260200101519150509392505050565b5f6128756121a8565b54600160401b900460ff16919050565b5f8160ff165f0361289757505f919050565b8160ff166001036128c957507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036128fb57507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361292d57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361295f57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361299157507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036129c357507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036129f557507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff16600803612a2757507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff16600903612a5957507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a03612a8b57507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b03612abd57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c03612aef57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612b2157507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612b5357507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612b8557507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612bb757507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612be957507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612c1b57507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612c4d57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612c7f57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612cb157507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612ce357507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612d1557507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612d4757507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612d7957507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612dab57507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612ddd57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612e0f57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612e4157507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612e7357507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612ea557507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612ed757507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106e9565b602060ff83161115612f435760405162461bcd60e51b81526004016106e990613c30565b5f8364ffffffffff1611612fa75760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106e9565b5f612fb3600185613be1565b9050600181165f0361300657846001015f612fce5f8461272b565b64ffffffffff1681526020019081526020015f2054825f81518110612ff557612ff5613692565b60200260200101818152505061302e565b61300f5f612885565b825f8151811061302157613021613692565b6020026020010181815250505b5f5b8360ff168160ff161015611ec757600182165f036131265773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff168151811061308257613082613692565b6020026020010151815260200161309885612885565b8152506040518263ffffffff1660e01b81526004016130b79190613bb1565b602060405180830381865af41580156130d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130f691906136d2565b83613102836001613b7b565b60ff168151811061311557613115613692565b6020026020010181815250506132d7565b5f613132826001613b7b565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156131d4575f876001015f6131898560016131789190613b7b565b60018864ffffffffff16901c61272b565b64ffffffffff1681526020019081526020015f2054905080858460016131af9190613b7b565b60ff16815181106131c2576131c2613692565b602002602001018181525050506132d5565b5f876001015f6131eb85600188611d529190613be1565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061324257613242613692565b60200260200101518152506040518263ffffffff1660e01b81526004016132699190613bb1565b602060405180830381865af4158015613284573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132a891906136d2565b856132b4856001613b7b565b60ff16815181106132c7576132c7613692565b602002602001018181525050505b505b647fffffffff600192831c169101613030565b60018301918390821561337b579160200282015f5b8382111561334957833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026132ff565b80156133795782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613349565b505b5061338792915061338b565b5090565b5b80821115613387575f815560010161338c565b6001600160a01b03811681146110a9575f5ffd5b5f602082840312156133c3575f5ffd5b813561262b8161339f565b5f602082840312156133de575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561341e5781516001600160a01b03168652602095860195909101906001016133f7565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561341e57815186526020958601959091019060010161343a565b604081525f61346a60408301856133e5565b828103602084015261347c8185613428565b95945050505050565b5f5f5f60808486031215613497575f5ffd5b8335925060208401359150608084018510156134b1575f5ffd5b6040840190509250925092565b5f5f604083850312156134cf575f5ffd5b8235915060208301356134e18161339f565b809150509250929050565b5f5f5f606084860312156134fe575f5ffd5b8335925060208401356135108161339f565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61262b60208301846133e5565b5f5f83601f840112613557575f5ffd5b5081356001600160401b0381111561356d575f5ffd5b602083019150836020828501011115613584575f5ffd5b9250929050565b5f5f5f5f5f5f608087890312156135a0575f5ffd5b8635955060208701356001600160401b038111156135bc575f5ffd5b6135c889828a01613547565b9096509450506040870135925060608701356001600160401b038111156135ed575f5ffd5b6135f989828a01613547565b979a9699509497509295939492505050565b5f5f6040838503121561361c575f5ffd5b82356136278161339f565b946020939093013593505050565b5f5f60408385031215613646575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161367757613677613655565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f600182016136cb576136cb613655565b5060010190565b5f602082840312156136e2575f5ffd5b5051919050565b803563ffffffff81168114611bdc575f5ffd5b5f6020828403121561370c575f5ffd5b61262b826136e9565b80820180821115610cb657610cb6613655565b84815260a0810160208201855f5b60028110156137635763ffffffff61374d836136e9565b1683526020928301929190910190600101613736565b50505060608201939093526080015292915050565b80518015158114611bdc575f5ffd5b5f60208284031215613797575f5ffd5b61262b82613778565b6040516101e081016001600160401b03811182821017156137c3576137c361367e565b60405290565b805160048110611bdc575f5ffd5b5f82601f8301126137e6575f5ffd5b604080519081016001600160401b03811182821017156138085761380861367e565b806040525080604084018581111561381e575f5ffd5b845b81811015613838578051835260209283019201613820565b509195945050505050565b8051611bdc8161339f565b805160ff81168114611bdc575f5ffd5b5f82601f83011261386d575f5ffd5b81516001600160401b038111156138865761388661367e565b604051601f8201601f19908116603f011681016001600160401b03811182821017156138b4576138b461367e565b6040528181528382016020018510156138cb575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156138f7575f5ffd5b81516001600160401b0381111561390c575f5ffd5b8201610200818503121561391e575f5ffd5b6139266137a0565b81518152613936602083016137c9565b60208201526040828101519082015261395285606084016137d7565b606082015260a0820151608082015261396d60c08301613843565b60a082015261397e60e0830161384e565b60c08201526101008201516001600160401b0381111561399c575f5ffd5b6139a88682850161385e565b60e0830152506139bb6101208301613843565b6101008201526139ce6101408301613843565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613a04575f5ffd5b613a108682850161385e565b61018083015250613a246101c08301613843565b6101a0820152613a376101e08301613778565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f613a8c606083018486613a45565b9695505050505050565b5f8154808452602084019350825f5260205f205f5b8281101561341e5781546001600160a01b0316865260209095019460019182019101613aab565b608081525f613ae46080830189613a96565b8281036020840152613af781888a613a45565b90508560408401528281036060840152613b12818587613a45565b9998505050505050505050565b604081525f61346a6040830185613a96565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610cb657610cb6613655565b64ffffffffff8181168382160190811115610cb657610cb6613655565b6040810181835f5b6002811015613bd8578151835260209283019290910190600101613bb9565b50505092915050565b64ffffffffff8281168282160390811115610cb657610cb6613655565b81810381811115610cb657610cb6613655565b5f82613c2b57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f6657808504811115613c9257613c92613655565b6001841615613ca057908102905b60019390931c928002613c77565b5f82613cbc57506001610cb6565b81613cc857505f610cb6565b8160018114613cde5760028114613ce857613d1a565b6001915050610cb6565b60ff841115613cf957613cf9613655565b6001841b915064ffffffffff821115613d1457613d14613655565b50610cb6565b5060208310610133831016604e8410600b8410161715613d52575081810a64ffffffffff811115613d4d57613d4d613655565b610cb6565b613d6264ffffffffff8484613c73565b8064ffffffffff04821115613d7957613d79613655565b029392505050565b5f61262b64ffffffffff841664ffffffffff8416613cae565b64ffffffffff8181168382160290811690818114613dba57613dba613655565b5092915050565b81515f90829060208501835b828110156138385781516001600160a01b0316845260209384019390910190600101613dcd56fea164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561000f575f5ffd5b506004361061024a575f3560e01c80639a7a2ffc11610140578063da881e5a116100bf578063ebf0c71711610084578063ebf0c7171461058a578063f165053614610592578063f2fde38b146105ac578063f379b0df146105bf578063f52fd803146105f9578063f6fc05d514610669575f5ffd5b8063da881e5a1461052c578063dbb06c931461053f578063e59e469514610551578063e6745e1314610564578063e82f3b7014610577575f5ffd5b8063c2b40ae411610105578063c2b40ae4146104b7578063c3a0ec30146104d6578063c6b2a438146104e7578063ca2869a0146104fa578063cd6dc68714610519575f5ffd5b80639a7a2ffc1461042c5780639f0f874a14610468578063a016493014610471578063a8a4d69b14610491578063bff232c1146104a4575f5ffd5b806370e36bbe116101cc5780638cb89ecb116101915780638cb89ecb146103c95780638d1ddfb1146103e85780638da5cb5b146103fe5780638e5ce3ad146104065780639015d37114610419575f5ffd5b806370e36bbe1461034e578063715018a6146103615780637c92f5241461036957806385814243146103965780638a78bb15146103b6575f5ffd5b8063291a691b11610212578063291a691b146102d05780632e7b716d146102f35780634d6861a61461030657806350e6d94c146103195780635d5047761461033b575f5ffd5b8063096b810a1461024e578063099a161a146102635780630f3e34121461028957806317d611201461029c5780632800d829146102bd575b5f5ffd5b61026161025c3660046133b3565b610672565b005b6102766102713660046133ce565b6107be565b6040519081526020015b60405180910390f35b6102616102973660046133ce565b6107f7565b6102af6102aa3660046133ce565b61083a565b604051610280929190613458565b6102766102cb3660046133ce565b6109e3565b6102e36102de366004613485565b610a2f565b6040519015158152602001610280565b6102e36103013660046133b3565b610c09565b6102e36103143660046133ce565b610cbc565b6102e36103273660046133b3565b60066020525f908152604090205460ff1681565b6102e36103493660046134be565b610cfb565b61026161035c3660046133b3565b610d3e565b610261610db4565b61037c6103773660046134ec565b610dc7565b6040805192835263ffffffff909116602083015201610280565b6001546103a9906001600160a01b031681565b6040516102809190613521565b6102616103c43660046133b3565b610f6e565b6102766103d73660046133ce565b60096020525f908152604090205481565b600454600160281b900464ffffffffff16610276565b6103a96110ac565b600b546103a9906001600160a01b031681565b6102e36104273660046133b3565b6110da565b61045261043a3660046133b3565b60076020525f908152604090205464ffffffffff1681565b60405164ffffffffff9091168152602001610280565b61027660035481565b61048461047f3660046133ce565b6110f7565b6040516102809190613535565b6102e361049f3660046134be565b61118d565b6102616104b23660046133b3565b6111d0565b6102766104c53660046133ce565b60086020525f908152604090205481565b6001546001600160a01b03166103a9565b6102616104f536600461358b565b611248565b6102766105083660046133ce565b5f9081526008602052604090205490565b61026161052736600461360b565b61153e565b6102e361053a3660046133ce565b61169b565b5f546103a9906001600160a01b031681565b61026161055f3660046133b3565b611975565b610261610572366004613635565b6119ed565b6102766105853660046133ce565b611bb0565b610276611be1565b61059a601481565b60405160ff9091168152602001610280565b6102616105ba3660046133b3565b611bf3565b6004546105db9064ffffffffff80821691600160281b90041682565b6040805164ffffffffff938416815292909116602083015201610280565b61063a6106073660046133ce565b5f908152600a60205260409020600b810154600590910154909163ffffffff80831692600160201b900416908284101590565b604051610280949392919093845263ffffffff9283166020850152911660408301521515606082015260800190565b61027660025481565b61067a6110ac565b6001600160a01b0316336001600160a01b031614806106a357506001546001600160a01b031633145b6106c057604051632864c4e160e01b815260040160405180910390fd5b6106c9816110da565b81906106f2576040516381e5828960e01b81526004016106e99190613521565b60405180910390fd5b506001600160a01b0381165f9081526007602052604081205464ffffffffff16906107209060049083611c2d565b6001600160a01b0382165f908152600660205260408120805460ff19169055600280549161074d83613669565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f8c008e3835f6c79bfcdb89f0f6ca8705e0b01049ee84a90b0e4da1c7ba9405d5906060015b60405180910390a25050565b5f818152600a6020526040812060048101546107ed576040516322e679e360e11b815260040160405180910390fd5b6007015492915050565b6107ff611ecf565b60038190556040518181527fbe772dc189863d512fa01e489c8eac204975aef1a8662d8b5a333804b5207ab79060200160405180910390a150565b5f818152600a602052604090206006810154600b82015460609283929091806001600160401b038111156108705761087061367e565b604051908082528060200260200182016040528015610899578160200160208202803683370190505b509450806001600160401b038111156108b4576108b461367e565b6040519080825280602002602001820160405280156108dd578160200160208202803683370190505b5093505f805b838110156109d9575f85600601828154811061090157610901613692565b5f918252602090912001546001600160a01b0316905060016001600160a01b0382165f908152600a8801602052604090205460ff166002811115610947576109476136a6565b036109d0578088848151811061095f5761095f613692565b60200260200101906001600160a01b031690816001600160a01b031681525050856009015f826001600160a01b03166001600160a01b031681526020019081526020015f20548784815181106109b7576109b7613692565b6020908102919091010152826109cc816136ba565b9350505b506001016108e3565b5050505050915091565b5f818152600a6020526040812081815460ff166003811115610a0757610a076136a6565b03610a2557604051630d4c1d9760e41b815260040160405180910390fd5b6003015492915050565b5f80546001600160a01b03163314610a5a5760405163e4c2a7eb60e01b815260040160405180910390fd5b5f848152600a6020526040812090815460ff166003811115610a7e57610a7e6136a6565b14610a9c576040516374ff462560e11b815260040160405180910390fd5b60015460408051630cc37d8f60e11b815290515f926001600160a01b031691631986fb1e9160048083019260209291908290030181865afa158015610ae3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0791906136d2565b905080610b1a60408601602087016136fc565b63ffffffff161115610b3260408601602087016136fc565b829091610b60576040516344ec930f60e01b815263ffffffff909216600483015260248201526044016106e9565b5050815460ff1916600190811783558201859055436002830155600354610b879042613715565b6003830155610b9b600583018560026132ea565b50610ba4611be1565b5f87815260086020526040908190209190915560028301546003840154915188927f381d281d32f95ef8fe4e5f3b263ea6a32d03d331e1a141ae1da996dc02a7a17092610bf5928a928a9291613728565b60405180910390a250600195945050505050565b5f610c13826110da565b610c1e57505f919050565b6001546001600160a01b0316610c47576040516350ca893360e01b815260040160405180910390fd5b600154604051639f8a13d760e01b81526001600160a01b0390911690639f8a13d790610c77908590600401613521565b602060405180830381865afa158015610c92573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cb69190613787565b92915050565b5f818152600a602052604081206001815460ff166003811115610ce157610ce16136a6565b14610cee57505f92915050565b6003015442111592915050565b5f60015f848152600a602081815260408084206001600160a01b0388168552909201905290205460ff166002811115610d3657610d366136a6565b149392505050565b610d46611ecf565b6001600160a01b038116610d6d5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b038316908117825560405190917f2c8267accd82e977550ed2349c73311183cd22e306347be4453c8d130995e3c991a250565b610dbc611ecf565b610dc55f611f01565b565b600b545f9081906001600160a01b03163314610df65760405163fcef374960e01b815260040160405180910390fd5b5f858152600a602052604090206002815460ff166003811115610e1b57610e1b6136a6565b14610e3957604051634f4b461f60e11b815260040160405180910390fd5b60058101546001600160a01b0386165f908152600a8301602052604090205463ffffffff909116925060019060ff166002811115610e7957610e796136a6565b14610e8957600b01549150610f66565b6001600160a01b0385165f908152600a820160205260408120805460ff19166002179055600b8201805491610ebd83613669565b919050555080600b01549250846001600160a01b0316867f6c783b92374361b4d6efaf29673b89437ee969bb3c9d2d5d86b143ad5447b8498686604051610f0e929190918252602082015260400190565b60405180910390a36040805184815263ffffffff84166020820181905285101591810182905287907f119cb11dd0a68c257d6dc9b06dcb37dd422ce276eb8bf3cd0b7079a116b8e2989060600160405180910390a250505b935093915050565b610f766110ac565b6001600160a01b0316336001600160a01b03161480610f9f57506001546001600160a01b031633145b610fbc57604051632864c4e160e01b815260040160405180910390fd5b610fc5816110da565b6110a95760048054600160281b900464ffffffffff1690610fef906001600160a01b038416611f71565b6001600160a01b0382165f908152600660209081526040808320805460ff1916600117905560079091528120805464ffffffffff841664ffffffffff199091161790556002805491611040836136ba565b90915550506002546004546040805164ffffffffff80861682526020820194909452600160281b909204909216918101919091526001600160a01b038316907f3318d261fe14a5761d2d1e21555652f623d2134c430a9883c9ad6e958bb0db53906060016107b2565b50565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03165f9081526006602052604090205460ff1690565b5f818152600a6020526040902060048101546060919061112a576040516322e679e360e11b815260040160405180910390fd5b8060060180548060200260200160405190810160405280929190818152602001828054801561118057602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611162575b5050505050915050919050565b5f805f848152600a602081815260408084206001600160a01b0388168552909201905290205460ff1660028111156111c7576111c76136a6565b14159392505050565b6111d8611ecf565b6001600160a01b0381166111ff5760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f4ccc8ed483c7c44c3602c3c38afc2c014a8f1d2dc210dfe58ebeeeead230f8e0905f90a250565b5f868152600a602052604090206002815460ff16600381111561126d5761126d6136a6565b1461128b57604051634f4b461f60e11b815260040160405180910390fd5b6004810154156112ae5760405163632a22bb60e01b815260040160405180910390fd5b836112f35760405162461bcd60e51b81526020600482015260156024820152741c1ad0dbdb5b5a5d1b595b9d081c995c5d5a5c9959605a1b60448201526064016106e9565b5f61130082600601612147565b600783018190555f805460405163101bb4d760e21b8152600481018c905292935090916001600160a01b039091169063406ed35c906024015f60405180830381865afa158015611352573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261137991908101906138e7565b9050806101c001511561147a57836113c45760405162461bcd60e51b815260206004820152600e60248201526d1c1c9bdbd9881c995c5d5a5c995960921b60448201526064016106e9565b8061012001516001600160a01b031663de12c640878488886040518563ffffffff1660e01b81526004016113fb9493929190613a6d565b602060405180830381865afa158015611416573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143a9190613787565b61147a5760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2102225a390383937b7b360791b60448201526064016106e9565b60048381018790555f8a815260096020526040808220899055905490516340a3b76160e11b81529182018b9052602482018890526001600160a01b0316906381476ec2906044015f604051808303815f87803b1580156114d8575f5ffd5b505af11580156114ea573d5f5f3e3d5ffd5b50505050887fbf0636a312095f6c09c909823813b50e392323588d2d83432e7512c64041e67f846006018a8a8a8a8a60405161152b96959493929190613ad2565b60405180910390a2505050505050505050565b5f6115476121a8565b805490915060ff600160401b82041615906001600160401b03165f8115801561156d5750825b90505f826001600160401b031660011480156115885750303b155b905081158015611596575080155b156115b45760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156115de57845460ff60401b1916600160401b1785555b6001600160a01b0387166116055760405163d92e233d60e01b815260040160405180910390fd5b61160e336121d0565b61161a600460146121e1565b611623866107f7565b61162b6110ac565b6001600160a01b0316876001600160a01b03161461164c5761164c87611bf3565b831561169257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f818152600a6020526040812081815460ff1660038111156116bf576116bf6136a6565b036116dd57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff1660038111156116f5576116f56136a6565b1461171357604051631860f69960e31b815260040160405180910390fd5b8060030154421161173757604051632f021e8d60e11b815260040160405180910390fd5b60058101546006820154600160201b90910463ffffffff1611158061181c578154600360ff199091161782556006820154600583015460408051928352600160201b90910463ffffffff16602083015285917fecc4a9fb7e28d074cba7f5b227e9b5827823c850a385539b9a2f98a08f8c203d910160405180910390a25f54604051635d968dc160e11b815260048101869052600260248201526001600160a01b039091169063bb2d1b82906044015f604051808303815f87803b1580156117fd575f5ffd5b505af115801561180f573d5f5f3e3d5ffd5b505f979650505050505050565b815460ff191660021782556006820154600b83018190555f816001600160401b0381111561184c5761184c61367e565b604051908082528060200260200182016040528015611875578160200160208202803683370190505b5090505f5b828110156118e757846009015f86600601838154811061189c5761189c613692565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205482518390839081106118d4576118d4613692565b602090810291909101015260010161187a565b505f54604051631f3ea75d60e21b8152600481018890526001600160a01b0390911690637cfa9d74906024015f604051808303815f87803b15801561192a575f5ffd5b505af115801561193c573d5f5f3e3d5ffd5b50505050857f4f1f5b329c741a8ba15e9645e301061294d0c1fdd455448ffd5e76ff255929d78560060183604051610bf5929190613b1f565b61197d611ecf565b6001600160a01b0381166119a45760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517fad4055f18cdad6f4bdd71afe3a72cbeee964217943e1bde38f138289e981a9a7905f90a250565b5f828152600a6020526040812090815460ff166003811115611a1157611a116136a6565b03611a2f57604051630d4c1d9760e41b815260040160405180910390fd5b6001815460ff166003811115611a4757611a476136a6565b14611a6557604051631860f69960e31b815260040160405180910390fd5b8060030154421115611a8a57604051639a19114d60e01b815260040160405180910390fd5b335f90815260088201602052604090205460ff1615611abc5760405163257309f160e11b815260040160405180910390fd5b611ac533610c09565b611ae25760405163149fbcfd60e11b815260040160405180910390fd5b611aed338385612260565b6001810154604080516bffffffffffffffffffffffff193360601b16602080830191909152603482018690526054820187905260748083019490945282518083039094018452609490910190915281519101205f90335f8181526008850160205260409020805460ff19166001179055909150611b6c90839083612431565b506040805184815260208101839052339186917f52999628fb1cb05707e842278833b22e511f11746202cecdf221968b0b89e8bd910160405180910390a350505050565b5f8181526009602052604090205480611bdc576040516322e679e360e11b815260040160405180910390fd5b919050565b5f611bee60046014612632565b905090565b611bfb611ecf565b6001600160a01b038116611c24575f604051631e4fbdf760e01b81526004016106e99190613521565b6110a981611f01565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611c6c5760405162461bcd60e51b81526004016106e990613b31565b825464ffffffffff600160281b90910481169082168111611cca5760405162461bcd60e51b815260206004820152601860248201527713185e9e5253550e881b195859881b5d5cdd08195e1a5cdd60421b60448201526064016106e9565b825f5b81866001015f611cdd848861272b565b64ffffffffff1681526020019081526020015f20819055505f816001611d039190613b7b565b60ff168464ffffffffff16901c64ffffffffff16905060018564ffffffffff16901c64ffffffffff168111611d385750611ec7565b600185165f03611dff575f611d5783611d52886001613b94565b61272b565b60408051808201825286815264ffffffffff83165f90815260018c0160209081529083902054908201529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611db891600401613bb1565b602060405180830381865af4158015611dd3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611df791906136d2565b935050611eb3565b5f611e0f83611d52600189613be1565b60408051808201825264ffffffffff83165f90815260018c0160209081529083902054825281018790529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe91611e7091600401613bb1565b602060405180830381865af4158015611e8b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eaf91906136d2565b9350505b50647fffffffff600194851c169301611ccd565b505050505050565b33611ed86110ac565b6001600160a01b031614610dc5573360405163118cdaa760e01b81526004016106e99190613521565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b8154600160281b900464ffffffffff167f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018210611fc05760405162461bcd60e51b81526004016106e990613b31565b825464ffffffffff908116908216106120135760405162461bcd60e51b815260206004820152601560248201527413185e9e5253550e881d1c9959481a5cc8199d5b1b605a1b60448201526064016106e9565b61201e816001613b94565b835464ffffffffff91909116600160281b0269ffffffffff000000000019909116178355815f5b81856001015f612055848761272b565b64ffffffffff16815260208101919091526040015f20556001831615612140575f61208582611d52600187613be1565b60408051808201825264ffffffffff83165f90815260018a0160209081529083902054825281018690529051632b0aac7f60e11b815291925073__$078c82ddf6c95d34ea184ef1dd6130d136$__9163561558fe916120e691600401613bb1565b602060405180830381865af4158015612101573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061212591906136d2565b647fffffffff600195861c1694909350919091019050612045565b5050505050565b5f610cb68280548060200260200160405190810160405280929190818152602001828054801561219e57602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311612180575b5050505050612748565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610cb6565b6121d8612777565b6110a98161279c565b602060ff8216111561222f5760405162461bcd60e51b81526020600482015260176024820152764c617a79494d543a205472656520746f6f206c6172676560481b60448201526064016106e9565b612240600160ff831681901b613bfe565b825469ffffffffffffffffffff191664ffffffffff919091161790915550565b5f82116122805760405163aeaddff160e01b815260040160405180910390fd5b6001546001600160a01b03166122a9576040516350ca893360e01b815260040160405180910390fd5b5f818152600a602052604081206001805460028301549293926001600160a01b039091169163bb03bd719188916122df91613bfe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015612326573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061234a91906136d2565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b0316631209b1f66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561239d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123c191906136d2565b90505f81116123e35760405163aeaddff160e01b815260040160405180910390fd5b5f6123ee8284613c11565b90505f81116124105760405163149fbcfd60e11b815260040160405180910390fd5b808611156116925760405163aeaddff160e01b815260040160405180910390fd5b60058301546006840180545f92600160201b900463ffffffff16908111156124af57508054600180820183555f928352602080842090920180546001600160a01b0319166001600160a01b03881690811790915583526009870182526040808420869055600a88019092529120805460ff191682179055905061262b565b5f5f90505f876009015f855f815481106124cb576124cb613692565b5f9182526020808320909101546001600160a01b03168352820192909252604001902054905060015b8454811015612553575f896009015f87848154811061251557612515613692565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205490508281111561254a578092508193505b506001016124f4565b50808610612567575f94505050505061262b565b5f88600a015f86858154811061257f5761257f613692565b5f9182526020808320909101546001600160a01b031683528201929092526040019020805460ff191660018360028111156125bc576125bc6136a6565b0217905550868483815481106125d4576125d4613692565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918916815260098a0182526040808220899055600a8b0190925220805460ff191660019081179091559450505050505b9392505050565b5f5f8260ff16116126855760405162461bcd60e51b815260206004820152601a60248201527f4c617a79494d543a206465707468206d757374206265203e203000000000000060448201526064016106e9565b602060ff831611156126a95760405162461bcd60e51b81526004016106e990613c30565b8254600160281b900464ffffffffff16806126c860ff85166002613d81565b64ffffffffff1610156127185760405162461bcd60e51b8152602060048201526018602482015277098c2f4f2929aa87440c2dac4d2ceeadeeae640c8cae0e8d60431b60448201526064016106e9565b6127238482856127a4565b949350505050565b5f8161273e60ff851663ffffffff613d9a565b61262b9190613b94565b5f8160405160200161275a9190613dc1565b604051602081830303815290604052805190602001209050919050565b61277f61286c565b610dc557604051631afcd79f60e31b815260040160405180910390fd5b611bfb612777565b5f602060ff831611156127c95760405162461bcd60e51b81526004016106e990613c30565b8264ffffffffff165f036127e7576127e082612885565b905061262b565b5f6127f3836001613b7b565b60ff166001600160401b0381111561280d5761280d61367e565b604051908082528060200260200182016040528015612836578160200160208202803683370190505b50905061284585858584612f1f565b808360ff168151811061285a5761285a613692565b60200260200101519150509392505050565b5f6128756121a8565b54600160401b900460ff16919050565b5f8160ff165f0361289757505f919050565b8160ff166001036128c957507f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864919050565b8160ff166002036128fb57507f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1919050565b8160ff1660030361292d57507f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238919050565b8160ff1660040361295f57507f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a919050565b8160ff1660050361299157507f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55919050565b8160ff166006036129c357507f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78919050565b8160ff166007036129f557507f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d919050565b8160ff16600803612a2757507f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61919050565b8160ff16600903612a5957507f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747919050565b8160ff16600a03612a8b57507f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2919050565b8160ff16600b03612abd57507f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636919050565b8160ff16600c03612aef57507f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a919050565b8160ff16600d03612b2157507f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0919050565b8160ff16600e03612b5357507f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c919050565b8160ff16600f03612b8557507f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92919050565b8160ff16601003612bb757507f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba7323919050565b8160ff16601103612be957507f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b992919050565b8160ff16601203612c1b57507f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f919050565b8160ff16601303612c4d57507f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca919050565b8160ff16601403612c7f57507f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e919050565b8160ff16601503612cb157507f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b1919050565b8160ff16601603612ce357507f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b919050565b8160ff16601703612d1557507f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d919050565b8160ff16601803612d4757507f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed540919050565b8160ff16601903612d7957507f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae21919050565b8160ff16601a03612dab57507f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce611518919050565b8160ff16601b03612ddd57507f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d279483795919050565b8160ff16601c03612e0f57507f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d2919050565b8160ff16601d03612e4157507f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d919050565b8160ff16601e03612e7357507f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef919050565b8160ff16601f03612ea557507f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff2919050565b8160ff16602003612ed757507f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead9919050565b60405162461bcd60e51b815260206004820152601e60248201527f4c617a79494d543a2064656661756c745a65726f2062616420696e646578000060448201526064016106e9565b602060ff83161115612f435760405162461bcd60e51b81526004016106e990613c30565b5f8364ffffffffff1611612fa75760405162461bcd60e51b815260206004820152602560248201527f4c617a79494d543a206e756d626572206f66206c6561766573206d7573742062604482015264065203e20360dc1b60648201526084016106e9565b5f612fb3600185613be1565b9050600181165f0361300657846001015f612fce5f8461272b565b64ffffffffff1681526020019081526020015f2054825f81518110612ff557612ff5613692565b60200260200101818152505061302e565b61300f5f612885565b825f8151811061302157613021613692565b6020026020010181815250505b5f5b8360ff168160ff161015611ec757600182165f036131265773__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280868560ff168151811061308257613082613692565b6020026020010151815260200161309885612885565b8152506040518263ffffffff1660e01b81526004016130b79190613bb1565b602060405180830381865af41580156130d2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130f691906136d2565b83613102836001613b7b565b60ff168151811061311557613115613692565b6020026020010181815250506132d7565b5f613132826001613b7b565b60ff168664ffffffffff16901c64ffffffffff16905060018364ffffffffff16901c64ffffffffff168111156131d4575f876001015f6131898560016131789190613b7b565b60018864ffffffffff16901c61272b565b64ffffffffff1681526020019081526020015f2054905080858460016131af9190613b7b565b60ff16815181106131c2576131c2613692565b602002602001018181525050506132d5565b5f876001015f6131eb85600188611d529190613be1565b64ffffffffff1681526020019081526020015f2054905073__$078c82ddf6c95d34ea184ef1dd6130d136$__63561558fe6040518060400160405280848152602001888760ff168151811061324257613242613692565b60200260200101518152506040518263ffffffff1660e01b81526004016132699190613bb1565b602060405180830381865af4158015613284573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132a891906136d2565b856132b4856001613b7b565b60ff16815181106132c7576132c7613692565b602002602001018181525050505b505b647fffffffff600192831c169101613030565b60018301918390821561337b579160200282015f5b8382111561334957833563ffffffff1683826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026132ff565b80156133795782816101000a81549063ffffffff0219169055600401602081600301049283019260010302613349565b505b5061338792915061338b565b5090565b5b80821115613387575f815560010161338c565b6001600160a01b03811681146110a9575f5ffd5b5f602082840312156133c3575f5ffd5b813561262b8161339f565b5f602082840312156133de575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561341e5781516001600160a01b03168652602095860195909101906001016133f7565b5093949350505050565b5f8151808452602084019350602083015f5b8281101561341e57815186526020958601959091019060010161343a565b604081525f61346a60408301856133e5565b828103602084015261347c8185613428565b95945050505050565b5f5f5f60808486031215613497575f5ffd5b8335925060208401359150608084018510156134b1575f5ffd5b6040840190509250925092565b5f5f604083850312156134cf575f5ffd5b8235915060208301356134e18161339f565b809150509250929050565b5f5f5f606084860312156134fe575f5ffd5b8335925060208401356135108161339f565b929592945050506040919091013590565b6001600160a01b0391909116815260200190565b602081525f61262b60208301846133e5565b5f5f83601f840112613557575f5ffd5b5081356001600160401b0381111561356d575f5ffd5b602083019150836020828501011115613584575f5ffd5b9250929050565b5f5f5f5f5f5f608087890312156135a0575f5ffd5b8635955060208701356001600160401b038111156135bc575f5ffd5b6135c889828a01613547565b9096509450506040870135925060608701356001600160401b038111156135ed575f5ffd5b6135f989828a01613547565b979a9699509497509295939492505050565b5f5f6040838503121561361c575f5ffd5b82356136278161339f565b946020939093013593505050565b5f5f60408385031215613646575f5ffd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f8161367757613677613655565b505f190190565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f600182016136cb576136cb613655565b5060010190565b5f602082840312156136e2575f5ffd5b5051919050565b803563ffffffff81168114611bdc575f5ffd5b5f6020828403121561370c575f5ffd5b61262b826136e9565b80820180821115610cb657610cb6613655565b84815260a0810160208201855f5b60028110156137635763ffffffff61374d836136e9565b1683526020928301929190910190600101613736565b50505060608201939093526080015292915050565b80518015158114611bdc575f5ffd5b5f60208284031215613797575f5ffd5b61262b82613778565b6040516101e081016001600160401b03811182821017156137c3576137c361367e565b60405290565b805160048110611bdc575f5ffd5b5f82601f8301126137e6575f5ffd5b604080519081016001600160401b03811182821017156138085761380861367e565b806040525080604084018581111561381e575f5ffd5b845b81811015613838578051835260209283019201613820565b509195945050505050565b8051611bdc8161339f565b805160ff81168114611bdc575f5ffd5b5f82601f83011261386d575f5ffd5b81516001600160401b038111156138865761388661367e565b604051601f8201601f19908116603f011681016001600160401b03811182821017156138b4576138b461367e565b6040528181528382016020018510156138cb575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f602082840312156138f7575f5ffd5b81516001600160401b0381111561390c575f5ffd5b8201610200818503121561391e575f5ffd5b6139266137a0565b81518152613936602083016137c9565b60208201526040828101519082015261395285606084016137d7565b606082015260a0820151608082015261396d60c08301613843565b60a082015261397e60e0830161384e565b60c08201526101008201516001600160401b0381111561399c575f5ffd5b6139a88682850161385e565b60e0830152506139bb6101208301613843565b6101008201526139ce6101408301613843565b61012082015261016082810151610140830152610180830151908201526101a08201516001600160401b03811115613a04575f5ffd5b613a108682850161385e565b61018083015250613a246101c08301613843565b6101a0820152613a376101e08301613778565b6101c0820152949350505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b848152836020820152606060408201525f613a8c606083018486613a45565b9695505050505050565b5f8154808452602084019350825f5260205f205f5b8281101561341e5781546001600160a01b0316865260209095019460019182019101613aab565b608081525f613ae46080830189613a96565b8281036020840152613af781888a613a45565b90508560408401528281036060840152613b12818587613a45565b9998505050505050505050565b604081525f61346a6040830185613a96565b6020808252602a908201527f4c617a79494d543a206c656166206d757374206265203c20534e41524b5f53436040820152691053105497d19251531160b21b606082015260800190565b60ff8181168382160190811115610cb657610cb6613655565b64ffffffffff8181168382160190811115610cb657610cb6613655565b6040810181835f5b6002811015613bd8578151835260209283019290910190600101613bb9565b50505092915050565b64ffffffffff8281168282160390811115610cb657610cb6613655565b81810381811115610cb657610cb6613655565b5f82613c2b57634e487b7160e01b5f52601260045260245ffd5b500490565b60208082526023908201527f4c617a79494d543a206465707468206d757374206265203c3d204d41585f44456040820152620a0a8960eb1b606082015260800190565b6001815b6001841115610f6657808504811115613c9257613c92613655565b6001841615613ca057908102905b60019390931c928002613c77565b5f82613cbc57506001610cb6565b81613cc857505f610cb6565b8160018114613cde5760028114613ce857613d1a565b6001915050610cb6565b60ff841115613cf957613cf9613655565b6001841b915064ffffffffff821115613d1457613d14613655565b50610cb6565b5060208310610133831016604e8410600b8410161715613d52575081810a64ffffffffff811115613d4d57613d4d613655565b610cb6565b613d6264ffffffffff8484613c73565b8064ffffffffff04821115613d7957613d79613655565b029392505050565b5f61262b64ffffffffff841664ffffffffff8416613cae565b64ffffffffff8181168382160290811690818114613dba57613dba613655565b5092915050565b81515f90829060208501835b828110156138385781516001600160a01b0316845260209384019390910190600101613dcd56fea164736f6c634300081c000a", "linkReferences": { "npm/poseidon-solidity@0.0.5/PoseidonT3.sol": { "PoseidonT3": [ { "length": 20, - "start": 7752 + "start": 7784 }, { "length": 20, - "start": 7936 + "start": 7968 }, { "length": 20, - "start": 8566 + "start": 8598 }, { "length": 20, - "start": 12400 + "start": 12576 }, { "length": 20, - "start": 12842 + "start": 13018 } ] } @@ -1316,28 +1330,28 @@ "PoseidonT3": [ { "length": 20, - "start": 7538 + "start": 7570 }, { "length": 20, - "start": 7722 + "start": 7754 }, { "length": 20, - "start": 8352 + "start": 8384 }, { "length": 20, - "start": 12186 + "start": 12362 }, { "length": 20, - "start": 12628 + "start": 12804 } ] } }, "immutableReferences": {}, "inputSourceName": "project/contracts/registry/CiphernodeRegistryOwnable.sol", - "buildInfoId": "solc-0_8_28-2705a75bc2d2d1f8b1e08ebca4cc37d76480abc8" + "buildInfoId": "solc-0_8_28-23df357f03d1ab6ff0a7509a32ecf84190997859" } \ No newline at end of file diff --git a/packages/enclave-contracts/contracts/Enclave.sol b/packages/enclave-contracts/contracts/Enclave.sol index b469cb097c..ac806dfce1 100644 --- a/packages/enclave-contracts/contracts/Enclave.sol +++ b/packages/enclave-contracts/contracts/Enclave.sol @@ -419,8 +419,13 @@ contract Enclave is IEnclave, OwnableUpgradeable { if (e3.proofAggregationEnabled) { require(proof.length > 0, ProofRequired()); + // Reaching `CiphertextReady` implies the committee was published, so + // `getCommitteeHash` is guaranteed non-zero here; the registry still + // reverts with `CommitteeNotPublished` if that invariant ever breaks. + bytes32 committeeHash = ciphernodeRegistry.getCommitteeHash(e3Id); success = e3.decryptionVerifier.verify( keccak256(plaintextOutput), + committeeHash, proof ); require(success, InvalidOutput(plaintextOutput)); diff --git a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol index aa574cf1f5..310b1b5084 100644 --- a/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/interfaces/ICiphernodeRegistry.sol @@ -38,6 +38,7 @@ interface ICiphernodeRegistry { /// @param publicKey Hash of the committee's public key. /// @param seed The seed for the round. /// @param topNodes Sorted top-N nodes selected during sortition. + /// @param committeeHash `keccak256(abi.encodePacked(topNodes))`, set at publication. /// @param submitted Mapping of nodes to their submission status. /// @param scoreOf Mapping of nodes to their scores. /// @param memberStatus Tri-state membership tracking (None / Active / Expelled). @@ -49,6 +50,7 @@ interface ICiphernodeRegistry { bytes32 publicKey; uint32[2] threshold; address[] topNodes; + bytes32 committeeHash; mapping(address node => bool submitted) submitted; mapping(address node => uint256 score) scoreOf; mapping(address node => MemberStatus) memberStatus; @@ -209,6 +211,15 @@ interface ICiphernodeRegistry { /// @notice Committee has not been finalized yet for this E3 error CommitteeNotFinalized(); + /// @notice `publishCommittee` requires a non-zero PK commitment + error PkCommitmentRequired(); + + /// @notice Proof aggregation is enabled but no DKG proof was supplied + error DkgProofRequired(); + + /// @notice Supplied DKG aggregator proof failed verification + error InvalidDkgProof(); + /// @notice Node has already submitted a ticket for this E3 error NodeAlreadySubmitted(); @@ -304,14 +315,12 @@ interface ICiphernodeRegistry { /// `pkCommitment` via the E3's pk verifier. When disabled, `proof` may be empty /// and `pkCommitment` is trusted from the (signed) aggregator. /// @param e3Id ID of the E3 for which to select the committee. - /// @param nodes Array of ciphernode addresses selected for the committee. /// @param publicKey The public key generated by the given committee. /// @param pkCommitment Hash-based aggregated PK commitment for the committee. /// @param proof DkgAggregator (EVM) proof ABI-encoded `(bytes rawProof, bytes32[] publicInputs)`, /// or empty bytes when proof aggregation is disabled. function publishCommittee( uint256 e3Id, - address[] calldata nodes, bytes calldata publicKey, bytes32 pkCommitment, bytes calldata proof @@ -334,6 +343,13 @@ interface ICiphernodeRegistry { uint256 e3Id ) external view returns (address[] memory committeeNodes); + /// @notice Returns the committee hash cached at `publishCommittee` time. + /// @param e3Id ID of the E3 + /// @return committeeHash `keccak256(abi.encodePacked(topNodes))` for the published committee + function getCommitteeHash( + uint256 e3Id + ) external view returns (bytes32 committeeHash); + /// @notice Returns the current root of the ciphernode IMT /// @return Current IMT root function root() external view returns (uint256); diff --git a/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol b/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol index 1519032e3e..b52efb6b41 100644 --- a/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/interfaces/IDecryptionVerifier.sol @@ -13,12 +13,14 @@ pragma solidity 0.8.28; * needs to verify the final EVM proof and bind it to the claimed plaintext. */ interface IDecryptionVerifier { - /// @notice Verify a DecryptionAggregator EVM proof and bind it to `plaintextOutputHash`. + /// @notice Verify a DecryptionAggregator EVM proof and bind it to `plaintextOutputHash` and `committeeHash`. /// @param plaintextOutputHash `keccak256(plaintextOutput)` expected by the Enclave. + /// @param committeeHash `keccak256(abi.encodePacked(topNodes))` for the on-chain committee. /// @param proof ABI-encoded `(bytes rawProof, bytes32[] publicInputs)`. - /// @return success True if the proof is valid and its embedded plaintext matches `plaintextOutputHash`. + /// @return success True if the proof is valid and bound to `plaintextOutputHash` and `committeeHash`. function verify( bytes32 plaintextOutputHash, + bytes32 committeeHash, bytes calldata proof ) external view returns (bool success); } diff --git a/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol b/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol index 98c3c76671..7984851c6b 100644 --- a/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol +++ b/packages/enclave-contracts/contracts/interfaces/IPkVerifier.sol @@ -14,13 +14,15 @@ pragma solidity 0.8.28; * matches the committee's aggregated public-key commitment. */ interface IPkVerifier { - /// @notice Verify a DkgAggregator EVM proof and bind it to `pkCommitment`. + /// @notice Verify a DkgAggregator EVM proof and bind it to `pkCommitment` and `committeeHash`. /// @param pkCommitment Hash-based aggregated PK commitment the proof must attest to /// (equals `publicInputs[publicInputs.length - 1]`). + /// @param committeeHash `keccak256(abi.encodePacked(topNodes))` for the on-chain committee. /// @param proof ABI-encoded `(bytes rawProof, bytes32[] publicInputs)`. - /// @return success True if the proof is valid and its last public input equals `pkCommitment`. + /// @return success True if the proof is valid and bound to `pkCommitment` and `committeeHash`. function verify( bytes32 pkCommitment, + bytes32 committeeHash, bytes calldata proof ) external view returns (bool success); } diff --git a/packages/enclave-contracts/contracts/lib/CommitteeHashLib.sol b/packages/enclave-contracts/contracts/lib/CommitteeHashLib.sol new file mode 100644 index 0000000000..9d72a15f53 --- /dev/null +++ b/packages/enclave-contracts/contracts/lib/CommitteeHashLib.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +pragma solidity 0.8.28; + +/** + * @title CommitteeHashLib + * @notice Canonical `keccak256(abi.encodePacked(topNodes))` binding for aggregator proofs. + * @dev Must match `e3_utils::committee_hash` (hi/lo split into two 128-bit limbs). + */ +library CommitteeHashLib { + uint256 private constant _LO_MASK = (uint256(1) << 128) - 1; + + /// @notice `keccak256(abi.encodePacked(nodes))` for the ordered on-chain committee. + /// @dev Callers pass `storage` arrays via implicit copy to this `memory` parameter. + function hash(address[] memory nodes) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(nodes)); + } + + /// @notice High 128 bits of a committee hash (Noir public input `committee_hash_hi`). + function hi(bytes32 committeeHash) internal pure returns (bytes32) { + return bytes32(uint256(committeeHash) >> 128); + } + + /// @notice Low 128 bits of a committee hash (Noir public input `committee_hash_lo`). + function lo(bytes32 committeeHash) internal pure returns (bytes32) { + return bytes32(uint256(committeeHash) & _LO_MASK); + } +} diff --git a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol index 15fb028bba..0773230d8a 100644 --- a/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol +++ b/packages/enclave-contracts/contracts/registry/CiphernodeRegistryOwnable.sol @@ -17,6 +17,7 @@ import { InternalLazyIMT, LazyIMTData } from "@zk-kit/lazy-imt.sol/InternalLazyIMT.sol"; +import { CommitteeHashLib } from "../lib/CommitteeHashLib.sol"; /** * @title CiphernodeRegistryOwnable @@ -195,7 +196,6 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { /// @inheritdoc ICiphernodeRegistry function publishCommittee( uint256 e3Id, - address[] calldata nodes, bytes calldata publicKey, bytes32 pkCommitment, bytes calldata proof @@ -207,15 +207,17 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { CommitteeNotFinalized() ); require(c.publicKey == bytes32(0), CommitteeAlreadyPublished()); - require(nodes.length == c.topNodes.length, "Node count mismatch"); - require(pkCommitment != bytes32(0), "pkCommitment required"); + require(pkCommitment != bytes32(0), PkCommitmentRequired()); + + bytes32 committeeHash = CommitteeHashLib.hash(c.topNodes); + c.committeeHash = committeeHash; E3 memory e3 = enclave.getE3(e3Id); if (e3.proofAggregationEnabled) { - require(proof.length > 0, "proof required"); + require(proof.length > 0, DkgProofRequired()); require( - e3.pkVerifier.verify(pkCommitment, proof), - "Invalid DKG proof" + e3.pkVerifier.verify(pkCommitment, committeeHash, proof), + InvalidDkgProof() ); } @@ -224,7 +226,13 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { enclave.onCommitteePublished(e3Id, pkCommitment); - emit CommitteePublished(e3Id, nodes, publicKey, pkCommitment, proof); + emit CommitteePublished( + e3Id, + c.topNodes, + publicKey, + pkCommitment, + proof + ); } /// @inheritdoc ICiphernodeRegistry @@ -464,6 +472,15 @@ contract CiphernodeRegistryOwnable is ICiphernodeRegistry, OwnableUpgradeable { nodes = c.topNodes; } + /// @inheritdoc ICiphernodeRegistry + function getCommitteeHash( + uint256 e3Id + ) public view returns (bytes32 committeeHash) { + Committee storage c = committees[e3Id]; + require(c.publicKey != bytes32(0), CommitteeNotPublished()); + committeeHash = c.committeeHash; + } + /// @notice Returns the current size of the ciphernode IMT /// @return Size of the IMT function treeSize() public view returns (uint256) { diff --git a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol index 558927152d..d6c8bb6f8a 100644 --- a/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol +++ b/packages/enclave-contracts/contracts/test/MockCiphernodeRegistry.sol @@ -68,7 +68,6 @@ contract MockCiphernodeRegistry is ICiphernodeRegistry { function publishCommittee( uint256, - address[] calldata, bytes calldata, bytes32, bytes calldata @@ -80,6 +79,10 @@ contract MockCiphernodeRegistry is ICiphernodeRegistry { return _committeeNodes[e3Id]; } + function getCommitteeHash(uint256 e3Id) external view returns (bytes32) { + return keccak256(abi.encodePacked(_committeeNodes[e3Id])); + } + function root() external pure returns (uint256) { return 0; } @@ -209,7 +212,6 @@ contract MockCiphernodeRegistryEmptyKey is ICiphernodeRegistry { function publishCommittee( uint256, - address[] calldata, bytes calldata, bytes32, bytes calldata @@ -222,6 +224,10 @@ contract MockCiphernodeRegistryEmptyKey is ICiphernodeRegistry { return nodes; } + function getCommitteeHash(uint256) external pure returns (bytes32) { + return bytes32(0); + } + function root() external pure returns (uint256) { return 0; } diff --git a/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol b/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol index 6b8ed8b999..b55542f71f 100644 --- a/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/test/MockDecryptionVerifier.sol @@ -13,6 +13,7 @@ contract MockDecryptionVerifier is IDecryptionVerifier { bytes4 private constant _FAIL_MAGIC = 0xdeadbeef; function verify( + bytes32, bytes32, bytes calldata proof ) external pure returns (bool success) { diff --git a/packages/enclave-contracts/contracts/test/MockPkVerifier.sol b/packages/enclave-contracts/contracts/test/MockPkVerifier.sol index bd54d16ab4..d96359c950 100644 --- a/packages/enclave-contracts/contracts/test/MockPkVerifier.sol +++ b/packages/enclave-contracts/contracts/test/MockPkVerifier.sol @@ -10,6 +10,7 @@ import { IPkVerifier } from "../interfaces/IPkVerifier.sol"; contract MockPkVerifier is IPkVerifier { function verify( bytes32 pkCommitment, + bytes32, bytes calldata proof ) external pure returns (bool) { (, bytes32[] memory publicInputs) = abi.decode( diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol index c572c09498..579ffae4f9 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol @@ -7,21 +7,43 @@ pragma solidity 0.8.28; import { IDecryptionVerifier } from "../../interfaces/IDecryptionVerifier.sol"; import { ICircuitVerifier } from "../../interfaces/ICircuitVerifier.sol"; +import { CommitteeHashLib } from "../../lib/CommitteeHashLib.sol"; /** * @title BfvDecryptionVerifier * @notice Verifies the DecryptionAggregator (EVM) proof produced by the * recursive aggregation pipeline (C6 folds + C7/decrypted_shares * verified internally). Binds the proof to the claimed - * `plaintextOutputHash`. + * `plaintextOutputHash` and on-chain committee hash. * @dev Used when the Enclave is configured with encryptionSchemeId * keccak256("fhe.rs:BFV"). The plaintext is exposed as the last * `MESSAGE_COEFFS_COUNT` public inputs, matching * `MAX_MSG_NON_ZERO_COEFFS` in the decryption_aggregator circuit. + * Constructor `threshold` must match the compiled circuit `T` + * (`lib::configs::default::T`). Committee hash limbs are always at + * indices 2 and 3; total public-input length is preset-dependent. */ contract BfvDecryptionVerifier is IDecryptionVerifier { /// @dev Message is always the last 100 public inputs (100 uint64 coeffs = 800 bytes plaintext). - uint256 constant MESSAGE_COEFFS_COUNT = 100; + uint256 internal constant MESSAGE_COEFFS_COUNT = 100; + + /// @dev `decryption_aggregator` return tail: `1 + 3*(T+1) + MESSAGE_COEFFS_COUNT` fields. + uint256 internal constant DEC_RETURN_PREFIX_LEN = 1; + + /// @dev `decryption_aggregator` return columns after the leading key hash (sk, esm, ct). + uint256 internal constant DEC_RETURN_COLUMN_COUNT = 3; + + /// @dev `publicInputs` index for `committee_hash_hi` (after sub-circuit key hashes). + uint256 internal constant COMMITTEE_HASH_HI_IDX = 2; + + /// @dev `publicInputs` index for `committee_hash_lo`. + uint256 internal constant COMMITTEE_HASH_LO_IDX = 3; + + /// @notice BFV threshold `T`; must match the compiled DecryptionAggregator circuit. + uint256 public immutable threshold; + + /// @dev `4 + DEC_RETURN_PREFIX_LEN + DEC_RETURN_COLUMN_COUNT*(T+1) + MESSAGE_COEFFS_COUNT`. + uint256 internal immutable expectedPublicInputsLen; /// @notice Underlying Honk verifier for the DecryptionAggregator circuit. ICircuitVerifier public immutable circuitVerifier; @@ -35,8 +57,17 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { constructor( address _circuitVerifier, bytes32 _expectedC6FoldKeyHash, - bytes32 _expectedC7KeyHash + bytes32 _expectedC7KeyHash, + uint256 _threshold ) { + require(_threshold > 0, "BfvDecryptionVerifier: threshold=0"); + threshold = _threshold; + expectedPublicInputsLen = + 4 + + DEC_RETURN_PREFIX_LEN + + (DEC_RETURN_COLUMN_COUNT * (_threshold + 1)) + + MESSAGE_COEFFS_COUNT; + circuitVerifier = ICircuitVerifier(_circuitVerifier); expectedC6FoldKeyHash = _expectedC6FoldKeyHash; expectedC7KeyHash = _expectedC7KeyHash; @@ -45,6 +76,7 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { /// @inheritdoc IDecryptionVerifier function verify( bytes32 plaintextOutputHash, + bytes32 committeeHash, bytes calldata proof ) external view override returns (bool) { (bytes memory rawProof, bytes32[] memory publicInputs) = abi.decode( @@ -52,7 +84,7 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { (bytes, bytes32[]) ); - if (publicInputs.length < MESSAGE_COEFFS_COUNT + 2) { + if (publicInputs.length != expectedPublicInputsLen) { return false; } if (publicInputs[0] != expectedC6FoldKeyHash) { @@ -61,6 +93,18 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { if (publicInputs[1] != expectedC7KeyHash) { return false; } + if ( + publicInputs[COMMITTEE_HASH_HI_IDX] != + CommitteeHashLib.hi(committeeHash) + ) { + return false; + } + if ( + publicInputs[COMMITTEE_HASH_LO_IDX] != + CommitteeHashLib.lo(committeeHash) + ) { + return false; + } if (!_verifyPlaintextHash(publicInputs, plaintextOutputHash)) { return false; } @@ -70,8 +114,8 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { function _verifyPlaintextHash( bytes32[] memory publicInputs, bytes32 plaintextOutputHash - ) internal pure returns (bool) { - uint256 offset = publicInputs.length - MESSAGE_COEFFS_COUNT; + ) internal view returns (bool) { + uint256 offset = expectedPublicInputsLen - MESSAGE_COEFFS_COUNT; bytes memory plaintext = new bytes(MESSAGE_COEFFS_COUNT * 8); for (uint256 i = 0; i < MESSAGE_COEFFS_COUNT; i++) { uint64 coeff = uint64(uint256(publicInputs[offset + i])); diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol index de5cb6a700..40f5aac8b5 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/BfvPkVerifier.sol @@ -7,17 +7,38 @@ pragma solidity 0.8.28; import { IPkVerifier } from "../../interfaces/IPkVerifier.sol"; import { ICircuitVerifier } from "../../interfaces/ICircuitVerifier.sol"; +import { CommitteeHashLib } from "../../lib/CommitteeHashLib.sol"; /** * @title BfvPkVerifier * @notice Verifies the DkgAggregator (EVM) proof produced by the recursive * aggregation pipeline (node folds + C5/pk_aggregation verified - * internally). Binds the proof to a caller-supplied `pkCommitment`. + * internally). Binds the proof to a caller-supplied `pkCommitment` + * and on-chain committee hash. * @dev Used when the Enclave is configured with encryptionSchemeId * keccak256("fhe.rs:BFV"). The aggregator circuit's last public input is - * the hash-based aggregated PK commitment. + * the hash-based aggregated PK commitment. Constructor `h` must match the + * compiled DkgAggregator honest-set size (`lib::configs::default::H`). */ contract BfvPkVerifier is IPkVerifier { + /// @dev `dkg_aggregator` return field count: `1 + H + H + 1` (key hash + two `H` arrays + pk commitment). + uint256 internal constant DKG_RETURN_TAIL_LEN = 2; + + /// @notice Honest-set size `H` (`party_ids` length); must match the compiled DkgAggregator circuit. + uint256 public immutable h; + + /// @dev `publicInputs` index for `committee_hash_hi` (after `party_ids`). + uint256 internal immutable committeeHashHiIdx; + + /// @dev `publicInputs` index for `committee_hash_lo`. + uint256 internal immutable committeeHashLoIdx; + + /// @dev `2 + H + 2 + (2*H + DKG_RETURN_TAIL_LEN)` for `dkg_aggregator` EVM public inputs. + uint256 internal immutable expectedPublicInputsLen; + + /// @dev Index of `pkCommitment` (last return field). + uint256 internal immutable pkCommitmentIdx; + /// @notice Underlying Honk verifier for the DkgAggregator circuit. ICircuitVerifier public immutable circuitVerifier; @@ -30,8 +51,16 @@ contract BfvPkVerifier is IPkVerifier { constructor( address _circuitVerifier, bytes32 _expectedNodesFoldKeyHash, - bytes32 _expectedC5KeyHash + bytes32 _expectedC5KeyHash, + uint256 _h ) { + require(_h > 0, "BfvPkVerifier: h=0"); + h = _h; + committeeHashHiIdx = 2 + _h; + committeeHashLoIdx = 3 + _h; + expectedPublicInputsLen = (3 * _h) + 6; + pkCommitmentIdx = expectedPublicInputsLen - 1; + circuitVerifier = ICircuitVerifier(_circuitVerifier); expectedNodesFoldKeyHash = _expectedNodesFoldKeyHash; expectedC5KeyHash = _expectedC5KeyHash; @@ -40,6 +69,7 @@ contract BfvPkVerifier is IPkVerifier { /// @inheritdoc IPkVerifier function verify( bytes32 pkCommitment, + bytes32 committeeHash, bytes calldata proof ) external view override returns (bool) { (bytes memory rawProof, bytes32[] memory publicInputs) = abi.decode( @@ -47,7 +77,7 @@ contract BfvPkVerifier is IPkVerifier { (bytes, bytes32[]) ); - if (publicInputs.length < 3) { + if (publicInputs.length != expectedPublicInputsLen) { return false; } if (publicInputs[0] != expectedNodesFoldKeyHash) { @@ -56,7 +86,19 @@ contract BfvPkVerifier is IPkVerifier { if (publicInputs[1] != expectedC5KeyHash) { return false; } - if (publicInputs[publicInputs.length - 1] != pkCommitment) { + if ( + publicInputs[committeeHashHiIdx] != + CommitteeHashLib.hi(committeeHash) + ) { + return false; + } + if ( + publicInputs[committeeHashLoIdx] != + CommitteeHashLib.lo(committeeHash) + ) { + return false; + } + if (publicInputs[pkCommitmentIdx] != pkCommitment) { return false; } return circuitVerifier.verify(rawProof, publicInputs); diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol index 8f26000969..110829355d 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol @@ -7,8 +7,8 @@ pragma solidity >=0.8.21; uint256 constant N = 2097152; uint256 constant LOG_N = 21; -uint256 constant NUMBER_OF_PUBLIC_INPUTS = 125; -uint256 constant VK_HASH = 0x06bd2790bd0ebcdac35c8a64701d3ac99c897bfb988d6a9fa2b1f07a6630a73c; +uint256 constant NUMBER_OF_PUBLIC_INPUTS = 127; +uint256 constant VK_HASH = 0x179aeedaf3c48066180561e127d73c1ffbabf175e47589b309ddec6b1cd679d3; library HonkVerificationKey { function loadVerificationKey() internal @@ -18,213 +18,213 @@ library HonkVerificationKey { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(2097152), logCircuitSize: uint256(21), - publicInputsSize: uint256(125), + publicInputsSize: uint256(127), ql: Honk.G1Point({ x: uint256( - 0x117c944457d4c445ea9296e8369c57035aaa6aa1a8d8961945b3265da72a31bd + 0x21b909972bfe373b93f74e8d1b23d4f9da2d359033f9bea3bfd0dff4b14583b7 ), y: uint256( - 0x1085aa2ad3f5c33ba5b8281d03fc61950c0efb18edf3ca4bbacab6dac95eecc9 + 0x00cca3f61b1c83f29f138790d10246931d7ac90c67f0868928a8f87f115bae3f ) }), qr: Honk.G1Point({ x: uint256( - 0x2167efafb6f18a256ec49ac455de2b906ff483dd58e50c27a3eb01c965527b58 + 0x282acc4814ca5bff02f14c4a58b751ecc70c1c01494610385bff82d9072bf548 ), y: uint256( - 0x0e3673e8a48e9d2cdb54886bbd28ad0dd56f51ef8cb5b5b8d0c0586df815f0a0 + 0x1d4bd882f21883ba61543964458224dbd4a53595d002e18c0db812390c45416c ) }), qo: Honk.G1Point({ x: uint256( - 0x0a0501c4ac048110cf75f2b20f9ffdcd9a68876fd2e5d222b64c7bcac4915773 + 0x1dd7761ff2c72c1af984fb53d1b3b42460c3323214a2d7dde42c62973d34198e ), y: uint256( - 0x06d4c7296e366ae470e2744f7c35c10a36205e875d76ff49b031643a34ca4b92 + 0x13040272a4c0bedcfdec2b313f9efe3ee9a0bbd5ca58d9432dc8d832127e99b0 ) }), q4: Honk.G1Point({ x: uint256( - 0x1cb87c34cda7588d707dfd9e5edc22aebcc4082a9a53bcd5cde3bee60468e8b0 + 0x174f2955dfa54bf68658a287d4658af6994ecd888993452c4c14f1c60871ce56 ), y: uint256( - 0x05ff1a3b7cee6850d9d747a8da9eded3048f5d04bc0e3bc9430691c03e1e27c2 + 0x0cda4ce133f1492a2f13a0e29c6df44b8e697f84e481f1b2dbf2d8d741be5e04 ) }), qm: Honk.G1Point({ x: uint256( - 0x202127ce81fb7649a03ec97775ca9fe2914220f389a449ddb636ba3d1176f3c3 + 0x22ac07bc4c7d102054ba8dc18954f43d66ed6c57ede3a78e5fe44e80ab26daff ), y: uint256( - 0x267b8e078201ba78546404fa94714a5dcf759d079c3979f0a5ee5c132be90b45 + 0x01a5cce0a2e3607ae4fc406e7379aed53d7cd2cdb0d3a14e759531cee30cb9ea ) }), qc: Honk.G1Point({ x: uint256( - 0x24252d386e1956c3f2eec5c2523dd7f1f00acab8486d728cda31a43a4c67ee03 + 0x11fee8c098df12a40892852407a771a7d280dbfbab5eeb06b23896095ca7a290 ), y: uint256( - 0x0bfc7d6c95dd2d204a8535c6c39293700dc0a10b7c436927ea67d06c5e092b47 + 0x17ec33cd33eacb4335ba2e0b3baffe2b0bd0f8371c7cf7213447d3ba6dd4ba6b ) }), qLookup: Honk.G1Point({ x: uint256( - 0x2f67e65f1cc76c010e87bd861eff857a592e08ada281645410d67488ce521499 + 0x13143d24a192079453fc93ca72b6be61609f4d042621b3d3973bfa341bb8a424 ), y: uint256( - 0x056e0fd959cdd56f2cb9d6d01440f7a5c2610ec3cb0efd64f856a119066366e9 + 0x2dee6429bc80fc94550da46393279fc6e08def2542d28bbc312a082f31e56409 ) }), qArith: Honk.G1Point({ x: uint256( - 0x0061573aad5b769a27e0a025f41dc6916969da4cb5e543584ab86b72c93e3014 + 0x2624d4d9d7eac2515cb4b322afc263ddc87c535791e2206eef64bc24024968e1 ), y: uint256( - 0x18285aff8bc7ed9f8cd1ea037443a178c0e77d7bae05c91613529a85717a5473 + 0x105a6a9c813245babf469aebeafca60e878d41b05f79125dedf362bee561b5ec ) }), qDeltaRange: Honk.G1Point({ x: uint256( - 0x11fe5aa4683da4b17c27c36019fd04b6c4daaf06d1138c136a82676d532e6897 + 0x1cec49a84cd964f7dccf24f37f746eb4660ffa446ba4e79d04582d86fc5fb2be ), y: uint256( - 0x244c605f6af78086d243fb2fffd815776932922d3cf081fa8d2ff7145b65dc0b + 0x16acc276874333a56f75e2c79d9e723e9ac1bb18d1ab5bd579a3ab1702464ed0 ) }), qElliptic: Honk.G1Point({ x: uint256( - 0x0e6398a099538b9c1f74c3a86c63d474fd2b934772171c785230674a79962144 + 0x006554df9837516dfb90ce208134e4b81d29ebf81032b08330501733f5f20d6a ), y: uint256( - 0x1152647b290d29791357e57cf4252e23aa8bb69266de667fcb6d49b50833c0fa + 0x0ff31f52484554b3123ffc5c911d928e91ee373db03b305bd1350ae27aba4169 ) }), qMemory: Honk.G1Point({ x: uint256( - 0x2f77d58e1935021197cf807adc9d6ed89c208e7397f837811935ad8e04a25646 + 0x28fad415a8ba66a6c2d15321977f696a033b56580937a63c0be78be9ccdbf00a ), y: uint256( - 0x28ca0aea22ed60e0fda6a3087590deac2e3c6dbb39f672db617a2c8f7576a3a3 + 0x229fa12d35300e25b3095908acfed5751d51e93cd6ecf4af6757ba5a4c540c18 ) }), qNnf: Honk.G1Point({ x: uint256( - 0x1ba222b35b1b79a59d990df8d802bbffd526ed44aa573cb7de03b4926e33cfda + 0x27769c90ab027f74a7f86fbe3a1832e41518cd4975e8ba110311664df43f0ce3 ), y: uint256( - 0x1e359c171885a972cb085a213975238e93b78b9b5067f6d470da0e47997cb560 + 0x24a8f977133bcb034382e4cbcd3e335373ae5aac0e67824a2647554a52536b87 ) }), qPoseidon2External: Honk.G1Point({ x: uint256( - 0x1a8754cb4b93dbc97099cedc11c48286b8fb9ab103537f8872f0e44d05b6f677 + 0x2eb3443efed96b06718b28d1bfbbc35a407b6af60f720ba5a9d0ac78501f0ed2 ), y: uint256( - 0x25b8a35780ef8e6b2544f4b3c9b96d25df0f4f3f2eb652c0d3ba10ee3066dc06 + 0x17022aa4435561f83bdddcaa9174723a1e31c11d128a3455edc0b21bf22d334b ) }), qPoseidon2Internal: Honk.G1Point({ x: uint256( - 0x15dcd14e33a5c64ef3eef7938fccf400d798ec44f2a02fdf2e196dfa65f10c32 + 0x2ef9e66a814fe6821f53a2a2e1e93ac8630a347d7c9fee2afd2edcdc13bc0548 ), y: uint256( - 0x1d52fe9202be704fa45de182df518c960eca7b5c8c8f8f3ff92d6522b9efaa13 + 0x0ebdcee17969483e898170e905ff58418ad7e99173fa87c028966bd8c040c923 ) }), s1: Honk.G1Point({ x: uint256( - 0x168d4cfd6436be78fc713ef78e188f60e11008a4740fce4f64342bd82ced648b + 0x235a96328f656f5e8e3935de342e7ffb06d3400d2e11e03ff3f5e9729dec07de ), y: uint256( - 0x011b219a479e28c150896d9aed6042b687a10b2e3d725f5d08d7fea94a122f45 + 0x23b38403e02d9a93b48b7e21c10d7360fd7a39299f6aae2174d47e2df318775f ) }), s2: Honk.G1Point({ x: uint256( - 0x2e416ff405b6c53bc74973defa708ccc60c6fe491349100cec7b1481979da38e + 0x2c15698c01375d97f94676f1bbdb3ba5b157bacaadec11b12cf074cf212f6e12 ), y: uint256( - 0x14324c310091b0f31ddfcbbac474565ff58d178a307ffc8178cec436ccd7163c + 0x141ec5c8ba7190c9cb1fab4f19e817d9d8f9cb2c0cedd614d4f7820a2f7c4abb ) }), s3: Honk.G1Point({ x: uint256( - 0x25133c6ea741cb3281d03c49f306b4f01fb6d338d27906e5409715ced74033f7 + 0x22e7871e851cfc6514318d6f16d1c34305dd0e3c0dbe39df3527feda3b0d1eb0 ), y: uint256( - 0x2a6c7c2db40a4d31607bd6f7d823207f1f5ed217b0784a085920722fd3ad36f4 + 0x078c546da57b7d1340a5a5b11922ab15592a2c3d32553532c318f0a238768a01 ) }), s4: Honk.G1Point({ x: uint256( - 0x1609e2a7fef984bfb951cdaa3901af7d335fdde29d47d4cae8c3b9e7363134b4 + 0x17e47cca2b9876b87b90039176b89b889b2e6f6ab55bf5b6ade7026c1886a55b ), y: uint256( - 0x1a6b3f2acc00e7396c9348d7dde2587bc1d0c8ee1b9c35465b02d16d5e23d3b7 + 0x1277395e4b6af40bd3099eedef9f6f1f4a3f6e95a1c0540bc521df5df391fdce ) }), t1: Honk.G1Point({ x: uint256( - 0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26 + 0x0bed9c3687f3524dbbb6410842f20eb0d87d1915348d97dd74ce9df8681fb03c ), y: uint256( - 0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f + 0x061cf87194c9b570a8d060c9dfed139083f2aedc80da0d97d390d72f5cc75579 ) }), t2: Honk.G1Point({ x: uint256( - 0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e + 0x0441aaeda5bb8ccbef2c72be215aacd45db72650f5a9855820447b241f57c887 ), y: uint256( - 0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19 + 0x27e4f80d4673c2dc9bc21386edf443e8f74d4cff7b89fb2c34c0bcca5008d9d8 ) }), t3: Honk.G1Point({ x: uint256( - 0x061f64497996e8915722501e9e367938ed8da2375186b518c7345c60b1134b2d + 0x17161957b5bea1c4b6cd7dd7a0b530aae4907cffac5801fff85ba8e4c3fa3f2f ), y: uint256( - 0x1b84d38339321f405ebaf6a2f830842ad3d7cb59792e11c0d2691f317fd50e6e + 0x14669badaf49b0e6aaa983ac2a20378e7c5ac3b4141284ca01124c3dd33589f7 ) }), t4: Honk.G1Point({ x: uint256( - 0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce + 0x1e10d6c8482b99a03f78a2028bb33719c19bc62fa08e1d548059b139388532e6 ), y: uint256( - 0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854 + 0x0139852d1968d8a0c11ba44db1553094224570b77f987b01a73781e265365cea ) }), id1: Honk.G1Point({ x: uint256( - 0x032c782b90a26fe68b4503eff33053fb0491f972c7589f678cecb1823567cfbb + 0x162e6ffc2acbbe037aa8301684ed9e2d850a2c83a3c1a3164453b5c2187c8c75 ), y: uint256( - 0x13cea8eda4216f5eec776c455ebe175fc799c21bfcc40bf06c386d575042624d + 0x22f0647302fbfc4d83670140b7ec0cd606fd991bd3e7cebeee96ee3b6169e538 ) }), id2: Honk.G1Point({ x: uint256( - 0x1927315353225025dbf69ce7184ee16deb1f77c740b23f61bb7c7dc0ed459aae + 0x1fc1d8dce21a638cd9695d5ed2d796b7b1423fe391391cbf0076dabcd5b1229c ), y: uint256( - 0x1163822d778b1f374f971a3bbbac861c3b3b7eacdb0e506cf216c40921f12174 + 0x2e4d338298032c5426ca47e6970b8ef0b055728771a8ad6b455f4d3001abd402 ) }), id3: Honk.G1Point({ x: uint256( - 0x211deee9dfac40c974eb8567e5f98f33c095c3b473646744ff9249c0141557f1 + 0x011c7ccc37d9abaf9dd6ffb88f045f8f6adb02dde453b8645b7a5461356255f8 ), y: uint256( - 0x012032061151f693f8b9db5136efa15439a59fcef2ce2a994474cc0e38deea65 + 0x0186d6fa335ec0a6179c9edeb2cfca478103eb4989218cd11ddeb6a4762ff294 ) }), id4: Honk.G1Point({ x: uint256( - 0x19feb056cf9e0242cd8b03b6382a7f4cc56ad7d791279cf4902bceaf76480661 + 0x1be8e47ef6bff9941f3febe177d14f28448a16fe9dd81b1c9cfd05bd9136c02c ), y: uint256( - 0x0ce22a0fb2bcfc2acceb26380d901ed53b28665d3202b66c178efe54ae0601e5 + 0x1d6ea8c9b1f0fd0d27694dee140ef177141fc8e1d240e5715834070a82a9d7e0 ) }), lagrangeFirst: Honk.G1Point({ @@ -237,10 +237,10 @@ library HonkVerificationKey { }), lagrangeLast: Honk.G1Point({ x: uint256( - 0x07a3911591931e1a78fe8e7034f651e03fa7512effe4eca4e5669efffccae5b3 + 0x201feccb28b5ddf7440c37e1a8d5676a8f9d7feb0e373436b3413fa9f775fd6b ), y: uint256( - 0x1e175c0cba144505ad7bf362c1fa2edd1cec27db3efc62e7aaec8f974ebd5d3d + 0x03f87d81d9e68bc20ce687e8a53620c9947d06fdc887f89e9fc6a023c8880e74 ) }) }); diff --git a/packages/enclave-contracts/contracts/verifiers/bfv/honk/DkgAggregatorVerifier.sol b/packages/enclave-contracts/contracts/verifiers/bfv/honk/DkgAggregatorVerifier.sol index c913812e71..8f8d5f63fb 100644 --- a/packages/enclave-contracts/contracts/verifiers/bfv/honk/DkgAggregatorVerifier.sol +++ b/packages/enclave-contracts/contracts/verifiers/bfv/honk/DkgAggregatorVerifier.sol @@ -7,8 +7,8 @@ pragma solidity >=0.8.21; uint256 constant N = 2097152; uint256 constant LOG_N = 21; -uint256 constant NUMBER_OF_PUBLIC_INPUTS = 29; -uint256 constant VK_HASH = 0x07706ac4275caeba3a6e83631b7cc30dc8322839a88f5a941700619161f38391; +uint256 constant NUMBER_OF_PUBLIC_INPUTS = 31; +uint256 constant VK_HASH = 0x1c0a60837c2a1d7cc5e62a5a531d6d1e4e9685388506a78f7c0bb201eef5ad96; library HonkVerificationKey { function loadVerificationKey() internal @@ -18,213 +18,213 @@ library HonkVerificationKey { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(2097152), logCircuitSize: uint256(21), - publicInputsSize: uint256(29), + publicInputsSize: uint256(31), ql: Honk.G1Point({ x: uint256( - 0x111a728f6d97feb2d07c8650c58297f43fa1cb737536686ba611035833266766 + 0x1d906d083872617485399605e6b8d7e0eea0a10f71271b8c59adf24cc8339be7 ), y: uint256( - 0x0fd591041aa17dcbf78787ba1f6eb644df43fb92c7b60870b3c29dd033933cd1 + 0x26cad07a2734aa9aee4ce7b358d3043b357b9c91a96529d54f52520050342e9a ) }), qr: Honk.G1Point({ x: uint256( - 0x062bd2526fa803f36afac0562659df1a9f4a0c6589aa65c6c6af7ed41d973839 + 0x246cfefd937a61df24c91a5f3fe31de8e7ce3f17837637c0e1f55e5889f58c77 ), y: uint256( - 0x0ea545fff69b5528031196319619d3bc836a0b18c4b0d8323c2c3f235f225c50 + 0x11bed90de8b7c6acb3b363d70850528c89b62b73d9f9b83a2ca30bce346bad94 ) }), qo: Honk.G1Point({ x: uint256( - 0x2f0724b72d5ed5a5fbe800439d3e9a5f0b202dbfacd761a0b4e4686fed34c6a1 + 0x0e932b810103be7429befc3ade0b3c06617473d69778daad01d4b62e6ea89507 ), y: uint256( - 0x28bdb4ee0c725dfd07c5c7409c846bcd4ecaedfaa5806962add7336452afa15d + 0x1b808239e3a1eca0011029525cc8fbfa471341d8d94df76b1c17718216f5eeda ) }), q4: Honk.G1Point({ x: uint256( - 0x0c39b0d165d345799d17d07f9950f4002d6e60382e9b56eb6c14010d467e6aba + 0x0c18563d13b6db7effc22340fc74a2e7b2f9dbb0b42d3f0acc47331f3558dae9 ), y: uint256( - 0x2e49a73ee7e9bb5a90edc5e724beb2fd71ccf5fcaa5f30d7b86c290de9be1e90 + 0x2ff93536486524c1c58a883b55284b278c7efdafc5b41808d88fce3243b11d69 ) }), qm: Honk.G1Point({ x: uint256( - 0x1536bfcfa305be4288c24dedcd842d1700eea427c52b732d404e83a426babb68 + 0x104aa9b4476927b9c3df51c532b1cae7b87f5b7ab9373da43777be83108dbca7 ), y: uint256( - 0x21a70fbc5c35eb021d4e24055c2fcdd215d7711ce8d99c001c7327be43500162 + 0x1cd279d089fb417574bdfff9320b8ef459196f7841d15f10ef03e78999520fe6 ) }), qc: Honk.G1Point({ x: uint256( - 0x0bd8b8c90ec9f0acab4b254d831db478a05a95e8ab4bb5d0cb9c7fd38ff4e837 + 0x2749c7c3188e135b4baacb08abda70578c43ba2793c2e376adebc8f5e092a1cb ), y: uint256( - 0x152422e5e5f4c10b9d337cf5284a22c017afd562787f81cce3e573e948cbebde + 0x02e6a616a7cd3b2c2107c830a18f766f558c5a56e2fe560de4216cb42bbe4095 ) }), qLookup: Honk.G1Point({ x: uint256( - 0x2ee537ee80c33fc3003e53f2fa67b14d63887059b541c3d5dbe38bfd517aa579 + 0x182070aa2b03de9e8b4cada6a0760a0c6c72852783e7db97b4cd91281c03d3ea ), y: uint256( - 0x0ecddf7b61838886fcf1a7fec5c69d8e02933d1e153e33e5ea7d03b0c21b314a + 0x08c55ecc2b52f5393505462ae16474727d81f865b293adee900644436146a8e1 ) }), qArith: Honk.G1Point({ x: uint256( - 0x2ae5c90804b7a2eee8676464c0afd8105452bc0b5160c5af08e07332f642509b + 0x2efb699f4c4dbbd9ec2552bfd41f42f8a5e958cc50ff9dc953be33140272458a ), y: uint256( - 0x1faa3c5b0d043233968e58ab03d1e3988d53933fd5716f73dfceaa283321fedc + 0x06c6d7d7d0a685224f444ac30d3fa678760361d759abc9e7a229ea8979703e61 ) }), qDeltaRange: Honk.G1Point({ x: uint256( - 0x12fabb263760a8bd891d6549cbbe45b5db26449b9095e982986ba5f0f8b71bcf + 0x019002e97cd41dd882e373b2bc79c3cad6a400244ff1e80aae06c0b1186b1e20 ), y: uint256( - 0x206f2d10317a3ba8c5147afb8c356eaa6af0912f3dd5f6af3acf4caac3075e6f + 0x1fef3eed64626bfd4a793a5330d1eebc6af338a1814c237fae0dc532abe6203a ) }), qElliptic: Honk.G1Point({ x: uint256( - 0x0791fed23dfada00ede6c9c02c9d8c5203db1c0aefb755b6bfd8858fd6ecbf20 + 0x2d867487b60acfaa537feeae0185cfbcb84315e1f9d8eb13e33fcee51e35cc4d ), y: uint256( - 0x21b24edba4ae135a28e9d5537974b00b80b0e1eb42850f3f659af9e923887ec0 + 0x231c0fe3f3de4990752e61ac8897498223d1cc527808376a7ab250c61b48e170 ) }), qMemory: Honk.G1Point({ x: uint256( - 0x09e78ace9cfdcf5ad7cc6802eecf242bc9e3e198894af77aaf3debcc2bd32fa5 + 0x1954e635e980037fb7bc3c25c450d12a9a19837e01e3f1d479d51728bb70af6b ), y: uint256( - 0x14fd3c6a7580ed1a7de952571906b5ce0185a46514fa57d0e04ab32c0ca0dd34 + 0x2ce76f6c6fe16633bf7c675281759908490fed6ff2829e8997513eb4fcf56f53 ) }), qNnf: Honk.G1Point({ x: uint256( - 0x0fd61103ff82eb1bae7052f5497eab0a2faf991c16f7e69d15f07cae89cce2ba + 0x077d3f2336940aec76438f6c30edddd2e751c56a72ffaf64e9ef476f524daa2c ), y: uint256( - 0x1e1dd49698f822a28bb1395b3f1f13f15e59d374ad9a55c90f32dd77ce17c858 + 0x04b61eb1f9b0837bcc0714bb3c00c190349dacb7ccaab86a6027b910dd2309e0 ) }), qPoseidon2External: Honk.G1Point({ x: uint256( - 0x2aec5550a01a45e0bc78f9c2c92eeab9dbb308125921dda7789fcff1d6d0db5d + 0x24a3cef3397bef0d207ce03d64d77ea0a7dabde143471d98cd7360b7685a90b7 ), y: uint256( - 0x117277f243642f35b0de763270a2f67f23c1a577fb9b645068f9bf3a8142f1bf + 0x165894aaaf725b36f72e71880ff23c78ffa1b757304b00b94c56f7e9886936ce ) }), qPoseidon2Internal: Honk.G1Point({ x: uint256( - 0x231e7ffadf1a4fe4c731aadba30f4e688c57036f2f0a292f6f4ed598bf5c45be + 0x24bf2806f2e4fdb9a4728a47a888038a8602f1a564cce5439d8a0c89eb04b351 ), y: uint256( - 0x04ad4cd62afd2071e675fb9f806fd010bdde31728b54162c5d388ff8407311a9 + 0x21002a27f9d4cb5b284ad2b3c83e2956e1ecdef6ab8ad07b085a429f82374a77 ) }), s1: Honk.G1Point({ x: uint256( - 0x12e76ee7f67d824af0f9eaf001d62ee30e3f77812e99060eb6f89c2cc0e2b825 + 0x1b1656cadd0b2ab6f8a6e5e22d0dec012d95f87e22432d4acfa44d0272596189 ), y: uint256( - 0x116e5a8a4011461fb9c38f402e6b1c6cc46bb827e701c4d8dc94f6e6e9b05085 + 0x283c907c7278fa3fce6eeadeaaa9c48f7ab8211c94882f851c9fdcabdbac1bdc ) }), s2: Honk.G1Point({ x: uint256( - 0x27474a8477926570b376c9484b946a50407ad175301d24f0823aa48bd4225990 + 0x23f558a747590ffc98f1cec61982a939c17078fb8597d196c5f71436f6135393 ), y: uint256( - 0x0ac3513a35e7af6ee46189ca6e0a2d701f7568427a6f6cab64490652985904f1 + 0x0bb3abcbf063633ba4de4a51dec092e6f79c64cf48340c2bb149bd340cc95e9c ) }), s3: Honk.G1Point({ x: uint256( - 0x25446ef56d42b22185a7b772992264f8614dd81c830197979efa2ce70b81c94c + 0x120874be1571c176bdb51bf3357b34f678084ba91f8d644019ce9cf69f819537 ), y: uint256( - 0x1fc621751d8cc710f997f7665d71c5969433e4148f625915610d437f25771a9a + 0x0b28eef919110795820b3818e697556033489a739c2056801c36b3e15b7a16ea ) }), s4: Honk.G1Point({ x: uint256( - 0x101488084a381a1a19fc537fff3cfdbc971c14810faf379184d40a10f8a2b111 + 0x2face01c0f73016a476cdae4e8825f315ed329847cf15c2f1c46a270cf1cdbab ), y: uint256( - 0x222d5570c3352d841d289672c2150d62852bb77cae4798e22890d5772e678c9b + 0x09d51e6255090c8a48ef74e1d2f20a6becf2b22811e77308559545471bbf9f92 ) }), t1: Honk.G1Point({ x: uint256( - 0x099e3bd5a0a00ab7fe18040105b9b395b5d8b7b4a63b05df652b0d10ef146d26 + 0x0bed9c3687f3524dbbb6410842f20eb0d87d1915348d97dd74ce9df8681fb03c ), y: uint256( - 0x0015b8d2515d76e2ccec99dcd194592129af3a637f5a622a32440f860d1e2a7f + 0x061cf87194c9b570a8d060c9dfed139083f2aedc80da0d97d390d72f5cc75579 ) }), t2: Honk.G1Point({ x: uint256( - 0x1b917517920bad3d8bc01c9595092a222b888108dc25d1aa450e0b4bc212c37e + 0x0441aaeda5bb8ccbef2c72be215aacd45db72650f5a9855820447b241f57c887 ), y: uint256( - 0x305e8992b148eedb22e6e992077a84482141c7ebe42000a1d58ccb74381f6d19 + 0x27e4f80d4673c2dc9bc21386edf443e8f74d4cff7b89fb2c34c0bcca5008d9d8 ) }), t3: Honk.G1Point({ x: uint256( - 0x061f64497996e8915722501e9e367938ed8da2375186b518c7345c60b1134b2d + 0x17161957b5bea1c4b6cd7dd7a0b530aae4907cffac5801fff85ba8e4c3fa3f2f ), y: uint256( - 0x1b84d38339321f405ebaf6a2f830842ad3d7cb59792e11c0d2691f317fd50e6e + 0x14669badaf49b0e6aaa983ac2a20378e7c5ac3b4141284ca01124c3dd33589f7 ) }), t4: Honk.G1Point({ x: uint256( - 0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce + 0x1e10d6c8482b99a03f78a2028bb33719c19bc62fa08e1d548059b139388532e6 ), y: uint256( - 0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854 + 0x0139852d1968d8a0c11ba44db1553094224570b77f987b01a73781e265365cea ) }), id1: Honk.G1Point({ x: uint256( - 0x2c9d9734c6b4280d3b45cd2f229b94ef9d6ea0cc4b12d3115772c8a44da778cd + 0x00efe1593a923558e7779f10e4753794a59ad0dcc02df6790b72346175b1b7b9 ), y: uint256( - 0x1bb5ebb400bf039d6bf710f9f260cbb912ee939afeef8d9d7038419872b51800 + 0x28b0744e7ea51d27a2624e7ffe4ccae8f3c9c6350131555ceedb42078a229a3c ) }), id2: Honk.G1Point({ x: uint256( - 0x03d6c8a21ed149f265d420e561a26db16aa036f6255b1d7cb1dbd7fef424e679 + 0x0f28ce7d149491697d292002785ff24f6089b458ea01234e4af8eda65b9dd266 ), y: uint256( - 0x0bec696b07abc01e6d9be8ac176d7e3f22c1ba9745dfef9b8ec43544a6401b72 + 0x24519d3dab7ba27bcf50279756292c7052edff4183446b2ae85617e6dff01883 ) }), id3: Honk.G1Point({ x: uint256( - 0x08079b32015b38fd3892014f149d0ae2f96b1251d2614dd1b749d18996e9efd8 + 0x27ae1958d5100a4fbe5ae016fdac9ea54c5c4172cc798a38d3f8730c5f481a5d ), y: uint256( - 0x154c73548738dbb8b06e4a787dd140c0ff343b94223a1ed3af02851ae55ed685 + 0x2e28100a9463b43a586fb70dfe15c841ddbd30703149bd5d9fb7273d520554c5 ) }), id4: Honk.G1Point({ x: uint256( - 0x036e02a212e0ea99da1fc3b9c88f80132bfce41225a39da38588bb8fb646dcc7 + 0x072921e4c634152a135b6fcd0c5cadfa66f780284592d1f3262fa04128f7ba6a ), y: uint256( - 0x212442209a29191258fc995d08e625ec8c4cd47e930363a0398644cbb11c30c4 + 0x0bfd2eec92d6aad31ca352447ca9a9e69eb7a2465f9741f67ea75c5622d14e02 ) }), lagrangeFirst: Honk.G1Point({ @@ -237,10 +237,10 @@ library HonkVerificationKey { }), lagrangeLast: Honk.G1Point({ x: uint256( - 0x2dd29b2f19810390ba06ca70af2a664ae7bc0928bc4352eaf47ca52aecc163e8 + 0x1f248647726750901d3e276b8a1d386600b913a3924d5bbc43cb896f40024400 ), y: uint256( - 0x2facd07b0816618d20a2dbeeb6a7f0045e981d6f0020135fc1131c8278a34730 + 0x20c67ede3b2a84a692458ecf65ad55a687027c57f4eca98eb419ea3b79f669c1 ) }) }); diff --git a/packages/enclave-contracts/deployed_contracts.json b/packages/enclave-contracts/deployed_contracts.json index 19734ae228..fed693f627 100644 --- a/packages/enclave-contracts/deployed_contracts.json +++ b/packages/enclave-contracts/deployed_contracts.json @@ -123,5 +123,130 @@ "blockNumber": 10697357, "address": "0x9D55635A78B96A72ee540bdE376722350e9B8B70" } + }, + "localhost": { + "PoseidonT3": { + "blockNumber": 5, + "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" + }, + "MockUSDC": { + "constructorArgs": { + "initialSupply": "1000000" + }, + "blockNumber": 6, + "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" + }, + "EnclaveToken": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 7, + "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" + }, + "EnclaveTicketToken": { + "constructorArgs": { + "baseToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "registry": "0x0000000000000000000000000000000000000001", + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 9, + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" + }, + "SlashingManager": { + "constructorArgs": { + "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "blockNumber": 10, + "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" + }, + "CiphernodeRegistryOwnable": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "submissionWindow": "10" + }, + "proxyRecords": { + "initData": "0xcd6dc687000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000a", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", + "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" + }, + "blockNumber": 11, + "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" + }, + "BondingRegistry": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "ticketToken": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "licenseToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "registry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "slashedFundsTreasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "ticketPrice": "10000000", + "licenseRequiredBond": "100000000000000000000", + "minTicketBalance": "1", + "exitDelay": "604800" + }, + "proxyRecords": { + "initData": "0x7333fa82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c90000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e0000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000093a80", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "proxyAdminAddress": "0x8aCd85898458400f7Db866d53FCFF6f0D49741FF", + "implementationAddress": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + }, + "blockNumber": 12, + "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" + }, + "Enclave": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "registry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "bondingRegistry": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "e3RefundManager": "0x0000000000000000000000000000000000000001", + "feeToken": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "maxDuration": "2592000", + "timeoutConfig": "{\"committeeFormationWindow\":3600,\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" + }, + "proxyRecords": { + "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000008a791620dd6260079bf849dc5567adc3f2fdc3180000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "proxyAdminAddress": "0x8dAF17A20c9DBA35f005b6324F493785D239719d", + "implementationAddress": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788" + }, + "blockNumber": 15, + "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e" + }, + "E3RefundManager": { + "constructorArgs": { + "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "enclave": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "treasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + }, + "proxyRecords": { + "initData": "0xc0c53b8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000b7f8bc63bbcad18155201308c8f3540b07f84f5e000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "proxyAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", + "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + }, + "blockNumber": 17, + "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + }, + "MockComputeProvider": { + "blockNumber": 19, + "address": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042" + }, + "MockDecryptionVerifier": { + "blockNumber": 20, + "address": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9" + }, + "MockPkVerifier": { + "blockNumber": 21, + "address": "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8" + }, + "MockE3Program": { + "blockNumber": 22, + "address": "0x851356ae760d987E095750cCeb3bC6014560891C" + } } } \ No newline at end of file diff --git a/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts b/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts index 3ce4e43d7a..d88a66818e 100644 --- a/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts +++ b/packages/enclave-contracts/ignition/modules/bfvDecryptionVerifier.ts @@ -7,6 +7,7 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import { BFV_DECRYPTION_SUB_CIRCUIT_VK_HASH_PATHS, + BFV_THRESHOLD_T, readVkRecursiveHash, } from "../../scripts/utils"; import decryptionAggregatorVerifierModule from "./decryptionAggregatorVerifier"; @@ -27,6 +28,7 @@ export default buildModule("BfvDecryptionVerifier", (m) => { decryptionAggregatorVerifier, expectedC6FoldKeyHash, expectedC7KeyHash, + BFV_THRESHOLD_T, ]); return { bfvDecryptionVerifier }; diff --git a/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts b/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts index be7a632926..6cd6fcd2da 100644 --- a/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts +++ b/packages/enclave-contracts/ignition/modules/bfvPkVerifier.ts @@ -6,6 +6,7 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import { + BFV_DKG_H, BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS, readVkRecursiveHash, } from "../../scripts/utils"; @@ -25,6 +26,7 @@ export default buildModule("BfvPkVerifier", (m) => { dkgAggregatorVerifier, expectedNodesFoldKeyHash, expectedC5KeyHash, + BFV_DKG_H, ]); return { bfvPkVerifier }; diff --git a/packages/enclave-contracts/scripts/benchmarkGasFromRaw.ts b/packages/enclave-contracts/scripts/benchmarkGasFromRaw.ts index 610a807d53..6043dae8c8 100644 --- a/packages/enclave-contracts/scripts/benchmarkGasFromRaw.ts +++ b/packages/enclave-contracts/scripts/benchmarkGasFromRaw.ts @@ -9,7 +9,12 @@ import path from "node:path"; import { BFV_DECRYPTION_SUB_CIRCUIT_VK_HASH_PATHS, + BFV_DKG_H, BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS, + BFV_THRESHOLD_T, + bfvDecCommitteeHashIndices, + bfvDkgCommitteeHashIndices, + committeeHashFromLimbs, readVkRecursiveHash, } from "./utils"; @@ -23,6 +28,22 @@ function findRawJson(rawDir: string, fragment: string): any { throw new Error(`Missing raw benchmark JSON for fragment: ${fragment}`); } +const MIN_VK_HASH_PUBLIC_INPUTS = 2; +const DKG_COMMITTEE_HASH_IDX = bfvDkgCommitteeHashIndices(BFV_DKG_H); +const DEC_COMMITTEE_HASH_IDX = bfvDecCommitteeHashIndices(); + +function requirePublicInputLen( + label: string, + publicInputs: string[], + minLen: number, +): void { + if (publicInputs.length < minLen) { + throw new Error( + `${label}: public_inputs length ${publicInputs.length} < ${minLen} (truncated or stale artifact?)`, + ); + } +} + function hexToBytes32Array(hex: string): string[] { const clean = hex.startsWith("0x") ? hex.slice(2) : hex; if (clean.length === 0) return []; @@ -98,6 +119,16 @@ async function main() { const dkgPublicInputs = hexToBytes32Array(dkgPublicHex); const decPublicInputs = hexToBytes32Array(decPublicHex); + requirePublicInputLen( + "dkg_aggregator", + dkgPublicInputs, + MIN_VK_HASH_PUBLIC_INPUTS, + ); + requirePublicInputLen( + "decryption_aggregator", + decPublicInputs, + MIN_VK_HASH_PUBLIC_INPUTS, + ); const expectedNodesFoldKeyHash = readVkRecursiveHash( BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS.nodesFold, @@ -166,25 +197,52 @@ async function main() { const bfvPk = await ( await ethers.getContractFactory("BfvPkVerifier") - ).deploy(dkgAggAddress, expectedNodesFoldKeyHash, expectedC5KeyHash); + ).deploy( + dkgAggAddress, + expectedNodesFoldKeyHash, + expectedC5KeyHash, + BFV_DKG_H, + ); await bfvPk.waitForDeployment(); const dkgEncodedProof = abiCoder.encode( ["bytes", "bytes32[]"], [dkgProofHex, dkgPublicInputs], ); + requirePublicInputLen( + "dkg_aggregator committee_hash", + dkgPublicInputs, + DKG_COMMITTEE_HASH_IDX.lo + 1, + ); const pkCommitment = dkgPublicInputs[dkgPublicInputs.length - 1]; - const dkgOk = await bfvPk.verify.staticCall(pkCommitment, dkgEncodedProof); + const dkgCommitteeHash = committeeHashFromLimbs( + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.hi], + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.lo], + ); + const dkgOk = await bfvPk.verify.staticCall( + pkCommitment, + dkgCommitteeHash, + dkgEncodedProof, + ); if (!dkgOk) { throw new Error( "BfvPkVerifier.verify returned false for folded DKG proof (Honk VK / proof mismatch?)", ); } - const dkgGas = await bfvPk.verify.estimateGas(pkCommitment, dkgEncodedProof); + const dkgGas = await bfvPk.verify.estimateGas( + pkCommitment, + dkgCommitteeHash, + dkgEncodedProof, + ); const bfvDec = await ( await ethers.getContractFactory("BfvDecryptionVerifier") - ).deploy(decAggAddress, expectedC6FoldKeyHash, expectedC7KeyHash); + ).deploy( + decAggAddress, + expectedC6FoldKeyHash, + expectedC7KeyHash, + BFV_THRESHOLD_T, + ); await bfvDec.waitForDeployment(); const decEncodedProof = abiCoder.encode( @@ -192,7 +250,20 @@ async function main() { [decProofHex, decPublicInputs], ); const plaintextHash = plaintextHashFromPublicInputs(decPublicInputs, ethers); - const decOk = await bfvDec.verify.staticCall(plaintextHash, decEncodedProof); + requirePublicInputLen( + "decryption_aggregator committee_hash", + decPublicInputs, + DEC_COMMITTEE_HASH_IDX.lo + 1, + ); + const decCommitteeHash = committeeHashFromLimbs( + decPublicInputs[DEC_COMMITTEE_HASH_IDX.hi], + decPublicInputs[DEC_COMMITTEE_HASH_IDX.lo], + ); + const decOk = await bfvDec.verify.staticCall( + plaintextHash, + decCommitteeHash, + decEncodedProof, + ); if (!decOk) { throw new Error( "BfvDecryptionVerifier.verify returned false for folded decryption proof (Honk VK / proof mismatch?)", @@ -200,6 +271,7 @@ async function main() { } const decGas = await bfvDec.verify.estimateGas( plaintextHash, + decCommitteeHash, decEncodedProof, ); diff --git a/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts b/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts index a7072d6042..002b04f450 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/bfvDecryptionVerifier.ts @@ -11,6 +11,7 @@ import { } from "../../types"; import { BFV_DECRYPTION_SUB_CIRCUIT_VK_HASH_PATHS, + BFV_THRESHOLD_T, assertBfvDecryptionVerifierSubCircuitVkHashes, readDeploymentArgs, readVkRecursiveHash, @@ -67,6 +68,7 @@ export const deployAndSaveBfvDecryptionVerifier = async ( circuitVerifierArgs.address, expectedC6FoldKeyHash, expectedC7KeyHash, + BFV_THRESHOLD_T, ); await bfvDecryptionVerifier.waitForDeployment(); diff --git a/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts b/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts index b51dd54401..9f09583988 100644 --- a/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts +++ b/packages/enclave-contracts/scripts/deployAndSave/bfvPkVerifier.ts @@ -10,6 +10,7 @@ import { BfvPkVerifier__factory as BfvPkVerifierFactory, } from "../../types"; import { + BFV_DKG_H, BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS, assertBfvPkVerifierSubCircuitVkHashes, readDeploymentArgs, @@ -63,6 +64,7 @@ export const deployAndSaveBfvPkVerifier = async ( circuitVerifierArgs.address, expectedNodesFoldKeyHash, expectedC5KeyHash, + BFV_DKG_H, ); await bfvPkVerifier.waitForDeployment(); diff --git a/packages/enclave-contracts/scripts/utils.ts b/packages/enclave-contracts/scripts/utils.ts index bd672365e1..33c05e8c85 100644 --- a/packages/enclave-contracts/scripts/utils.ts +++ b/packages/enclave-contracts/scripts/utils.ts @@ -3,10 +3,24 @@ // This file is provided WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +import { getBytes, hexlify, zeroPadValue } from "ethers"; import fs from "fs"; import { fileURLToPath } from "node:url"; import path from "path"; +/** + * Reconstruct `keccak256(abi.encodePacked(topNodes))` from aggregator public-input + * limbs. Each limb is a bytes32 with 128 bits right-aligned (`CommitteeHashLib`). + */ +export function committeeHashFromLimbs(hi: string, lo: string): string { + const hiBytes = getBytes(zeroPadValue(hi, 32)); + const loBytes = getBytes(zeroPadValue(lo, 32)); + const hash = new Uint8Array(32); + hash.set(hiBytes.subarray(16, 32), 0); + hash.set(loBytes.subarray(16, 32), 16); + return hexlify(hash); +} + export const deploymentsFile = path.join("deployed_contracts.json"); /** Monorepo root (`enclave/`), resolved from `packages/enclave-contracts/scripts/`. */ @@ -15,6 +29,36 @@ export const REPO_ROOT = path.resolve( "../../..", ); +/** + * Default insecure-512 / micro committee layout for BFV aggregator verifiers. + * Must match `lib::configs::default::{H, T}` in compiled circuits. + */ +export const BFV_DKG_H = 3; +export const BFV_THRESHOLD_T = 1; + +/** `dkg_aggregator` EVM public-input count for honest-set size `h`. */ +export function bfvPkExpectedPublicInputsLen(h: number): number { + return 3 * h + 6; +} + +/** `publicInputs` indices for `committee_hash_hi` / `committee_hash_lo` (matches `BfvPkVerifier`). */ +export function bfvDkgCommitteeHashIndices(h: number): { + hi: number; + lo: number; +} { + return { hi: 2 + h, lo: 3 + h }; +} + +/** `decryption_aggregator` EVM public-input count for BFV threshold `t`. */ +export function bfvDecExpectedPublicInputsLen(threshold: number): number { + return 108 + 3 * threshold; +} + +/** `publicInputs` indices for decryption-aggregator committee hash limbs. */ +export function bfvDecCommitteeHashIndices(): { hi: number; lo: number } { + return { hi: 2, lo: 3 }; +} + /** Recursive VK hashes for `BfvPkVerifier` sub-circuits (from `pnpm compile:circuits`). */ export const BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS = { nodesFold: path.join( diff --git a/packages/enclave-contracts/tasks/enclave.ts b/packages/enclave-contracts/tasks/enclave.ts index 2914450fa5..bb69284e90 100644 --- a/packages/enclave-contracts/tasks/enclave.ts +++ b/packages/enclave-contracts/tasks/enclave.ts @@ -130,7 +130,7 @@ export const requestCommittee = task( .addOption({ name: "proofAggregationEnabled", description: "whether to enable proof aggregation (default: false)", - defaultValue: true, + defaultValue: false, type: ArgumentType.BOOLEAN, }) .setAction(async () => ({ @@ -382,7 +382,6 @@ export const publishCommittee = task( const tx = await ciphernodeRegistry.publishCommittee( e3Id, - nodesToSend, publicKey, pkCommitment, proof, diff --git a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts index d2bc3e29a5..c8e8006ee0 100644 --- a/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts +++ b/packages/enclave-contracts/test/BfvDecryptionVerifier.spec.ts @@ -7,6 +7,10 @@ import { expect } from "chai"; import { network } from "hardhat"; import MockCircuitVerifierModule from "../ignition/modules/mockSlashingVerifier"; +import { + BFV_THRESHOLD_T, + bfvDecExpectedPublicInputsLen, +} from "../scripts/utils"; import { BfvDecryptionVerifier__factory as BfvDecryptionVerifierFactory, MockCircuitVerifier__factory as MockCircuitVerifierFactory, @@ -21,9 +25,15 @@ const MESSAGE_COEFFS_COUNT = 100; const EXPECTED_C6_FOLD_KEY_HASH = ethers.id("c6_fold"); const EXPECTED_C7_KEY_HASH = ethers.id("c7"); +/** Must match `BfvDecryptionVerifier.threshold` / default circuit `T`. */ +const THRESHOLD = BFV_THRESHOLD_T; + +/** Exact `publicInputs.length` for the configured threshold. */ +const EXPECTED_PUBLIC_INPUTS_LEN = bfvDecExpectedPublicInputsLen(THRESHOLD); + function buildPublicInputsWithMessage( messageCoeffs: bigint[], - totalInputs = 402, + totalInputs = EXPECTED_PUBLIC_INPUTS_LEN, subCircuitHashes: [string, string] = [ EXPECTED_C6_FOLD_KEY_HASH, EXPECTED_C7_KEY_HASH, @@ -77,7 +87,12 @@ describe("BfvDecryptionVerifier", function () { const bfvDecryptionVerifier = await ( await ethers.getContractFactory("BfvDecryptionVerifier") - ).deploy(mockAddr, EXPECTED_C6_FOLD_KEY_HASH, EXPECTED_C7_KEY_HASH); + ).deploy( + mockAddr, + EXPECTED_C6_FOLD_KEY_HASH, + EXPECTED_C7_KEY_HASH, + THRESHOLD, + ); await bfvDecryptionVerifier.waitForDeployment(); const dv = BfvDecryptionVerifierFactory.connect( @@ -97,11 +112,15 @@ describe("BfvDecryptionVerifier", function () { const invalidProof = "0xdeadbeef"; await expect( - bfvDecryptionVerifier.verify.staticCall(plaintextHash, invalidProof), + bfvDecryptionVerifier.verify.staticCall( + plaintextHash, + ethers.ZeroHash, + invalidProof, + ), ).to.be.revert(ethers); }); - it("returns false when publicInputs.length < MESSAGE_COEFFS_COUNT + 2", async function () { + it("returns false when publicInputs.length is below expected", async function () { const { bfvDecryptionVerifier, mockCircuit } = await loadFixture( deployWithMockCircuit, ); @@ -110,13 +129,36 @@ describe("BfvDecryptionVerifier", function () { const messageCoeffs = [1n, 2n, 3n]; const publicInputs = buildPublicInputsWithMessage( messageCoeffs, - MESSAGE_COEFFS_COUNT + 2, - ).slice(0, MESSAGE_COEFFS_COUNT + 1); + EXPECTED_PUBLIC_INPUTS_LEN, + ).slice(0, EXPECTED_PUBLIC_INPUTS_LEN - 1); const plaintextHash = plaintextToHash(messageCoeffs); const proof = encodeProof("0x01", publicInputs); const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, + proof, + ); + expect(result).to.equal(false); + }); + + it("returns false when publicInputs.length exceeds expected", async function () { + const { bfvDecryptionVerifier, mockCircuit } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + + const messageCoeffs = [1n, 2n, 3n]; + const publicInputs = buildPublicInputsWithMessage( + messageCoeffs, + EXPECTED_PUBLIC_INPUTS_LEN + 1, + ); + const plaintextHash = plaintextToHash(messageCoeffs); + const proof = encodeProof("0x01", publicInputs); + + const result = await bfvDecryptionVerifier.verify.staticCall( + plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -134,19 +176,22 @@ describe("BfvDecryptionVerifier", function () { await revertingVerifier.getAddress(), EXPECTED_C6_FOLD_KEY_HASH, EXPECTED_C7_KEY_HASH, + THRESHOLD, ); await bfvDecryptionVerifier.waitForDeployment(); const messageCoeffs = [1n, 2n, 3n]; - const publicInputs = buildPublicInputsWithMessage(messageCoeffs, 402, [ - ethers.id("wrong-c6"), - EXPECTED_C7_KEY_HASH, - ]); + const publicInputs = buildPublicInputsWithMessage( + messageCoeffs, + EXPECTED_PUBLIC_INPUTS_LEN, + [ethers.id("wrong-c6"), EXPECTED_C7_KEY_HASH], + ); const plaintextHash = plaintextToHash(messageCoeffs); const proof = encodeProof("0x01", publicInputs); const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -164,19 +209,22 @@ describe("BfvDecryptionVerifier", function () { await revertingVerifier.getAddress(), EXPECTED_C6_FOLD_KEY_HASH, EXPECTED_C7_KEY_HASH, + THRESHOLD, ); await bfvDecryptionVerifier.waitForDeployment(); const messageCoeffs = [1n, 2n, 3n]; - const publicInputs = buildPublicInputsWithMessage(messageCoeffs, 402, [ - EXPECTED_C6_FOLD_KEY_HASH, - ethers.id("wrong-c7"), - ]); + const publicInputs = buildPublicInputsWithMessage( + messageCoeffs, + EXPECTED_PUBLIC_INPUTS_LEN, + [EXPECTED_C6_FOLD_KEY_HASH, ethers.id("wrong-c7")], + ); const plaintextHash = plaintextToHash(messageCoeffs); const proof = encodeProof("0x01", publicInputs); const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -195,6 +243,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( wrongHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -213,6 +262,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -225,7 +275,12 @@ describe("BfvDecryptionVerifier", function () { const bfvDecryptionVerifier = await ( await ethers.getContractFactory("BfvDecryptionVerifier") - ).deploy(mockAddr, ethers.id("wrong-c6"), ethers.id("wrong-c7")); + ).deploy( + mockAddr, + ethers.id("wrong-c6"), + ethers.id("wrong-c7"), + THRESHOLD, + ); await bfvDecryptionVerifier.waitForDeployment(); const messageCoeffs = [1n, 2n, 3n]; @@ -235,6 +290,7 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(false); @@ -255,12 +311,13 @@ describe("BfvDecryptionVerifier", function () { const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(true); }); - it("returns true with minimal public inputs (vk hashes + message tail)", async function () { + it("returns true with exact-length public inputs", async function () { const { bfvDecryptionVerifier, mockCircuit } = await loadFixture( deployWithMockCircuit, ); @@ -269,13 +326,14 @@ describe("BfvDecryptionVerifier", function () { const messageCoeffs = [1n, 2n, 3n]; const publicInputs = buildPublicInputsWithMessage( messageCoeffs, - MESSAGE_COEFFS_COUNT + 2, + EXPECTED_PUBLIC_INPUTS_LEN, ); const plaintextHash = plaintextToHash(messageCoeffs); const proof = encodeProof("0x01", publicInputs); const result = await bfvDecryptionVerifier.verify.staticCall( plaintextHash, + ethers.ZeroHash, proof, ); expect(result).to.equal(true); diff --git a/packages/enclave-contracts/test/BfvPkVerifier.spec.ts b/packages/enclave-contracts/test/BfvPkVerifier.spec.ts index c2d24dbf57..88f81fb1a1 100644 --- a/packages/enclave-contracts/test/BfvPkVerifier.spec.ts +++ b/packages/enclave-contracts/test/BfvPkVerifier.spec.ts @@ -7,6 +7,7 @@ import { expect } from "chai"; import { network } from "hardhat"; import MockCircuitVerifierModule from "../ignition/modules/mockSlashingVerifier"; +import { BFV_DKG_H } from "../scripts/utils"; import { BfvPkVerifier__factory as BfvPkVerifierFactory, MockCircuitVerifier__factory as MockCircuitVerifierFactory, @@ -17,6 +18,32 @@ const { loadFixture } = networkHelpers; const EXPECTED_NODES_FOLD_KEY_HASH = ethers.id("nodes_fold"); const EXPECTED_C5_KEY_HASH = ethers.id("c5"); +/** Must match `BfvPkVerifier.h` / default circuit `H`. */ +const H = BFV_DKG_H; +const DKG_RETURN_FIELD_COUNT = 8; + +function committeeHashLimbs(committeeHash: string): [string, string] { + const bn = BigInt(committeeHash); + const hi = ethers.toBeHex(bn >> 128n, 32); + const lo = ethers.toBeHex(bn & ((1n << 128n) - 1n), 32); + return [hi, lo]; +} + +function minimalDkgPublicInputs( + pkCommitment: string, + committeeHash: string = ethers.ZeroHash, +): string[] { + const [hi, lo] = committeeHashLimbs(committeeHash); + return [ + EXPECTED_NODES_FOLD_KEY_HASH, + EXPECTED_C5_KEY_HASH, + ...Array(H).fill(ethers.ZeroHash), + hi, + lo, + ...Array(DKG_RETURN_FIELD_COUNT - 1).fill(ethers.ZeroHash), + pkCommitment, + ]; +} function encodeProof(rawProof: string, publicInputs: string[]): string { const abiCoder = ethers.AbiCoder.defaultAbiCoder(); @@ -33,7 +60,7 @@ describe("BfvPkVerifier", function () { const bfvPkVerifier = await ( await ethers.getContractFactory("BfvPkVerifier") - ).deploy(mockAddr, EXPECTED_NODES_FOLD_KEY_HASH, EXPECTED_C5_KEY_HASH); + ).deploy(mockAddr, EXPECTED_NODES_FOLD_KEY_HASH, EXPECTED_C5_KEY_HASH, H); await bfvPkVerifier.waitForDeployment(); const pk = BfvPkVerifierFactory.connect( @@ -51,7 +78,11 @@ describe("BfvPkVerifier", function () { const invalidProof = "0xdeadbeef"; await expect( - bfvPkVerifier.verify.staticCall(pkCommitment, invalidProof), + bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + invalidProof, + ), ).to.be.revert(ethers); }); @@ -60,7 +91,11 @@ describe("BfvPkVerifier", function () { const pkCommitment = ethers.keccak256("0x1234"); const proof = encodeProof("0x01", []); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -69,7 +104,64 @@ describe("BfvPkVerifier", function () { const pkCommitment = ethers.keccak256("0xabcd"); const proof = encodeProof("0x01", [pkCommitment]); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); + expect(result).to.equal(false); + }); + + it("returns false when publicInputs has trailing elements past expected length", async function () { + const { bfvPkVerifier } = await loadFixture(deployWithMockCircuit); + const pkCommitment = ethers.keccak256("0xabcd"); + const proof = encodeProof("0x01", [ + ...minimalDkgPublicInputs(pkCommitment), + ethers.ZeroHash, + ]); + + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); + expect(result).to.equal(false); + }); + + it("returns false when publicInputs has only pub params (length 7, no return fields)", async function () { + const { bfvPkVerifier } = await loadFixture(deployWithMockCircuit); + const pkCommitment = ethers.keccak256("0xabcd"); + const [hi, lo] = committeeHashLimbs(ethers.ZeroHash); + const proof = encodeProof("0x01", [ + EXPECTED_NODES_FOLD_KEY_HASH, + EXPECTED_C5_KEY_HASH, + ...Array(H).fill(ethers.ZeroHash), + hi, + lo, + pkCommitment, + ]); + + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); + expect(result).to.equal(false); + }); + + it("returns false when publicInputs has only vk hashes (no pkCommitment slot)", async function () { + const { bfvPkVerifier } = await loadFixture(deployWithMockCircuit); + const pkCommitment = ethers.keccak256("0xabcd"); + const proof = encodeProof("0x01", [ + EXPECTED_NODES_FOLD_KEY_HASH, + EXPECTED_C5_KEY_HASH, + ]); + + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -81,7 +173,11 @@ describe("BfvPkVerifier", function () { EXPECTED_C5_KEY_HASH, ]); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -97,17 +193,23 @@ describe("BfvPkVerifier", function () { await revertingVerifier.getAddress(), EXPECTED_NODES_FOLD_KEY_HASH, EXPECTED_C5_KEY_HASH, + H, ); await bfvPkVerifier.waitForDeployment(); const pkCommitment = ethers.keccak256("0xabcd"); - const proof = encodeProof("0x01", [ - ethers.id("wrong-nodes-fold"), - EXPECTED_C5_KEY_HASH, - pkCommitment, - ]); + const proof = encodeProof( + "0x01", + minimalDkgPublicInputs(pkCommitment).map((v, i) => + i === 0 ? ethers.id("wrong-nodes-fold") : v, + ), + ); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -123,17 +225,23 @@ describe("BfvPkVerifier", function () { await revertingVerifier.getAddress(), EXPECTED_NODES_FOLD_KEY_HASH, EXPECTED_C5_KEY_HASH, + H, ); await bfvPkVerifier.waitForDeployment(); const pkCommitment = ethers.keccak256("0xabcd"); - const proof = encodeProof("0x01", [ - EXPECTED_NODES_FOLD_KEY_HASH, - ethers.id("wrong-c5"), - pkCommitment, - ]); + const proof = encodeProof( + "0x01", + minimalDkgPublicInputs(pkCommitment).map((v, i) => + i === 1 ? ethers.id("wrong-c5") : v, + ), + ); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -145,13 +253,13 @@ describe("BfvPkVerifier", function () { const pkCommitment = ethers.keccak256("0xabcd"); const wrong = ethers.keccak256("0x1234"); - const proof = encodeProof("0x01", [ - EXPECTED_NODES_FOLD_KEY_HASH, - EXPECTED_C5_KEY_HASH, - wrong, - ]); + const proof = encodeProof("0x01", minimalDkgPublicInputs(wrong)); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -162,13 +270,13 @@ describe("BfvPkVerifier", function () { await mockCircuit.setReturnValue(false); const pkCommitment = ethers.keccak256("0xabcd"); - const proof = encodeProof("0x01", [ - EXPECTED_NODES_FOLD_KEY_HASH, - EXPECTED_C5_KEY_HASH, - pkCommitment, - ]); + const proof = encodeProof("0x01", minimalDkgPublicInputs(pkCommitment)); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); @@ -179,17 +287,22 @@ describe("BfvPkVerifier", function () { const bfvPkVerifier = await ( await ethers.getContractFactory("BfvPkVerifier") - ).deploy(mockAddr, ethers.id("wrong-nodes-fold"), ethers.id("wrong-c5")); + ).deploy( + mockAddr, + ethers.id("wrong-nodes-fold"), + ethers.id("wrong-c5"), + H, + ); await bfvPkVerifier.waitForDeployment(); const pkCommitment = ethers.keccak256("0xabcd"); - const proof = encodeProof("0x0102", [ - EXPECTED_NODES_FOLD_KEY_HASH, - EXPECTED_C5_KEY_HASH, - pkCommitment, - ]); + const proof = encodeProof("0x0102", minimalDkgPublicInputs(pkCommitment)); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(false); }); }); @@ -202,14 +315,13 @@ describe("BfvPkVerifier", function () { await mockCircuit.setReturnValue(true); const pkCommitment = ethers.keccak256("0xabcd"); - const proof = encodeProof("0x0102", [ - EXPECTED_NODES_FOLD_KEY_HASH, - EXPECTED_C5_KEY_HASH, - "0x" + "00".repeat(32), - pkCommitment, - ]); + const proof = encodeProof("0x0102", minimalDkgPublicInputs(pkCommitment)); - const result = await bfvPkVerifier.verify.staticCall(pkCommitment, proof); + const result = await bfvPkVerifier.verify.staticCall( + pkCommitment, + ethers.ZeroHash, + proof, + ); expect(result).to.equal(true); }); }); diff --git a/packages/enclave-contracts/test/BfvVkBindingIntegration.spec.ts b/packages/enclave-contracts/test/BfvVkBindingIntegration.spec.ts index a437d063fe..d3f1897fa8 100644 --- a/packages/enclave-contracts/test/BfvVkBindingIntegration.spec.ts +++ b/packages/enclave-contracts/test/BfvVkBindingIntegration.spec.ts @@ -7,13 +7,20 @@ import { expect } from "chai"; import { network } from "hardhat"; import fs from "node:fs"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { BFV_DECRYPTION_SUB_CIRCUIT_VK_HASH_PATHS, + BFV_DKG_H, BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS, - REPO_ROOT, + BFV_THRESHOLD_T, assertBfvDecryptionVerifierSubCircuitVkHashes, assertBfvPkVerifierSubCircuitVkHashes, + bfvDecCommitteeHashIndices, + bfvDecExpectedPublicInputsLen, + bfvDkgCommitteeHashIndices, + bfvPkExpectedPublicInputsLen, + committeeHashFromLimbs, readVkRecursiveHash, } from "../scripts/utils"; import type { BfvDecryptionVerifier, BfvPkVerifier } from "../types"; @@ -21,11 +28,69 @@ import type { BfvDecryptionVerifier, BfvPkVerifier } from "../types"; const { ethers, networkHelpers } = await network.connect(); const { loadFixture } = networkHelpers; -const INTEGRATION_SUMMARY = path.join( - REPO_ROOT, +const testDir = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.join(testDir, "../../.."); +const COMMITTED_FOLDED_ARTIFACTS_FIXTURE = path.join( + testDir, + "fixtures/bfv_vk_binding/folded_artifacts.json", +); +const INSECURE_INTEGRATION_SUMMARY = path.join( + repoRoot, "circuits/benchmarks/results_insecure/integration_summary.json", ); +type FoldedArtifacts = { + dkg_aggregator: { proof_hex: string; public_inputs_hex: string }; + decryption_aggregator: { proof_hex: string; public_inputs_hex: string }; +}; + +const isValidFoldedArtifacts = (value: unknown): value is FoldedArtifacts => { + if (value === null || typeof value !== "object") { + return false; + } + const folded = value as FoldedArtifacts; + return ( + typeof folded.dkg_aggregator?.proof_hex === "string" && + typeof folded.dkg_aggregator?.public_inputs_hex === "string" && + typeof folded.decryption_aggregator?.proof_hex === "string" && + typeof folded.decryption_aggregator?.public_inputs_hex === "string" + ); +}; + +const readFoldedArtifactsFromFile = ( + filePath: string, +): FoldedArtifacts | null => { + if (!fs.existsSync(filePath)) { + return null; + } + const parsed: unknown = JSON.parse(fs.readFileSync(filePath, "utf8")); + if (filePath.endsWith("integration_summary.json")) { + const summary = parsed as { folded_artifacts?: unknown }; + return isValidFoldedArtifacts(summary.folded_artifacts) + ? summary.folded_artifacts + : null; + } + return isValidFoldedArtifacts(parsed) ? parsed : null; +}; + +/** Prefer env override, then fresh insecure benchmark output, then committed fixture. */ +const resolveFoldedArtifacts = (): FoldedArtifacts | null => { + const envPath = process.env.BFV_VK_BINDING_FOLDED_ARTIFACTS; + if (envPath) { + return readFoldedArtifactsFromFile(envPath); + } + const fromBenchmark = readFoldedArtifactsFromFile( + INSECURE_INTEGRATION_SUMMARY, + ); + if (fromBenchmark !== null) { + return fromBenchmark; + } + return readFoldedArtifactsFromFile(COMMITTED_FOLDED_ARTIFACTS_FIXTURE); +}; + +const loadFoldedArtifacts = (): FoldedArtifacts | null => + resolveFoldedArtifacts(); + const hasCompiledVkArtifacts = (): boolean => Object.values(BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS).every((p) => fs.existsSync(p), @@ -47,6 +112,12 @@ function hexToBytes32Array(hex: string): string[] { return out; } +const DKG_COMMITTEE_HASH_IDX = bfvDkgCommitteeHashIndices(BFV_DKG_H); +const DKG_EXPECTED_PUBLIC_INPUT_LEN = bfvPkExpectedPublicInputsLen(BFV_DKG_H); +const DEC_COMMITTEE_HASH_IDX = bfvDecCommitteeHashIndices(); +const DEC_EXPECTED_PUBLIC_INPUT_LEN = + bfvDecExpectedPublicInputsLen(BFV_THRESHOLD_T); + function plaintextHashFromPublicInputs(publicInputs: string[]): string { const messageCoeffsCount = 100; const offset = publicInputs.length - messageCoeffsCount; @@ -112,6 +183,7 @@ describe("BfvVkBindingIntegration", function () { await dkgAgg.getAddress(), expectedNodesFoldKeyHash, expectedC5KeyHash, + BFV_DKG_H, ); await bfvPk.waitForDeployment(); @@ -121,6 +193,7 @@ describe("BfvVkBindingIntegration", function () { await decAgg.getAddress(), expectedC6FoldKeyHash, expectedC7KeyHash, + BFV_THRESHOLD_T, ); await bfvDec.waitForDeployment(); @@ -140,6 +213,7 @@ describe("BfvVkBindingIntegration", function () { await bfvPk.circuitVerifier(), ethers.id("stale-nodes-fold"), ethers.id("stale-c5"), + BFV_DKG_H, ); await stale.waitForDeployment(); @@ -163,6 +237,7 @@ describe("BfvVkBindingIntegration", function () { await bfvDec.circuitVerifier(), ethers.id("stale-c6"), ethers.id("stale-c7"), + BFV_THRESHOLD_T, ); await stale.waitForDeployment(); @@ -180,30 +255,23 @@ describe("BfvVkBindingIntegration", function () { }); const runFoldedProofIntegration = - fs.existsSync(INTEGRATION_SUMMARY) && hasCompiledVkArtifacts(); + loadFoldedArtifacts() !== null && hasCompiledVkArtifacts(); (runFoldedProofIntegration ? it : it.skip)( "folded aggregator proofs: artifact VK hashes match publicInputs[0..1] and verify passes", async function () { this.timeout(120_000); - const summary = JSON.parse( - fs.readFileSync(INTEGRATION_SUMMARY, "utf8"), - ) as { - folded_artifacts: { - dkg_aggregator: { proof_hex: string; public_inputs_hex: string }; - decryption_aggregator: { - proof_hex: string; - public_inputs_hex: string; - }; - }; - }; + const folded = loadFoldedArtifacts(); + if (folded === null) { + this.skip(); + } const dkgPublicInputs = hexToBytes32Array( - summary.folded_artifacts.dkg_aggregator.public_inputs_hex, + folded.dkg_aggregator.public_inputs_hex, ); const decPublicInputs = hexToBytes32Array( - summary.folded_artifacts.decryption_aggregator.public_inputs_hex, + folded.decryption_aggregator.public_inputs_hex, ); const expectedNodesFoldKeyHash = readVkRecursiveHash( @@ -224,28 +292,54 @@ describe("BfvVkBindingIntegration", function () { expect(decPublicInputs[0]).to.equal(expectedC6FoldKeyHash); expect(decPublicInputs[1]).to.equal(expectedC7KeyHash); + if ( + dkgPublicInputs.length !== DKG_EXPECTED_PUBLIC_INPUT_LEN || + decPublicInputs.length !== DEC_EXPECTED_PUBLIC_INPUT_LEN + ) { + console.warn( + "Skipping folded proof verify: folded artifact public-input layout is stale. " + + "Re-run insecure benchmarks (syncs test/fixtures/bfv_vk_binding/folded_artifacts.json) " + + "or set BFV_VK_BINDING_FOLDED_ARTIFACTS.", + ); + this.skip(); + } + + const dkgCommitteeHash = committeeHashFromLimbs( + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.hi], + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.lo], + ); + const decCommitteeHash = committeeHashFromLimbs( + decPublicInputs[DEC_COMMITTEE_HASH_IDX.hi], + decPublicInputs[DEC_COMMITTEE_HASH_IDX.lo], + ); + const { bfvPk, bfvDec } = await deployHonkAndBfv(); const abiCoder = ethers.AbiCoder.defaultAbiCoder(); const dkgEncoded = abiCoder.encode( ["bytes", "bytes32[]"], - [summary.folded_artifacts.dkg_aggregator.proof_hex, dkgPublicInputs], + [folded.dkg_aggregator.proof_hex, dkgPublicInputs], ); const pkCommitment = dkgPublicInputs[dkgPublicInputs.length - 1]; - expect(await bfvPk.verify.staticCall(pkCommitment, dkgEncoded)).to.equal( - true, - ); + expect( + await bfvPk.verify.staticCall( + pkCommitment, + dkgCommitteeHash, + dkgEncoded, + ), + ).to.equal(true); const decEncoded = abiCoder.encode( ["bytes", "bytes32[]"], - [ - summary.folded_artifacts.decryption_aggregator.proof_hex, - decPublicInputs, - ], + [folded.decryption_aggregator.proof_hex, decPublicInputs], ); const plaintextHash = plaintextHashFromPublicInputs(decPublicInputs); expect( - await bfvDec.verify.staticCall(plaintextHash, decEncoded), + await bfvDec.verify.staticCall( + plaintextHash, + decCommitteeHash, + decEncoded, + ), ).to.equal(true); }, ); @@ -255,16 +349,13 @@ describe("BfvVkBindingIntegration", function () { async function () { this.timeout(120_000); - const summary = JSON.parse( - fs.readFileSync(INTEGRATION_SUMMARY, "utf8"), - ) as { - folded_artifacts: { - dkg_aggregator: { proof_hex: string; public_inputs_hex: string }; - }; - }; + const folded = loadFoldedArtifacts(); + if (folded === null) { + this.skip(); + } const dkgPublicInputs = hexToBytes32Array( - summary.folded_artifacts.dkg_aggregator.public_inputs_hex, + folded.dkg_aggregator.public_inputs_hex, ); const expectedC5KeyHash = readVkRecursiveHash( BFV_PK_SUB_CIRCUIT_VK_HASH_PATHS.c5, @@ -292,19 +383,32 @@ describe("BfvVkBindingIntegration", function () { const bfvPk = await ( await ethers.getContractFactory("BfvPkVerifier") - ).deploy(await dkgAgg.getAddress(), wrongNodesFold, expectedC5KeyHash); + ).deploy( + await dkgAgg.getAddress(), + wrongNodesFold, + expectedC5KeyHash, + BFV_DKG_H, + ); await bfvPk.waitForDeployment(); const abiCoder = ethers.AbiCoder.defaultAbiCoder(); const dkgEncoded = abiCoder.encode( ["bytes", "bytes32[]"], - [summary.folded_artifacts.dkg_aggregator.proof_hex, dkgPublicInputs], + [folded.dkg_aggregator.proof_hex, dkgPublicInputs], ); const pkCommitment = dkgPublicInputs[dkgPublicInputs.length - 1]; - - expect(await bfvPk.verify.staticCall(pkCommitment, dkgEncoded)).to.equal( - false, + const dkgCommitteeHash = committeeHashFromLimbs( + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.hi], + dkgPublicInputs[DKG_COMMITTEE_HASH_IDX.lo], ); + + expect( + await bfvPk.verify.staticCall( + pkCommitment, + dkgCommitteeHash, + dkgEncoded, + ), + ).to.equal(false); }, ); }); diff --git a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts index 0ac7414139..8b39e03453 100644 --- a/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/enclave-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -438,15 +438,10 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await registry.finalizeCommittee(0); // Publish committee (this triggers onCommitteePublished -> onCommitteeFormed) - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); // Verify stage transitioned to KeyPublished (after publishCommittee which calls onKeyPublished) stage = await enclave.getE3Stage(0); @@ -483,17 +478,10 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await registry.finalizeCommittee(0); // Publish committee and expect CommitteeFormed event - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await expect( - registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"), - ) + await expect(registry.publishCommittee(0, publicKey, pkCommitment, "0x")) .to.emit(enclave, "CommitteeFormed") .withArgs(0); }); @@ -749,14 +737,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); // 2. Wait past compute deadline → mark as failed const e3 = await enclave.getE3(0); @@ -853,14 +836,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); // 2. Fail via compute timeout const e3 = await enclave.getE3(0); @@ -1105,14 +1083,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); stage = await enclave.getE3Stage(0); expect(stage).to.equal(3); // KeyPublished @@ -1184,14 +1157,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); stage = await enclave.getE3Stage(0); expect(stage).to.equal(3); // KeyPublished @@ -1427,14 +1395,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); expect(await enclave.getE3Stage(0)).to.equal(3); // KeyPublished @@ -1558,14 +1521,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { expect(await enclave.getE3Stage(0)).to.equal(2); // CommitteeFinalized - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); expect(await enclave.getE3Stage(0)).to.equal(3); // KeyPublished @@ -1617,14 +1575,9 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(0); - const nodes = [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ]; const publicKey = "0x1234567890abcdef1234567890abcdef"; const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(0, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(0, publicKey, pkCommitment, "0x"); // Publish outputs const e3 = await enclave.getE3(0); diff --git a/packages/enclave-contracts/test/Enclave.spec.ts b/packages/enclave-contracts/test/Enclave.spec.ts index 8535215348..01790ce68b 100644 --- a/packages/enclave-contracts/test/Enclave.spec.ts +++ b/packages/enclave-contracts/test/Enclave.spec.ts @@ -79,7 +79,6 @@ describe("Enclave", function () { const setupAndPublishCommittee = async ( registry: any, e3Id: number, - nodes: string[], publicKey: string, operators: Signer[], committeeProof: string = "0x", @@ -92,7 +91,6 @@ describe("Enclave", function () { const pkCommitment = ethers.keccak256(publicKey); await registry.publishCommittee( e3Id, - nodes, publicKey, pkCommitment, committeeProof, @@ -825,17 +823,11 @@ describe("Enclave", function () { proofAggregationEnabled: false, }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); @@ -860,17 +852,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration + timeoutConfig.computeWindow, }); @@ -900,17 +886,11 @@ describe("Enclave", function () { proofAggregationEnabled: false, }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await expect( enclave.publishCiphertextOutput(e3Id, "0x", "0x"), @@ -933,17 +913,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); expect(await enclave.publishCiphertextOutput(e3Id, data, proof)); const e3 = await enclave.getE3(e3Id); @@ -966,17 +940,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); expect( await enclave.publishCiphertextOutput.staticCall(e3Id, data, proof), @@ -999,17 +967,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await expect(enclave.publishCiphertextOutput(e3Id, data, proof)) .to.emit(enclave, "CiphertextOutputPublished") @@ -1044,17 +1006,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await expect( enclave.publishPlaintextOutput(e3Id, data, "0x"), ).to.be.revertedWithCustomError(enclave, "InvalidStage"); @@ -1076,17 +1032,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); await enclave.publishPlaintextOutput(e3Id, data, proof); @@ -1116,11 +1066,6 @@ describe("Enclave", function () { await setupAndPublishCommittee( ciphernodeRegistryContract, e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], data, [operator1, operator2, operator3], encodeMockDkgProof(pkCommitment), @@ -1148,17 +1093,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); expect(await enclave.publishPlaintextOutput(e3Id, data, proof)); @@ -1183,17 +1122,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); expect( @@ -1217,17 +1150,11 @@ describe("Enclave", function () { inputWindow: [(await time.latest()) + 20, (await time.latest()) + 100], }); - await setupAndPublishCommittee( - ciphernodeRegistryContract, - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - [operator1, operator2, operator3], - ); + await setupAndPublishCommittee(ciphernodeRegistryContract, e3Id, data, [ + operator1, + operator2, + operator3, + ]); await mine(2, { interval: inputWindowDuration }); await enclave.publishCiphertextOutput(e3Id, data, proof); await expect(await enclave.publishPlaintextOutput(e3Id, data, proof)) diff --git a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts index c1f303ec29..58eb888211 100644 --- a/packages/enclave-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/enclave-contracts/test/Pricing/Pricing.spec.ts @@ -141,7 +141,7 @@ describe("E3 Pricing", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(e3Id); const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee(e3Id, nodes, publicKey, pkCommitment, "0x"); + await registry.publishCommittee(e3Id, publicKey, pkCommitment, "0x"); }; const setup = async () => { diff --git a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts index ea53846141..7ff7603198 100644 --- a/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts +++ b/packages/enclave-contracts/test/Registry/CiphernodeRegistryOwnable.spec.ts @@ -424,19 +424,7 @@ describe("CiphernodeRegistryOwnable", function () { await finalizeCommitteeAfterWindow(registry, 0); await expect( - registry - .connect(notTheOwner) - .publishCommittee( - 0, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - dataHash, - "0x", - ), + registry.connect(notTheOwner).publishCommittee(0, data, dataHash, "0x"), ) .to.emit(registry, "CommitteePublished") .withArgs( @@ -474,17 +462,7 @@ describe("CiphernodeRegistryOwnable", function () { await registry.connect(operator3).submitTicket(0, 1); await finalizeCommitteeAfterWindow(registry, 0); - await registry.publishCommittee( - 0, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - dataHash, - "0x", - ); + await registry.publishCommittee(0, data, dataHash, "0x"); expect(await registry.committeePublicKey(0)).to.equal(dataHash); }); it("emits a CommitteePublished event", async function () { @@ -511,19 +489,7 @@ describe("CiphernodeRegistryOwnable", function () { await registry.connect(operator3).submitTicket(0, 1); await finalizeCommitteeAfterWindow(registry, 0); - await expect( - await registry.publishCommittee( - 0, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - dataHash, - "0x", - ), - ) + await expect(await registry.publishCommittee(0, data, dataHash, "0x")) .to.emit(registry, "CommitteePublished") .withArgs( 0, @@ -694,17 +660,7 @@ describe("CiphernodeRegistryOwnable", function () { await registry.connect(operator3).submitTicket(e3Id, 1); await finalizeCommitteeAfterWindow(registry, e3Id); - await registry.publishCommittee( - e3Id, - [ - await operator1.getAddress(), - await operator2.getAddress(), - await operator3.getAddress(), - ], - data, - dataHash, - "0x", - ); + await registry.publishCommittee(e3Id, data, dataHash, "0x"); expect(await registry.committeePublicKey(e3Id)).to.equal(dataHash); }); it("reverts if the committee has not been published", async function () { diff --git a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts index bc4bf24e99..032c50a070 100644 --- a/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts +++ b/packages/enclave-contracts/test/Slashing/CommitteeExpulsion.spec.ts @@ -342,16 +342,9 @@ describe("Committee Expulsion & Fault Tolerance", function () { await time.increase(SORTITION_SUBMISSION_WINDOW + 1); await registry.finalizeCommittee(e3Id); - const nodes = await Promise.all(operators.map((op) => op.getAddress())); const publicKey = ethers.toUtf8Bytes("fake-public-key"); const pkCommitment = ethers.keccak256(publicKey); - await registry.publishCommittee( - e3Id, - nodes, - publicKey, - pkCommitment, - "0x", - ); + await registry.publishCommittee(e3Id, publicKey, pkCommitment, "0x"); } // ── Return ───────────────────────────────────────────────────────────────── diff --git a/packages/enclave-contracts/test/fixtures/bfv_vk_binding/README.md b/packages/enclave-contracts/test/fixtures/bfv_vk_binding/README.md new file mode 100644 index 0000000000..c289ecab3e --- /dev/null +++ b/packages/enclave-contracts/test/fixtures/bfv_vk_binding/README.md @@ -0,0 +1,25 @@ +# BFV VK binding fixtures + +Golden `dkg_aggregator` / `decryption_aggregator` EVM proofs for +`test/BfvVkBindingIntegration.spec.ts` (insecure micro preset). + +## Automatic refresh + +After an insecure benchmark run that writes +`circuits/benchmarks/results_insecure/integration_summary.json`, +`circuits/benchmarks/scripts/run_benchmarks.sh` calls +`sync_bfv_vk_binding_fixture.sh` and updates this directory’s +`folded_artifacts.json`. + +`BfvVkBindingIntegration` also reads `integration_summary.json` directly when +present, so local `pnpm evm:test` stays aligned even before you commit the +synced fixture. + +## Manual override + +```bash +./circuits/benchmarks/scripts/sync_bfv_vk_binding_fixture.sh +``` + +Or set `BFV_VK_BINDING_FOLDED_ARTIFACTS` to a folded-artifacts JSON file (or an +`integration_summary.json` containing `.folded_artifacts`). diff --git a/packages/enclave-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json b/packages/enclave-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json new file mode 100644 index 0000000000..fe5f7e9a14 --- /dev/null +++ b/packages/enclave-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json @@ -0,0 +1,10 @@ +{ + "dkg_aggregator": { + "proof_hex": "0x000000000000000000000000000000000000000000000001104c69c76ea8f5f6000000000000000000000000000000000000000000000005c85075d6baa615c900000000000000000000000000000000000000000000000eb6de0b1c015f0f2a0000000000000000000000000000000000000000000000000002a0b5c2857c800000000000000000000000000000000000000000000000036176084b0205127a000000000000000000000000000000000000000000000004549377f025fd0f40000000000000000000000000000000000000000000000003ff07c8a94fbdbbd8000000000000000000000000000000000000000000000000000185ecac0421330000000000000000000000000000000000000000000000044f1f17a53eba29b1000000000000000000000000000000000000000000000004096147c1d40da636000000000000000000000000000000000000000000000007c2eaade9aae157c100000000000000000000000000000000000000000000000000023ccf2dca92b000000000000000000000000000000000000000000000000e02d12f90edb8cac6000000000000000000000000000000000000000000000007c223713eba54496600000000000000000000000000000000000000000000000ec928a9ef7dcf2da9000000000000000000000000000000000000000000000000000282e9bb83bee61a05d33c39ba3812376a494cad4c46e07e18763a4c0cc37c7ac2f3635530c6110f00693d937276e524dafd5fffac373d40ca9ac38bc4003aa97fa25c28eaae471e6801e127832204ea5a325f05bb8550bd90338e17663499f9908e07c1a27a4d25db068d58486c5ed1d571b154613b2a444f9ef333d6490c341531f43898470028e20e0d46d87d6e6a8c672bd88dbdbae7c0e0a9d06da0323fdaf7ee61ceb7611d45afd3c8ec55431dab1b693939c2a7f313b832a28959c3ae3d30629655cc051ff1a5efe96161c60a46f240cb6ca1a531353aec9b48b52ad525bf6481f17e0923676a74fc00629f08348ca4b4467e32b7907ccf75e78538096134b580c00ad016d8f24d8b2251a384465ecf7da74301f64008beb9c8b71af609a0085afa8bb10891080d365806d9ed9f21901108254290c057a4b986687bebd3eae86d9d84d52ba59894f06a73d164ff99fcb0d13873279ce4f307eef63d2c0ba38c4624e95e009c113dba40ba429e2620e10806283dd5fad8df1b6a85051c1f7167194c70620f370484b9bd06cf6e6199ccd69d2c0e0db004474b4ffc62084f7697d21fc04f1518380c30df7edd6752046611f209863dd69ccbd4af39b35e05dbaa35d7aea81dac6609d0b9b649962dd23bd220709758af7743abf5395724f809100dfd19cb13ee772bc80efdcb985314bbe58feda8ac8cb79523fe9ff183ebf3e6835eff81084ebea45358443421fb0f2d31a11171c0537eaf216aa68a5bfefa0d02b1c5b92a10ac9238f294ee18007a6f18f72214951c398ce84c3616bcf3c79e0f2e2f022a0c90527061c47a42c43cace4fc879a5a326863a6f82d9c6bb420290aa900d8244a98b1668bcfcb6023d101fde9f2fa579bbd8947480f7058466d6000b38c5c1a4fd3aa5794aad136c957e92be80cca60120b6d839e54f1036f9e857e14746f2433e79c2a2df9f7ea53e60405fe812eb086dfac1f0b0c638610dbdd208a28f2260c558292be011ce1ad7ea6fc1a18428a3199764be0e5e4169e261b655ffddd06ca1104a26cac71683ee832dcd3cac2ca05e81de30bed5f8b67ce620c6f88f62d90a64a9659cd90458edbd62bb6cc9f8d942669ccb243386ee53c938746a2462ab0830a5ee749ccf6259eb0ddd308297e3093c1e2bf8454dd5e900345907a8608b9832d8e40d08cb3dbf14939398e8c032b1baf82f3b45da26fc2aa8a69639d1379060a52801809840916499ab8679e0af7fa2b5e549f58ddfc8c60090ad5d42fcf59ab9661b29f6aee13a20e279602925e6fffb2328ef1334585e819ea8002085571a91540444e60b8c9350331f5cdfe8ba889466f4b26343d3b179b436d1015fdbeb6b1586fec95a850abe17e3d23dbb519b068c9c59ed740833e71319db516be4631e64a10edbbdfac8daafe9004a1dfb5631249e558132163eb6429c715143679b05e2edc9c236a9a7ca760761c3a117bb03755bf8d04aefc7742ab0ba811710087242ad211047ff4f6b9c4f8faa4640f53721a400815c301a8b079d1ca2b7184bc65e7bc3cd2c380df2376ec233411c4d429fb12795cdaa8b932bff94628703868796573c773ba5a60dbe2dcfdba86fbf73e2cbabe306511dd6f71509607ebc04687500585f37d8135ebac5386803439c01b36e449d3b029c1576fc2f422160f4fa03d8f11c89e134103a7918939563aad5285049c66b3479d416852b11896f8b31c6d91580c0cc03bd04ef40a9b201d686cbfec6170ee5a1aace7c7f2248c548038c030a7c267fe72915cd397e273c42561e11410672a1e41f71827eb247b679c4eebf11bf064f256f418ef2364b7eaa29fa9cfbf018eef1952daebd915d423652908cbd25b28b3b07d28cc918af5ac73226b02d6340d02ee74f643db15c870a4de33c870580fb55142ed86a7b1efb02d4f5d1d6e074137126f61818d0dce8e49b8aff13f2e80fa7d585aff6147ee7265bc92df749635d9cd77bfb87508e4dd08b4f437bb59702e34ec8c390bf6e7455a4619bb3586688b16e1045a9c0c8d0b760cf3d11357e9840fd3e702cce25045c7835bb1b0ce6275af5571d18d1e90731123ccd8bb5b7550b8ba901f3e94958acb3e9583067cdaf68cd913726817755888db2a7a28e1a4748b9ede248fe0ef76aa51bf8e5eaca3049ac9dd7984241212bdbe5b3d0d4b586a7f468056893fbdde4c94203e8ff8238fa1a028ab2b059669f73b36030f5205fcc5958017fd26f9fa8d827b6cf11aee31fa922e8f0c21c5cccf059ac7d29e54a4df6f1e43b8a4b22689859e8569dc98990b9fd1d1b2222e19e76cbb31fff18fcf40798cf42482bc063795fa19dfe65eb6e9a570b4c41e85f9c94ff56701adabc0cdb76def2f5770270aa236e1be1c18ed64e51cdc911a1133e096a0272e0675c680fe24f2cb4f9a201401977945b920b02e60c84f3309e8ba8688c6e982bc9357327d438c5d34986a3ee5c88fc5886a4c66f1d14ef625d0aa01c82cf320cb1543887eea14b4481733f213beaef47ad92251eb2910bb1c23b4c930200102e6ec848b5470cc88a0204f6d4a9aaa1cb29e808e3cf2cc7622ea3e6a331b26e1d2a78f90b99066780df63afffc89bb080ef954828fc64a9b0e589c3d02f1f8f8c03919178dcd7138e1381f54749a684c6c7f852b0e85251427b6dad8334cd11f9f2e16ab2d7654d1dad887e5dce9d872887c6dc9d07f45481835c2ae47a1c0c9b680a009ce8218506f77c3b8b62654b8fb93043f60dca8992c4ca79d52dc8431a240cc5d01a027438fa19c91f638b7cddd6db1a1f6faedbe1c7eda2cda8637e7e0a2f49d2ad0109f7a5bbbadf6c8478ba78e716fab26944e182e437f00afe8873f1030439bfed6f6bb3abc39bd1882eb2b6eda0078c680e924d942cd5b55449783c3a8f192e24aaa6c305167959fe1cf58e9065a7784325c2d0fe06c3e064f99ebc1570a82cd43c33ea443971e0f434ac11883fe84461b9821746609c618a3362bf051334253a22ae38e9b6773a528204c0797297835f3f61549c8cd8ad16bb415ada181c52d843d558dea5cd548c3823ac4e3d6df1838e0073102582f62d7dc0ac66710e9d0e8826ef77755403b7f12a2863faac6dfe4cb1914e29db1b956406e9f46ba2653617ac8ede05dfb69035dca3ee5c2d00d3a612ec25b4fe71e06659ef23bb53a839b6ee48c4e38207109e68d3e073fef16eb062dcc3a22a15afb381581cd7e9db2c78f2b801ef7104a5ffb41dce92caeebf6141190682aae5ce74e6b6adc7c901eb6db76c548746b9170a1c81930149032b19c0c0ab947223f7d82d1f7fe5930eb75cb6dd0bf5394a906376146da02731747ba17ee40b5061140ddbffbf7b01d0e6661cb6d3cca9eeca0a0c4640c5d61c72d9819f1b54c8878b1cacc853f1ca2e3ef455bd082bf5bf60e4b13ba7569e7804d5b1442193595af32b92e91b90c7f7c9999f7c665a9c7a7f5911d73d415c3339c6f0a968a68b6475c1dabe40dd46087630e1fabf2155f2017e4fb42180a3319e7d7063c027b22b6b8389f83c9aba5a25fcb0cee256c1c16760db9bdec0c82d90800249d026ad7e4fa1f8635c4ee66ac2ecc8ac01ec76d44981128e4000cd5a529b4011b6145ece1a1d5404a453d8f28fb6ecedf4584fc8a952cb6f9d6df93cafcd21eac2a8b63973d1643a07daf8ac82dd5b054c0d25445e09978693ac63ee2de6516fc2b9c0d2c59aa561b6029edfe22e85ec79edb34bdc7617ba11cf3d4c0f02b13c2eeb3c0faa2fd0592f8303ed4bac9e9f81e7c627493f4a334c539b8acd96f02bc66d56f149f0139979ef02b7f584ae703925e664182e410729af2b9675cb406169d27e032bfcc6e540bd4b7b1b11054f83ac31d5c5013e0ac3f6d6e6a97ec1b08b22c0d8fcec02e23c3d2f56227fdf155a9a7c363854deaecc5321bc94fc52e50df9ac72c04b4fb74cbf7cd86c427f9049ea0123dbabed674a4e2de9652290ddbf03a1835d5a92ae4ef3237137432ccc8146c33fbd50155eb4e68cabd0208196843c201f2ed0ff53d389b7845fe62eb1e873c6f5c9c1216ad8ffdfeadfb1718e74c50fe500225ee24b08374d2a8b7fc17d324f50220961759194b39f844b12739e80621a5960316675859bed49ede417bf5a5acc2e4b364b70bb92683986c1df944a9a3b8cc87e3951e156af6abca648b28be2b74e6df59df0801edc236b129ba40af8c1c9f93b26fd9a45d102fa7bf90e7f51f14dd59d241c4327642134210376431209d2593785a6a4a6f042505387ab87daf614bbafce0a71426a7e26d2ebe8f7a36e23272d68e4396afe0eb899fe01103e5190ad987834ca9971bed9c1030fa67d27207d4a97e2583383f5904f0a0ef868a6b8a0a2c85fe1c9554e620130e6c08293a578b5a28ea7c0021ceb00c5e4e171a08f2097216d3dced274a6407868f61297f9fe9e95cfa52375e1390c2a034d849bbce454638828ee58aec0b0e171dadb3c2ba34e649b6df427a1a22ec81e2406de5d9d3db670db9198fc1070ef752419ede5f9973c2105bfba9ccb21d5e02ea1e13024a8072d8d2816018970bb8e226425c4c82771c7400941b55dac1a82c6ee13100d8bda00bab5a6d4e0111f101af580b036e177b7e88d70ebf1f57d3d9869f488de7ef2e41923a71cda5153c0f99aa741088d700453e078bda0ac7cf72c4d40e5755f51e9f972d5193161ffbef1f56c0eaf0507bfe67e000aa14c77e2fc597669522fd7553bc3a340e622190378956119d6213836b644a25648d9b3463ff256fa07f431fb1254f38a2540d7d8d1ba4d4000d5470105399683fa97f32adc17549946b7d4e33a06085ea451bb9b0d600fe3202fa84f96bbe9895918438d9d23440f5d086cb4624eefc7a2c09554cefe010fc8412f7dea624ecba0b778302ee742b84e396dc43d3c76eb2b10567ee21da53b51452ef279344c3f4cf1797576436ef727f496641913bc0f28b2dd03f71184034d502788de0d7d8caa15ab98c454d2676e297017823c35c061419bd9a63ba9deda91b4a7f5cc27883af1ce981a40998cb00af959ef782a4971b2bdfd91e38d7045ff5b399c5c097e014ee9959edff45d11affda024527b1c03417b6609dd14487de0f2ab328f2c7066e2fe3d18fdad528fa097746a24139bfcd1361368052ae8ebd22969612d971a162c5cd161da46aefa32d4b540937b80ee404eae6eb13a39ce56f8fff92b54da51403fdfcf7946dd8a43ce26cdccee842af2f6eb15827f305af101464d910fb943488e0e5ba33853c6206eddceb9e2575bf15ab59f5b519e3023a368f7c1584b1f9e4e185f05cdf6b4ae976f075d4db94882711c2ab8e50b028f8f181b95604247e18cefb32c187176e0c4264b9d9e78f7c053277dd97cae1eb03dcf68ccb9c14d6f77256486d60a6ef3c8dfc54254ae5d317284ed44a8c2ef6ddf4aec97a529d841a43fdf3bff0d07776383574af343a6b2504328a61ae7607b1e792ad94fd63e0f5f7a714febd8866ecf4e93be767a16f2c6a4302ed3c88f3e59bf92c5343617ad9051655cd702ff03e0a52af7f0759fa18826dd0d6c0d6b9b58a943c485c911cc2e83d683725ff800e4f44dea9e5747c064f56dec7c38e976a8667949d972a1e8d5cf265e4f07d86e2bd4c2706fea5e50780f6bbcf004fad574131b2a5d060402b25a79ba39adebc44adec286e2641d02c06eb8264faccb1c5ba4cfe130df3ea472e3ad9df249f14eb4db5f2a7b1bc271d67455ab068c58b17a0eb2445f60d9788b899e3779594819895fadc61cc2e080daff29cee7c04c152928572b235c790f229121bf087c155efff507d086f273f11769248554252c8d5972cc79eb93724ca839565986fd0d23149a7d428b2eb18206374aaf52de2629a8215536912ce04303d8308cbe65b8b76a963b097519a531615325c2fd7a1cdd84daeaea5f0951ba4421342db3b0225bd35b659e31cff10180bd6dc65a34a851c7c9d943c9a600c76aa179626a52d8e9f77fb03b5f03100037dc56ffa38081b2a6db99e9299075f3b2c4cf6039d9586cbf123bb759bdb130475385704108ec22012b4742792a05037da6aaa56e84da60c467ea7d3a908e81d7ecf0f95150be7f4d5dec9a1dd9dc832495542d1c376395c5e7aa334e020a21b28b9245119102fd119e81c340311a9ae3749ba3384ba0f1204f6293e3937dc0eeb2fd7a2ac724da6224dfd2dbec16d3a3af4c70ef9ffc653a52eab8d1693a61bf5633124ef3a8eec373e13373abc59d5993e616593eba7dbb5e248ff802881102c6eb060d5d2b8968e9eef372763ca5183b873e5a581e9e865f47b6028bff71c19cd3c08fd68a23f0d9c99aab607387b9c6ec678f9455616311768fa832a5204da68b4a1d18935ff4523e6cf72b1850132058c7f150c2e126196b6723f19ad2fb8db2bfb259f034348221b3d3f87b85780619a6d54e67cf0a55965862b7fe52e23144adc595bc2be1a48f1c1cc41b41dd9da0dbe5adef141730e340d04585616328ade11c06b5003e195f1e3dab9003fa8013ffd3f7e6a67c1f51ebf65dad418a861e2f11f2ffe125ce67efb0eb74f33bd131b5a5d11b6446a8b3fa207ed8b2285a3475847e33e625ed4e7d6533778b595aff6607586bb0412d8210fe340552e3583fceba101476b4fd039726118ac87f80df3cba443836dc2a53fd6fcd34e0e18d5690c79a9e9db8026bb60f070b81acd43c1e5f7030ea7dd2d61bff42ea430279ed1125758d018a344fb17c2592a3d2c34594303a65937825b43c263ceff01c029ef10cc78125dd9f4a55a19c460e1ad391a367f976c8d14a2fb91320efe28825a32c3b76a082a9e42428bac2e25c4892681860db150836148b3b1fdb13d1f64fd78bb318ce7387682b34c821bedafa127f2556a9c2687178ebe195756f609fe81400fb471b4fb1d59f727b378ed82d87dcd5d496097eb293d973564d398058ff3208fb5c9cd219328dff54018be2374f4a66fa489fcdff636810ec5288a0f1428e907d19a12444d9075431e049e594078e1d039e1260075278fb374a93e0105ee257808016fb5c76dee7c048012653bed21b536bffc786e8a1d77a2b8290b41964caad2025868bca96f50308b0e8d7a814ec83b900c8f77583e86bae18a18d2d335215664076fbe4a32999c11aad848aaa1df092c39ba98380a3439943e1ee02ed6a5098b95951eb7e0447b7df1eef98bc02b65dfe974bb92a4ffccc41c2983166df1755e1dfbd5545f0d62e8a27daaead2c734a6e61a196f7c253b967c1528ef00362014c7cae847514cfffb599397f6fe6c6ee72025414d2908b47de40a84cb4e3c3424ba0329707761ff4b3262835631ea1a3e164fedf5077ad2ad20039921b628ef95d8480eb14371130e00af763739537e2d02d6f125589f25eb850ec1140ed345fc070944b3846169aaf337e145e157dba7bb5cc8ae1919e050e01864dcdeb4f64782d440a6e643bd1f58b00fa425237d8a1f8b9a014d7198127601a587ed01e73a590f2bb886b1526b9aa2f577b51ab869e9e11fb795efaaa6c31762c2ab563613d28bfb2c3d59f769eb526bff8eb35ce7a97fb655447093663f1d1095d270f54f28866027ea95f63a6e5715618c99e7e08f17948a1e8c65d0f223eb8346f3a9ca6c43ab9669df0c286376cb610b5a073c5371c2c168935bc1a82162a0e476196e2da58d90892d41a9a9ba1d51aea5d2e8fe1d3554036501ad561776fe8203c0febc1bc49c023b4f2095f7ab99dc9fa4a09c70050ea6c1a6f93d04e66dace55265374deb889c25cf2a56f3cd964ae8d3ac45ee95781743bf701a13b4cb3c6948375a09050916d900fb3d0811a077bf61fad07727b53c2564dfe216679c8ff255da315e1e475b866a908dbbbd515d620c7182b849e8863869ddd808902283f89ce762a42304280edf68f9a76b67fcb61a7a54cda8575384ef380b24d73b1e75b50a6174ae6ab664e0a75f91d4acd60402170a2bf967c9862f0ae40ea80f4d02e46dfc9d22f4c5d3358a3a741b39930b017558af7a8c9e268f37a00cd48b6a5afe6dc0785efacd85eacbf38ff3691f503bd723796d7a2b7a5505471c0a5dfa4b6eec5f56d4b7e4805da697d7a7e2878d717e21d742f9699ac0aa802f8b8c774afd950836e8ec22a520412abd775c4619aafa9dd53a9dba31f385d121f23710baecf82aadad99712d54fbbff07e19d618663216ebf13dd355389ed70ab297bb2e8f14c44d9db5aed00f4272956f940c814e02c329cac3b33e110f7b260c8b643c9225c725f638d415096330c953d46a6e6901548de47f050cea00921c406ed69b8affa8c49e5126b09b7407f1fe39e6c3a67ff985f44b4068d17ca2211a8e6004ac2ce57b738ea79b47a79212fe05f59fc333dfea5b973e0189f8711d2ac25b7da815377b5e0b79bb57edfeb0b3e249284b093f937eb3c8cd5dfc470e799e62210ee5038ca82113eb298d0a91ed7265809b0e3c41842327227bca7e179281876a2d730f88bfcde6a261d12b63b325fc4b8f8a07deaab29e073e24612e721bd4dfbc7a76064f51b97cb8c9aadaebc2219602c4018e412558f0c92cf50f0300b41c3af93217af662fae6c20aba5c5de25678a70e7548eed1465315e04260f3dcd91a642d67ec3157acf46ef336e01231612fd33a33d547b352838ff602202827e24bf1d82e874c4b2e56d6da2211d4f7ca4affadd0e17c9939bae8c861988b22b4b7bb9ef9dffa40b919b3a3182f30d07eb113eb168bd5c30bd8b206a032495cd76b9b5ded766b724b3e8a955b114b6bc8eb936462efea06162c87c2c1caaf7adc04449a6a314f788d3f2e7ad03a89388119434eb73467f6a22898b762192c947c632f83b1d839ac813849f7f22884a21461081a6d636bc2c044241732a226e71541009557abe207a50bb07ee6e5318c4ee2f10bb0bcda8e4fe00e6b71fc41469002dd8f72c043824f87eeaab33b31ac8effef573e9f15bb24f1af840107e0034eaaa8cce6143056e561c708175ebd2bd2b01f7204024529b36328ec107e1079b23231ca0576310db1dcddae6dfb2272b968d23ce655bfaa3b5b578bb051aa676102be135cff656a57bf369ca177e279e14f723c6d567cfa0cce54170301665691ed411acc68341b6e22d99e80c111504fb6e8fa565540666a6c139f21693e4c8d39fee103747a085926e9c36d672e0950b53e0168b556f7cb1a672ec12a0aa0eab6371061b8532a895927a22ff8cd0d1b0f4c4daa831cfdb62551d422abedad3879ba0e5d639f4ea58196f23087af2ffd496a7572303590001f57c652e0d004ca35307c2f8c99a335d6378a3770e5dea4aeea8e5a4493369f406fbdd1bb85993f3834486eb72a18278e27c76aa92986a4b9285143493f120104d628016e1f540e94796eb5b0014ee099328f84ceb614add86ccfbc550f7600f3413651c6d6c29222e50e8a15edef04969562fdbee5ffa843960d92d565d380cbe1def21d8212fb0ef618b09a78a0d3030ea274197521f239b7b82874d575222ec0ba81ee82dca840e340012136ef0b243eba0e650058aac4a5fc88ad5327ad848ecc710d71beeb1dfa88fb932d6125e181271335a9083d7fc6e13cdb92d1ea5b3d60912591a5d8eab8b8db19ca4336fc32c3147ffe8088684fdcaebf5f634cf5e1eab1b68a4d96dbdaa0afd40748e0b4a0ebfba0a627f30c9dbc621e727f7bef5e78e245f34dcd0a1828753e5723eaa14bb4313dbe15d5e76965f8bb765910f417ae403a931a5b653d4fbe31332fd04fc6e69626fb834cda6fe48674b98219ec25e212df043b86786dd8b06d34b0bb7e6cf4c5bbaa01158fc330b05fcee8b4fb9eed20ead836e6b8cdbc6cbc06457ac64cf3a72283181e35a9657ba381ed47169ef3f178a2f40907c36a2de63a99c8cbe92a23d9b10305c3003f5341ef1f9bdef0a99000586c10ea5861a049a13f7c69b0bf6526387aedb3952554218cb5ae0266b3d17107b45cca47a5078acf00a36247bd987db1d331c585953c27b3e7b68e34c5c086f1e38aef9ef67f6bd98ba574b8534c2f71e4ec038565f0b24c6faeeff168926ae5209a04acf180a8c7481af21deeb7a02886f61625e734604feae11bb965306c08ab20127db181eb638f57097f85600f251529faea4299afb46dc539ed447212bbf694211232606e3fc74627321d1188ba6d02f9e8269dd81843182e41575113b3b7b2c3b1a8698546d3aec50985c37a3184edcc69efc421fd3e4f939fde4182255831a27d9b5d835ed40def306d138225b855aa0b81e5707438d4cf7408725dd70cb357f50ec938767a6216c3c45ef2034d3fbc3c8555a67b7dc78b47d8628fd188cef3d2b8dfbf4fc38ef79f480b2efd8c4adfd46fb6205e251212ebaf31e70b2d8a82ef799db3afddc46ae635734ac0c700fe84891c053e63156981b0b0fdba632fd2f3c239ee4bd04254130f5d66e68515143c5f4d6f2b29e17bcb1a303aa93928c09c5312a4d16946121da973879c2af82cf71b14a2ecbeda0e5ec8b02462777d72e300a2f695fe1e4440becc12fea0e2ca14ff1862931e8175d31cb1c9f8844549a6ea22385d3a4f60cd14fd6425aec8890bde9221d42f60e54bca41eea53a6a00c6fe7b66f129dec025d3c05b1a7661322b803efc62b123918b9700799cf50fecd11f0787f2807bf01fbec1f9774eb693afa70d652dd59d292b74809f0b45fd23a36228017f8cfaffd39368d2317dfa86d5eeefabb69e13c7d7ca5128829e70548ddef6f0d1230f3674f752890c754e20a858ff699eb425595132818423036c330b0a4c86f547594d8e34b5abacc9933308d03ff4b5307c9f44b721d9e1d6655d4140a8adca0117a6ac07565e7e8887975eb3965583949cd93c18900bb301068bcbc64aa85a14a8ef8365ea3f57bbe465f80ed8c039a04a7c9e5da0e09ec9c44885c8ab72021e4f8f6c388240c577957dbdd7f64e929aa54c2960a071e8b4cd84f4f659b95605e75c42ca42547f2462b36f75b57972e6f9859d45f067723d028b166e84ad2a5d9921bf762376c3e90ae6b17bd87c27e0fc007a77d1f5f7d8b0028999ef82f084a250d8562793aa0ed27644ad82feb94e80d948a6f09feb51fd95f0632eb2b356c130b50c4f70fb0f967cb7eeddb222c546a5efb49050476a0d41bb023dc5d85b1cd7776f9a2c3c792be49704ef8e0bb09b9e6913728a0b8490ce3a1277aaa62aab1f07ebb41c1f395c34eb9e983884e8dd953bf4a0f0e353000cb746ce229ae769ee10c47f15ec40591d589d798d0c2bd2655751106774bd58d59720491a086b4721fe745209895969578d037e71ae982f8a9320322a859297e7a85a2002ebe2e883aaad92af39668cd0798c08b7eddd7d503b24b1ae2daa5c4eb25393ee6ebf4008bc4e0c072ca90b67a65c586fcd5550b29423f093d0da983505afaafb1eb0771e8e9e1cb3539fbe61f5efca2d4860b1fa1b36121e5effbfaf7611b946208ea448d990b3cfdaf50b40063af0b7cccab49f5c86b16506192e554f89afa326ed0528f6aa248eba2da1825d58628355393113a8fee286a02b1c4a452f8f15011bf27dfa4fd6832f09725a7219294e11954b957f9221166c24763a83391287fc3eefe14933c5c14f4c7d6937f7b75542347d04045a110890ee0f78b861b3af29a624e25b367017d565f468cddce5b7f0cf3c35939a710bf47754178cfcde50bc00ad8afdeb5f65ac80bf3130f8f916859fdd0d676b51a19030af15d64ddc9aefd991cd5cfa036cb80826b4373b9d7bcc892d88b7dc91054be1686426a50d43560b6f5a738e11ac395dab9fe8c808f8f8ceef391350406b72a33744c6e8340275bc6ba889bb2a39e4e44a5ec3608ba7e9ff3169958a41fdf27650f39023fd280fbcd8a14f01e01129e55d1f39690748e99810326fdcd20e052a932671c905b1eaa5c122a28ec8ee55385d4230903c923a10347dfdee01e17b2763b6a7060a5b8096bdf84673c406e1bbeb5fba30c109497c0aa3ce4d91814c363d790b240b21d0c46bca0a903c5fee1e5fd6e2278a36d7209bff11e701244171b2ba258a8c4b611fe9d842c33b90dc2bb751a4c9834b94ee633ff2f0c17e99d90e05e03e67dcc81f0482fe23b3edcf8af33abbd48817fcd2f01e5cbad02174e2613f854965fff32fcfe1b2ceb878c5e8451dd0aa5d75a96db1423038d224a2a1f5665b42ccf0cd2009d22d026f92aed1329fa0eeeac0bd789e8a094c82617ebca343afad708cbf7746a1a7b486be884219e41fc54bc92afa7c4fde27204e3b778f1434022e9a0f5af3cb796f94594c41fe3d1343ce8e95cfa3405e76024841490ba15b8d6e571c78b5fa9bdb4f42cf6939f0ca766f8a33f9af1388e9f0cb4e92a32b3f70b729d395a955e2080b6f0ef0d26e8692148295a7b56b5f6a31596ef09d919d4e9ff98704206e61a8dc0a9ce4662eaf6a10878f3180ecd6bcb0093e2dacd06fe78b044dd4e2f973281e38c793a05bc453015dd5d99c1adfa70234a32f957d93338fde57563ebaf78674ac0ecfd3bfe0a8293a8222791613d2c2ffeacc050d243fae78fecd4172ef8ac8d65605f37137ac2d95706f7fd8f331204bbed683e9949fba2e4bf9941b4939ee707c3973843138bebfee49358309dd60265751d08c2e979f56c6bd140921e7a66e34962c2e608d7326c40f95b797636285580e22fa6e96ffbdfa09b8be7d9c5def6bb69b24b832097fc8501a8ca707c0b7f05f0505eb62b7964b96d0c4913735b728fa4baf217082e8f47e2f582872412c7a05dcc806ce1d8cddcca1d989321c22e660aeba3d8945d7f932b6de9e6591b97a10e4e7f2ac05c0135756d3e162058d1b9e577760bfa12f779dc1b21c04300b8aa9e06aa51ffdcd11ff50c67a307276719bc15611fd86c8098faf7c829da2c4b1f4eb53f6fb595e1961d38512f3ce9827b9e4822b90fe6e5c0c52672cc1d012e591b62f714b671321c5ce756f826cdc2bd630a9a79272f7aa02baf56779d25d42ac69b671532b1d51d23e7c79160bc322015ca838b4e674eea5167aba83c218ea51067f7176b027556fd11238b4bcf8865d89a9cd0bb3e4f43477398ccf22aa043b2ff7867dea2472de15e42e20bfccd0fd02248e6f1ebf7f95edc2eb2312c0a6b7ad4f50c3bf03555011fdf65cd0e2fa85d3bb7df6dd924e7bb5794985118a1d10561c8f03828a912b04d1e50f8bde69235134a4d4ae2da48c118a5dce12e703a9115055cdecba78a75a6d10a5e56613e9dc3efd226cd0756e592f880642c9974ff67e8a91633f52d02e73ef44399b35cab4796c37156f0f9800b7a88660345dcbf63e44f1fa2d1f8eab547a67f70db529978f40217b5422eed2588a4ee300457f11907f9415e349dad8cb86d9910eebe588cc8c0cc798a522e39a669031bcc7172286c9537143a92c965481a89f3c4e860d5ca9824175d9c7a597ee7c61c115ec99fde4909f191e31613746673c5507ab6e01436e6fe5f07d8a929fef51ff7676cbb3def22e44a545acbb9aaee1773f706fc8684a7b465d2f92f8af7dc0a1800216db2c08004b42287c6df656f6b5dedaae8e1b9013c94532463df05952bbf330909de4d033727d32480cae73d2a2e9e50326fc605ae30c0c9f011128b1a678d3619cafef8cf5d5e07d61a849c05e91e9ce8290b8e0ee69c705736ed81117bbbb0fad9bfc93fbeda8ec8b9464853ee161b5fa9b5e954c36d10f7d2e01d0837f15100dc35eb17b2dad7ccd87b482048827c1716d510244380ac5b0934e3124b0552ca7a5902213329c982bf38782b0aa337a618d658aec9d01e4885977f1514eb3c815c8ac482050a2d19638a584180f196c16339e4652b1b7f1ad870891d63a0420da9390f9dc04588fdfb066906fbeda08ee28cf7f06541519f991aa7125c2099036a614739e41d2ee4266b3faec273304a8a7fb09758a64cdae16d281d06427553cb1acf30f1603889e575889f826a832acc44180f68c230647d971413a392f060a527885509f15ad448f8aece5aadc9836862138a8b6d3b52c33dd41faa36de1e5f4355825cc13a32d55f9d84a7337b691d12ab95d7eddcdd3f72a22ee84a7b8932c0aec98b47176220beadc273414c3a7d739e598b932603544fab03f191cf63a65ae49a832011f34c94d75bb99361b17399b27d77231128adfb33018fd3f19e9f95a38b4f4296e1b8ac28f6ee41814be442b889ffd99b621ce5bf1bf69588a55456a7f9911222a4825f68d22106aaf2ee07891bbcae65d952e75b2ce90f558af3f890bff0115d005d1e5f714935cb35aa8e12c3b0f194f53ba20427e5d13527c1a9f7563f61ae1f59a6dc16f2cca1df47ba4d47ad490a54d1a9af10e1bfddf43ad707f810b5b9b48a91b16d892c73403c3f5cd6670bf79e355e1d1cb721ea112226ce6a6d52283c887da649f153a7790ec04f440176987419b5421b7c694c646cbc5618e0f2e9d9ca5a10be1c9e007d519aebc3fcaa904cf4028d0f15c92504ec8655c6f5ec0bdac134b4194ab85c505cca657e295d2041c68be114b83a369cc7707cd41264238945dcc4d2581939579ebdc673ae8a5ec925776e28341d66f9f6eae02473c10b21c2f682ba22fd78f1b25895ac2adad8511422110bdfcc50e8b7e10c22d1061ca72d0945d2ae76eb874cca31ae41ce92e335e6732e0ecb8257b64e85774c95c601b69ccdd6cbdb5bce2bdb755e0f4309e735725f", + "public_inputs_hex": "0x2138b0022ab9af3c96b082bbf307bc9e79f8f1401462e3ac1cb3a9913a5b856c18c40bec999a837ec1f06dcee05102acdef50c501e771cef739dfd0a4cac5e94000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7011521e0a601b59f0fa9d199e9f861874db5d701a0c38f6d725d9fd8c1f0b53da03219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218625eaefc46d4dc1d14d29441b83268d90e246af546b51272b038fd206edb2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7296995105557a58df75d3a42759d29e124a15ef43bad6b7fd6a9d93d4efda1c900382d23bccbad9ba827179293d23b719de8374589fcad5bc6d2148bc787593a" + }, + "decryption_aggregator": { + "proof_hex": "0x00000000000000000000000000000000000000000000000dfa79688268e94f45000000000000000000000000000000000000000000000003b27d8c4969fe006f000000000000000000000000000000000000000000000008596197ae31284d9a00000000000000000000000000000000000000000000000000025071b1b78e460000000000000000000000000000000000000000000000049f29ba73988453810000000000000000000000000000000000000000000000037166cb36624c1ddc000000000000000000000000000000000000000000000007d050eee5ee699fe8000000000000000000000000000000000000000000000000000258bb7095c7a3000000000000000000000000000000000000000000000005704f0d79a04cd41f000000000000000000000000000000000000000000000001cc8608e7634392ef00000000000000000000000000000000000000000000000af88bb11f4b13a3c200000000000000000000000000000000000000000000000000029db74f7fe7cd00000000000000000000000000000000000000000000000f4a5900047ae9ba6400000000000000000000000000000000000000000000000a2f7b686593ac5c9b000000000000000000000000000000000000000000000006e5e184d039f43481000000000000000000000000000000000000000000000000000265f972d900ce28738b09735682ead7a4c64799135201b3899d799236623c3b56cde6eeffc14c0df0717f0a39df3d76c516e8bf543821b9f4ba63b14188d420b92f5ed32350042061c4c31ac25d95dc3913a7a4720dcbd0d2b502eea4245f0e8e0b648eb3664f0ffcf0587456eae3287e653a00e8edaaebecd3e65d8ec98782517ef25ca5f5ed17e994084f3bba80177c052107cd4673933d4d7d498712c3c1a765d4ddd106cf23121b833a7165f5c9a7cbae738a5033ca28022a37b8399326468eccd785a1650e921736cbaea5f086a1fc0b8d34c9b3cf259d4260e3a0fb734e9ba562371b5d22be915dc76a01693899c6a34254a2ee1d2034d4b4afb734de2afae62fe3949727c3b05c1e3ca04b6abb43df9172b580ce32a1ea52c6a13bdabefe41b291b61b0acf905985d7fe37c2a12230fc1fe3c698d1495d937e0315f8ebc4f08b81f07b054fd658b021f59f1486e8105180cf9ea58448782cea621e76ef6e2b502df53c097f54506c667839a3fd6816ce0201339146d1334deb91f8ea6a14405ad6153a182d352d88c84c0f0d3446535350ae13ab7965e65605009887d7909a2fa1d42e2896551a0829706edd47b1b5786e28188506120cab5c15268750c76c2282e001032b6979a88d90b20a1db9d030107ffc0677ebcb6777c7f4ca2ee0510182362e2657252207babe037b83a8d8b3dc52cc67e771540a593d889433e9cb38eec2d71d52810b29a729959f506e4ee054bd6382f9acfcfa7c288777d3a5f4797e9342229726d66b20423a7f33a255cc294690bea014d9afb0331f91401058a271c34d2ab341191877abb7207f8754970389d7dfcfa00ec4ffaaeb0524dd716cfe7cb11e9223897133507d5227ce3ce11671f837ab1ef85d0aa6e308de0ecae5e49f712bf468ea81ea81e5527ee9e0f1a6128b1d1d32c56b82e3da07269e74c46c9978078a4fc2c3ec815158339b79250151302bb388375cdeada8e2669ddf041f19621eabb305f4d3270b826fa6ed2f25db9ffe39fc47e81839abfbecd91abc210133053d60869e919a115fda8d5046e59bfb2f874261d17b698de9e524a7145be6c521e3e2c29389e805e67940c921c0dd97b619b10e3d3e1822e3b2906d448ec85a031c38b5d1f34c2d4b5b7d5b6360c16fc3f097a28fc83c272b1fce5a6398bbe20a3997e59fc3a0e2317de98fdb917166780523993068ec1cdcd514df1fe9083f1991ee90b63c34c18b2639cc3c3df351ba4b8ee53f5663219c845085116bb81c1639cac4dda73a16cc4d7f9e8e607200c85a8e0fad44becf3891ffe93aa770132a39310b85cbbff14f0bce323cc23f445f6a258707355b3779232a642eff4b1a09e4b99928bfd02b699bf248fd01e881d98aef5772a6043cd5619e1a61af8b3303c7e35dd434b2854019587951ffb7e885f616ef360789979c7851ff5bb479421f42bb812a236b6fca6f7ded6823a28d36810b5eac6732fc2ad4410f715951cb2b5e09eda26e7793afd5c7c865de1570c4e72d9a88ce4b31a88264717a070d802a817a31b2c84d4c1f13a918c3a73c88d8a67f6c81fcf41ecd278894e88485c5062a3ef24ec877338c2cbafd1e61205fa95e2b93c59326cbf8f6468453a1e85e054db79eff791b9a1cb823dd9566f06129dce2b1f1c15e9c6d878629d40f61512eced624da055ff54fd71cf3520e5a759b33d31ce3d711c6e1163e3645a725960c4b1b6a5254cb9b135176e02075b45e9e1ea54e21b1a420b1414abc132d02be133cc2dfd9cdbf2a0a44fd11b51779483b4052c658b345b31ba93b918522167102cd4824015fe51e5b84a6fb335ac4842f9ed11d6f5e69b4d8dd8ba64e0f36270f78b42c71621f1501e1ba49fa4e661de16cb8dd3c698093969b8964809106412790264f0ae9b8007b76649a949b69ac1d6ec2a955902ececb7d33336b485a7c2c3c6a1fadf0fd121f79fface6cdf947dae0f776d069829fa900f514ece4141616bbbedf7de53e30cdfab6d5619028b321d44e93184fdf01e7ab3f5a4424386c23b8e5447413e6639c215e2f7bacbbe08458fe90fcff82f4dc73b1b9fa944e91108a5c28ea9df2a9e1b17874a186d1d5301848073af15ed52a4836a71b9576fb284357773419bdaa332b8130670664dea49b96012f02b091e273421d579b8b7c0db2b2715658dfaf910c32aab84a6eb1daa3f8c4c72cd2b43abc44cdb4aa8a0b0dc67c649a6c3b9cdcbea178401c0abcb272d8d5240a492956cdb2e4a3de78841ec42a7c9a5ab3b10d4264cf887b1c81451ebfb5e4277942e5736a7049bc071c168f11d6111ca6731a245c4f6f0aa9acba6d334d552193f8453f06e454c0f1b30e3264e919b2c667507684454b0045f26da17f27caf045c7b4d2f6be92bfa160277b4cf55287f67b9560a68e53fde3b7b85ee9043123cd7039658e7f874c136d1a2c26f2deaf00a930cd611ae4ca28ec30d65792e9493c2175e557b21e31a5102a8f42f94c87e31eb528d7a5fd4ca83ac3a1b62ed65113bf25e5e0a82dd2cae52cba89c170eaf2134fd4b818630ab330f68c040bca7285e619b2d493d713fbfe079f72b0b80fe7f56ea6eb5b20bf7990fa72a7f26191f159a2eb29d01801330d26bad38bdbd921c0e68d44a56c432329d5477f1e52f1d720e9dfb09f24fcc2f610e4303caced66f68ebcb8d876ec6f7c1904ab11800505a020eb41124069deb92d748417971506e406a675a65eebf63796897742b6080c037c097e742a446ed528783529668433efa5bade2e3f9052c11418f54b8bac5ae047f5fd30ba9e031f2bf38e36125c725b69365847ab2eaffb80c917ac7d3a97a47c1a1a9950db209d0326fe9bb980be5ef2bf21a3e85f236f53aa3843581e6e49d3b4451db82ff50218cdf7411b81f746a1086be6f27cffbf9f2352b4fca25777ae421cb673afe74d276522587e772895b53893a247b5bfb427dacfe13c2992700becb2313d3dc00f1876d430708da7298c907dff0b5984eafba5b26cd6fdfd59363b0bc511769da02db19b422e86e8e4003ad6554001fd10fd87d5f32af8a9d13f23bbe12525038a1a7a3867ea9741941c29e3aaa8491855617b16f140ded2b19a0b03cc4a4cd74c20f4111cdff9aaca53255e23c1c6412be63bccc4930ef87a63fb8e59411f56d4214b5fdb1a07fb3d5e91b25b3df5df862ad9cd72d3a24325c122801358aa149d2c03a7e24a687a2135762b2c1108cf1432e73f5ebb8e20a552ad92a91dbb185f11f9ede94d1ecebb9b30bc4c1a7744e2d121a63bb8fb54c2a83dcb8bb61cd6b600571edfb0c5ae31403c4fdebd9bfba727fe0422077b4bc1b660ad5ec5db84b7279d5845420a92bc08b2e5698b81383cc1490904ea5f20406d04b670ac20b49919e8beffaf81535d507d4ca8b08778bb8b791d016fb0c935e0ad7f1c6146cc4a262ce42077ad7d82e2e3848618c2e9514a3422581329e323cfb5e6153a6131990a4326ca63611c14ab69058cdfe7289463baabde69bfb64c895637ad70f47acb101d099896c7ba7b7aaeb2292c376efdfe9278aeabc23363ec0d2c0fad2cf14325801e832e9d2edeffbe63a053f8d6ac11a13118adbe3cb26f66bdc367bdf2a11bf5271e7b3828c52104b02b5f157695823763e7093e3e9e680921cd0c3dce450f4251845969a5c04cfa21f68c982ad2303130bdb22134d6210746c76817e25a249c64fff8b9d2e3651db73d13eea4360f99ebea5b17fd312fee8b1117e4967004fcf53c8939497fd46ee37dc67a58480fa1d8f2cba62cd1a04755796bdb1dbd0625d390458c05bc57aa6cec0ecf86e5b90d7d7484ce043ba332d42367e4b5310c45f065d59ed77cdf230d709944f6dab4c7782c82a2ce64161caa970c2c071c11e59f3300de1c8e44688c10c9214d8ee5d1402f31710c6c033adcef7c521b550cfbf8b66cb58eaf5b4f600593e7a7337c5b37df382e5df9bb7da69acd0935db2f71443d93c858a05143b20f06298edcc053d6f52755f8791f02c80856e1f55b0eab451543b5001697d60235605a12ca6377956f5161eabb574ea08f2741d0501dc63400f0e57099a68241c1d29056336dd70b0ed371da2615573480f10f933212ec6e0b1f25cbfe5ab5958a232a3c6555bc5d9a88ca2a5433eeb71500a178dc1003e570f070517a79e4ad9d72892bf563aebc21f65a15617fba60ab62749c622bb9822e4621ceeae8fc692ec1384c31b3fa7f85ea545106bbd4f0c8b5b03a6a0f64ca4fc38aaf821910592887b951fe39a88fed773f3c32e9d3afc97ee079d406d44e6772130b54178d8e84cf33390e8b880c554746bf355472185cbff9ba4c218facbf53bb5db501c6c583ac7df90901c1a4c7bfad4dc5a1f811986294c3e30b018f42f8d486433a79cebc05ab5a4861a0a19f413346be6108d93bbb7ab24d0f1e374662c55fbd4000b52009915ae41ace2fd2798513822da5c47b69c627522fa60c93b96255feeb8fead0646f6c03c55bdf0ce8c90d8a4ced28275e6005101dff152a15dedc7a5077b8a6a24fb6ba47511dcf942b097d341439041c53dd82030dff114cb5c1acff5f422b9f9157306540025097b5ca9666848657a1bdd8ac035532d8747b5182f12d2d76caa80b6ef5f2c23ed91c230c03f3c38b667fe41f03c5292df7fcc0485405a81a40666c864a1c0bd0f9797d7f00211a2a4d7073be1a8cc3df21420e1ac68e87a2eb75b32473cae6554a8c5118662b250f3c8e00ae2e2973ca4bf0d376bfeeaabf8f7b5c4eb4761a0b51fc018d7a205f02979d60c2027172019511cbaf761d504bfb9dfc8e01e45cd38b4e10103c13b2146174d8fb073f021f5d8fb8369b690f7a5df4044a2acc9e308e6165e6f7f5ea5d0d5f695a201986328ac16e02384a0f49de5929baa1956458ee19a901e8fbe31ecfa803bd2954fe80592a60132ae23e7c8d4d79dca4d60db2dbfe343b01cbab95a814deef0d2f09686caba0a5e8714860f809bff73ea57ed27ff26c921247633ff0f53d010898444c0522085bf95583c6bc1ea11245794f6442c79c3467afd6de0e938b9905fee8793edd702dfee158d66580b78e7124a0aea44968f9ded2dd0500d8263218735ffa49cc44890afd2777727aa4f9895a7039122d6e333b3520dde3f6096c29ec16859e98a504c88d771cc47aec7ff40a9e4f201ca83dfc7574e01261a9ea214114b3db1469a1cf55002bbd38d0ea429b1e24004d7677a57f16b4b0cbc25803108c1d04f5c0c3ef669689f62188b71909f1c11d95d514ca3a78edc8a7976422a8c196a42444ac4076ff06e369f839e38244111f04d4f74cc3ca2d635bc3001c60ee36b09471a5ed2d5db3a067183c50ddd40f2d74469507e949541d101d7e16c41645a3fc37a00b4708cb588611fe15d807d9861ea110e6883f4df31cc8ec278d447019f5d65f772020851c65d6a10ea601c7c4bcf78e58fc905b2c664f0d2c457a65f6424d6739ccaefc361f1e700d1735c61328bc29e75cb0d76b1c013910c82a1c8b34214adff97e9d94943f069509a46742bcd835da11ebb9b440dd3624c70366a5708a3a10b9688401e4250bf48266aa77d0ec6e5403d5db41f718f30f947098f457716160288bdb4721cea1adc69d2745d7aefc57eafbd2e901013b2ccf7ff182845d214e0fbe248a08364934d0ff522a9fd3005df960972ab255052930025839cab3bfbb81d5127ddf6fa01a61a613a6e8f128a85004743292f3cd2c1792d9ba72f886ed7a121297461743136ce348913ca557297019e2a3aec0a51922836c33d87bb152b06b9b9f3bbd144c703eb94cdf020568660d841a255e5d276bde9c1bf661ff908ef89874dde149fc4dceb010e3a6a382e292716cb4b8d916263774fee4ab4ba83a3ebf0b1064ebd75b9ae887644471f86a6bf8221107cc078182f2a821d52e0cfec07bc6657e50526ef9fd0048ec552d0808a742742aa625f90291e0ca4e5a4bd0c2588f4f2072da4cbc09e48791ccc16cea22ca882cd00d0381fb3133577f3d82a0a0bdcb0db0e88fe939063377ee25026eaabd38be1902111b320f710bb3503857b61c13fed36475db6ed1080063626c619d22f9b0932aa34375d85de0439ab7c194f504bc2523abd9627a8eb0c3ddfd751df66f5c95293d54b5e457bb7a9f8362a8f0e2a8acc4586c5f9109067fce81c82242a2eb5f2558d88d1bb575b0651061ce1f9bc8c75a95c5f785ef7933948632c1cb5b43592f88a62189b6ddad9274e56b188dcf13db455a4801c175f2bf802dd46ce5aae405421fc32aa47ef04f6c1ae84584ad7f02e065e6a7cfe8d1854a0f5431c7dadb0437a9c689c31a4cea1d48dc8bc6b635382ab3f7dcab912b6169fa9550900047047ef7b1b8393d511c82c6551d90fecf2662f336597b24113124e3d13b21b27b05f81ed1c2b356defe173c7cb7e4a5d33e4dda4cf7020e7fb85bf2893696a1a3238660d480aafbb0c4271397203e1a80122314f7b9ad807960830b0cacf78e1b1d45f76d3dce3e1db3071e9055eddca41a84da428fd19241adbc656e5cf7255b0cf5ad55a164b6805f639c3f7202975845aaa64ec03b57fa721daf278099b20c04630ee5a1d2cf8aa318da7097dfc780e843e1e2b8d7a550db5cad5d2ad4cfbf2e115682cc648ca983330ffb7283318b6311873be9977637d3acc6b2eb932bd00f387b1c9aed7bf928c15e9af4b7c165e4b59cc38d8e190b8b3a81d1c6d9f83725e0695fb46317bebde0aebedd01b2ed491ce402d501aefc8f4c1c293705be6b000354686877258d5ec4bec33fe416c64ce5925bc9d9a537b439250967bf458702d23d65decbeb6752b51e297d25b2432a6f5b64c0773b205c4e1446b087a44324cce538d0ae9959129c92b2240f863c773941aa0d1c503d20b91f430a467b4f2bbe0a36f9facb42624703f09f4288e1c7b74a9cbc5b2bdaf212a49f219b618c2580560061039f9eb6c52b7688ff624844a0a4acda0f1db128eef1bd0259ac3c176b1db37e377cb9d25a85c75ba3643e894de5bd3e998a4160837cd75f1cdc723038cec04a4853a6ba6c62cd4918f1632ac30de6ed5c0f8b0a68398ee741e60f184ea704315635056068c59f3feb2e28bba86ca05e77abe071bf4d179a0e9e2d0d2bcc51f8249afca59bf04cfb916937a0183917178db300a3d477e6c83f018f0db99b774c888c7019932c91882095d48b2c84a5004642e7ab200a22e90de77515c4e35e9d6ec6d71aba421ab36b30e7328fa15dd936f1c740838181ff349e122ffeb6ee1157415c7f104ac0f38ed2cfad62acb25a58a89eea6a5f66b4bf392520de5b7a89e66f24a828b7141b01fa5c1067327831d040d0e7a07f565528f2ef250121b6f9948bb2f3f2cb4099853f11073ea5173ed10bf2cd22f90108fc7c4c231b03d6f484e3bf256fd3d4f82388d90090764a9b6eaf6cb2cc2806c5fff469294e11a6fafce22457c6817315bc429ad19853b7957af2af6c3389e10c5a105a2e8d982fe73afb4addc3aa9b344fabc343c6438c8a59098f5936add0947217cc2ab165ac1555e0264108944578a3738595d56b7e274644af28a52c992a33209c05dfa9b8864f3155f77a4b18eb1eb793f4721180a337c7fb5a0b499ea96afd5d00044ba5da625f9a36bc38107cbedf12e0a51a8a2f59f2096e0d20e065018da92bc0a7112a7e48a4444a728d936338120a122db00a096cb486e3b67164120ed11205e12b3245fff17ccc63ec28b2e2a1f3d2bc7c8e7403e0c9c5d5a1514a2b900797eb3f3ea1748dfe9e23cad65e839d8e3074d0fd24a1bec13252b57f821f9d068c1cc3c26382875bc0d27da9d3bed3fdfed96ce2b7ddd3446e35d91b31d301164e3aaaaa7534f8ad4eb17b0621e6e5c876d84fa1937a023d2c29e37bb14c9202c71cc7c96f699ecaacae99aa36e15dd8055793bc6276958cbcad551d2448d1199499f2720dc367e892cbec806b3c9459f49f22dfa2b990fc8282a4ce499ba20799ba426355a8ef8dd0fd899bcfc06372d212c6ac1f63c8bd5e6914b18cbcb61704504f2e1e2ed6d86e2da36bbac86aeca425a6720cb4facfb7fd429b85ad57032d86246b281117624b1b92e7da1c0d27bbbff6a32918fc2f5945cd0b4a0ae312ce4799fc5d07c7180005bab2956d23025adfa9e3e37b7a6166084eaec7740518fa072d7ef56b4c1f8aa21142872240e2dbebec78db08384dac3cf7c36628851830f724379349291aedfc0f9cf05c92d4af5be0a50f586929489f98bc520eb906de5f1f41ebe26c58492fcf53552fa0d1df87ab01ecf27efd93652d85bf06180c0bd83850c4ddf904a68bb0f3a24d6703fbb5e7e3e3d58561e1f21783729acc1c3d2d9b96213fba91b08d5a06eca9adb713d1636c1c20ee1c6ff40a786694870e24656dcaccb56da1ff15761c4128774105f4869db44cd54a07414e76bae9ab2bd6f76e121840d8e8f87364deaa979ff118965f2ccb1ef97b3e45187af7eee1034b6d88504c0eb3f27f35f0f36cced25475b2f62df8cceedd3f4a9c7808fe41219bca2c439d0b29739bea7622a1d7c44d8a1de6d59c63b7ab55283f5df05cb70692e71c660ed45d49f1fb0790bdf274bb6cfadb9fe7d0c436f8f784478cc8df189e594ea67b7432713bf22c1199d90e0043695858aa46cccc397e528741c6b52e19c9ff45986020241cec343c8d8f74989c21f2b86e94a704335942c967bc9c032ae6b105131dbd3e550889cd96d3577f80542ab10e53487ebad39ca428ecbb236b4ac29357495fdbcd24b194b37aef7798539cb7407fc2d16cc02647616fda1bcd71bbaf8633ca0fcd9bb267a051933c14313c8a09c665da7ab26b142e9d811d717384396cecc500f378df1db9683fda74d5bc2c4e78fa1a89f7cf4975ad69066156264ceee9b8b8926b5a7105c90889998882ac9420f532112a6f1f2f2b9c023a3ed64af572f19d017aa3ef6afaab087d3bd768155bd3df0fc9f7f822ca88009d54f9ab76967e873ce437bd0f7e3195cb48599df46f54ef9d2e424a93f59213e02a423870816fe39839111cf60a4d2ec4acd8e43863cecead8f660361b8a903bb39e0d785dcdfdbe89b85c713b3355eee749fb6027ef71e9984d38806510f18a4b230924b0b848a291f8e62922077c1034005c5ee611f550a746bba75289e04ea00ca60efb7b8587281ce5223eaaf8a07771df77a7dfee0d61b4d1e01602517cdae4f6c4ad7205b5c2d781c36bb7f9c36d3a1db2c4eec78e001dc931594700617d097a075cf9b4e688aff67aeef2b5befdca4f21e388b8c655c2b55c24e511251c2d400d40a3946224c052f1ce75a4442306569e701bcc086439a62f9e04c0758fd7bda12e1ce40b209d30d67f2f003fea544afaa1d0420f6608116269508081983a5d8a574b216c19749a1472029898399220ee4a6506f95e7c5787f5b9925e200ee2c2cf08cf40b446659aa9b72d867e89de012b1336c390f8884c2087e09f19183af33cab63051be64938e007258d7bc38158dc0e80b4f2b76d13813ba2926c0c2da99395ffbf9e8cd65c95721cffa67de1b3aacb1e40f9a75ae46d9a11e06d148dfe7adc51debf3a5ed2958ac53f09e30b368648762c53d629ea154aa10cfdd10faa8de5faa738ed3d7bded2740c0187ffd6fb2f51ae27931572d853d27b75276de25a8deb23b075f1581f71d8b45f9525f54c924a3057476123f900f1f8fc748b50883c13789486e4a0750c4c2b32d747542761d6b41b5afdb17086b17b7f3f2125e5df91bd8ff04ec54b3b732214ab81bf6e21560db4780f1f0ce7329d6540a217743efe23cd1c6694b52623718e1478973ba5f76afd37d376b8930082c5adf2d53ad44dd629106b3c3b3ef24829f1570d6fe0e6bc673a33d3f233406fbe881c13361f5495c94f2d43887657f474a5ca6ebdad16ee92ebf3755c619252bb90cee7c61ef1b3729012c54101ff03af47b6444e81ace561d759d309b050a82f6e71cfd7854a68ef7452aa7e48f7c5ae0d48b5f2d54902687a8f0bb78852bbcb6b17cc2f8cac0ec1526e2a60015d3efd9a0426d82aeee4260b71813bde80392ede8d86bf0d16af0977963ce5a573f7d561fcd20ab05e2db8ea7ccb334ab0307670beb2978093fdf7001199dd0d72b0b7752ecfb91da30847c8243072a7c2f199d811b6a6c1635c6ec835b05fd77235cb3d8451194f699293e70133d756f2c9881849ce8eae584597a83c53a47450a578d88f75f6982d17ddea04e9b9ed5095939009049cfc7cd6cf9f412a3cde99720adb91ee077da2aeafbc7a033044a0b672f1ad786fbd543528c38703fb4a37c1db9a2674feabf00ff33a5ceb01bab1aa064e846cd5d748df1714875b6a62c9dfe562519ab164540c0d7530589c288064e7b496b7184387d1d4686c18f22110364c55e53f3a70d016832be570218a012f6b252d06f73d254937d9062a293346adc20823419633ffed17822bc3259dc061a1a8863d10da15f11186f71f04b20e0d152385bc108ff740a68bf824f890f05b422bc8f53d3255aff1e028a79f6da0e0e24e931497d03ca96b04e687a6f6300ef2bf5af84353c1e1a3aec79fe45be15ff7c3791aa7dbb919da84d1106515f2d5ecbc9c4928ef292fc4de434d4b92ac996d21ebf2d7d0b9d99a295622cf2ed2ef5cbf883993dd846bae8f4fdbae671e7338c6e1743fb26ecfd0e40e409c60b03445ba5b1bad93b6d8fd88b0dfb82ea5a9a01db23cf5f74ec68b4ea42a309c624208abd552ce7d9b316865cbfad7d0c232c8f3589cc58f93168ad5fef7c3843002e357ed1e5708133f433b4e0976a4b1d8f75d99556678833e17699e399f9970d0053375c14a0ab5cd8135fe265e537ae1d98e32f64258458b7ca404128db1e2c187a91f43be9f07bbdf161b002391f1b31d31a2c8f62d7dab2f8d7c4e618a71a943d0f30fbce765f0a81a0b86f000a9edca80be34d9fb22fd5959a52dff8b214d45dd690880833365f782eaa2bbdba3cc6758d345dc129399b5ad29e5d8b1f25d06a5eade8a0ef42d3759d662b6c3b27d9ca7f5804c2b3e92f1cbf128efb05252410af5cc57c287a8f8c6c3e7e83ac898b59003c3c39da20e238659b09f1df157216dafe77fb079590574e4b4123bf304f18960ac407b2405de4825cc00c35061d04805f2451cfe3e026bb617a8e284ae1bb816526a9c506a33186bdfacbd016102199b0ef23d253849057f884b691e22de105d33dd87777305d5ea3c564ff00af3dfa4db7f4b2aa305bda33a2476a6b05cce69d61d9f75f986dfc4527af3f19102cb5b69b2842d6d7e9e90e8d575adbc16ad8a3003209e911b2a11d4e200225ec90847799d4821848766737493f708ece7a692e4885692d011ceade273fc4041c5d41854376102a27aceaa0aaa4c3257eb59982599d817fb2605623931306009cb304bbce9135174946a02bb039b7995536a8c4dbb218259ddb2c1c5b9dd411f093e4e518d590f06f8c106fa0f4df4b40f10db27b63d53eb4decb2481d15a1b1f9a4dcf66168ae5f6d7c79354ec366e79b5875482aed5d9a686fdb62b17630dc56a8b87bc1dcb6329bf2d19a56110dcc82f939acb1a6e70e994bb94ce7ff31a3b1db0cf696f5c842eabdc0a6e9d5372ecb94426fc8faef668ab3d9576705e304a945cf241ce3038a11c6f5622a3422ca25d6d0040b99e5cc4e4b39843b7d72534843b4222447511a5174d7c860e10896b36b505a0e16e37cdf8ac5691664e1e5ea49b6f6f35384f56d9faa8b6aa800fd2444e741c31814b3bb2c8c6cdf828187c46187808eac8eed732b528bd82ac8f43e6db3dcd19ed12205172f578245a1589aff49acc083e14f1caa589eabd4d490f6940acbabb055c05319dcded45bf21f0d43708de5ca2383859008ca641deed357917f5ec7ba58101d82a5cc8a6f524f19284b599173697a880f26ba158d39dde2cf107c3dec0a9723aa76b6bad28134544a94eff974c94c041ba956834fb7b8a20cb3f9594b54e896704c00828401eb747c909f8e2fd22eab075a9078c84b13b6bbac635ae9abaadb151c6e827b606742f6ff2939ada26729759830191df4708924fea7ebfebcff8f927d22df05724b550de94617b485e6049826fe78c7dcef0a4b2d23fcfd60d744b89dd19180f1b06d00b6b4c79b71bd446267e49ceaf11951b2d9082b09d0e3489fe070a744a0e64fa7d24d7703e2e82a7f26381ca659b1f66255b7efd0df075b6ba4de7a085030738dcb43875953999c2f7d5392df24b864833ccc9bca50062a633f8e7b8150bb74b7a7c537b12c72b109f8c212bdc542940fcbe580040f301baf107ae48ae17da9f15e0d3439be0bd2a45788973bf8745d03428478327de779fb78c055f53138a8e8df3e15405872ddae7b1ce4515871a20b0787503e861c20abb64c517e0042a2680e7a04527301326182626e560ba34cbcd567a6fbb797077ae12ee618312c49cbfef179c6440930137664d6cc87902a61de833c0aed0a616790b8a9ff71c492e8944bc3f60fe2de37788fef01f939351f4b1fc27098590ebadd75746f60b012641c5ef934924a686fb002c329d97277967b2da3706e342c7418340cef72d0392b4fae0d4ac069893efedb6739f3bf6c4ccc98c201a908dd8f2c46ec94720c00cce419319dfc91c3b842b3e8591e284dca480d39268d31117cdd8efc4e520f283358f61913978ac3430c515e7517268d57226dfab2e09755fd0fbb8654723c336ff3932cd6cd57377fc84ad99e65e92e3e62a10cd8cb84d1eabe63874b70602ec92c43565c29787cfbf0eb1066ce59023d4ae6b066217bdc050dfad86e31c4e357566f631a0ec0d3fa61c328756f7e8e9d5b3b7c8f86cbc08daabc2e8f31bf8eb84ff8a4a6db3643f1495b21c73cad93e3e2fd220aaf09a29cf4c9c5864053a1331b441aa1c585625e656e3e58df740cf3d457c40b0429e10e67b7544310643409645badd52389b0023568f354686018d5cc617ca0be53ea64144ab52b5109a28e74e789766193593c8bad70d10b403c06dfd7ca3b97079f9a4974f563a19019c8c895f9372f50226c3b0976ba2dcba703af39b1c50c7a46b720ba7d6491ee9143c7b653930901b4617eac146fee04757443f36c7156af58c8bb33670bf2928276bea49e7849cc27cafdf183902bfbed16820c68c2238e877290b90a118068947b5a8977360e5a952e0036257dee5e0443433bc39b931f3a78a42a124210a51c58cfd80c56b67a52a3238b4a47524f9e269369e91ec03c1b7ec246c04420d0035d930d1a4936dae183715bee51356873764905f7e7ca33c3f31a56996e22caba046602b6b24130d134eccc1cfaa4eeb4a5eba6fa0cbc022057243d8d478035a50d38b9c15b98af87ef36ccfcb1a41265398b117976d06a7b604b0945f6724c34befafe430b6e687635eb05e98b27b9e57fc05ceac658bbf43be2b055ceb12385938b72f3e4e0ec92cbec13b6b816fa60b5404b418c33fe661142a616b6e24e8f9c3bb35d37e457d1dac5b9c74f471beaf7f8f4d26f608f520ccf0e113801460fb5f0d9b7c6ec1f81756e4486d34752010a0dfd19ff23b9bab9cdcfb1df1251615cb508e4922ecfab788decf45b7e877c73e46391f8e7368dbc5f351ebce144bd31203ce49b741425627c097ec248008f704ab6321f4c59e6e6c1adcf21d255b9c0abc5e5d1e913335b2f5c18fed758628396b06073450bdc8e51b9ac17a15988467eb7f3ec60395c779f28a2a1d9998f24515ca5b47eb5cc29f875c9d1a1165b3fa07fd3b99b18269fa72901035818a9bd02031ad308ff76ede118c97350024db3130d1c0b83bc7b65c3bb1f886c3996c4cd8939139aeb8e749c34ff131274570245f1e762ee28f9876c9e240e56dbafeda6fe7047f8f56148b0440f23f0d011a69b14d6dc35825881a3eba8c695d89526348a2e783135364552adcb2de2bd4bb42f48491930f07c20e89c9f87dc463d93e72a7162f518cab3474af3cd60888cd45bad31620195330ad1fa68c7b800b83761b351b440ee1542ebddff7fc14b018c913564c935e83398d0e28e5cbfd160707ca15b6e4efde70def302103524f2d9162a684c86e6dd17b74948e34b7523839b5557457dae8b84d9679010b82b4f9b6ccffc1777904eda4e4583e195476f62b6b2fc96fa400281d935327130216f637efce4bd7967925161f603ef63854cd24c1637de8a8fb2fcc7031bfba6108270c3dcf4e240a99c15115a88522efafbcb2905c304d35cc0db64799797a10e49bd25c35c762064bf13db5ed47baaf7dd7c0f4a4e768926eb2b5f9f2b7e9b0780258805e32665ef178dd88e89fbeb7c2dbdc7f4c7672d6cfa8a46075a304407aba54c51707cf93558bf6f2bc15e138ce94d38ef015c8abdb37dc627159b601389b40547fdd18c07caa2e8c156ac50719ee2e1e57d111bd79ae6d03a1297a40c36bfcb7110608d12d503545f26013b67f6883ade09afc1a9ec2287c5e0b4fc18961675c195b7025239a4f728b6354262a3b333a9f49a39f5f740652ce6fb271e03230bc5559de174f64dd0d90f02b5f2a2eaf004278215a9d856042f48cb3e2028a458428b511f716a00e9432a28ba15a6eb8cfd6a26c33641dcf788c1f6a71cfdd7f6043c8cf84ada544f719aad323ec1d2ee9f5a4888114e008cf4c467cd2b509709b141b7d822abeb2f1122d0735485f29454e0077ef21016ddcd68fbe9", + "public_inputs_hex": "0x1a207628cc6936816ccb62a7b56fdbbf8e975293b677c988644e018fc402e441156615ed204aa948509f830e7e8756e609e419f8a6f8561fddd9202f8abcba01000000000000000000000000000000008d297f772405c35b14daacbd6b92f436000000000000000000000000000000006134a41a9eb8ba562f5ed7df154f8b7001cad4adce90c01d548eb5a88e3935668204c5bddb827b618a40626d8bc1281f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000203219b289bf708a79fb51b2ca033a711b50507c0a223589ab5e58ca23d94046612cdec838f7f61ac1a22b03689875a641846bd79456adbb7461037044d0f88ca2218aba4df02ce9e79dc47d8caacecb6ace5864e51f2b43f071bd722a7e2728219d950512dcce7ada3f9d302cfa36d3768e83ceee44bf4287f509a003a7a4db7000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } +} diff --git a/scripts/build-circuits.ts b/scripts/build-circuits.ts index cc1ef1cb28..e9d093861e 100644 --- a/scripts/build-circuits.ts +++ b/scripts/build-circuits.ts @@ -55,9 +55,17 @@ interface BuildOptions { skipVk?: boolean outputDir?: string clean?: boolean + noCleanTargets?: boolean + skipIfBuilt?: boolean dryRun?: boolean preset?: CircuitPreset | 'all' } + +interface PresetBuildStamp { + preset: string + sourceHash: string + builtAt: string +} interface BuildResult { success: boolean compiled: CompiledCircuit[] @@ -102,8 +110,7 @@ class NoirCircuitBuilder { mkdirSync(this.options.outputDir!, { recursive: true }) for (const preset of presets) { - this.setNoirConfigPreset(modNrPath, preset) - const presetResult = await this.buildForPreset(preset) + const presetResult = await this.buildForPreset(preset, modNrPath) result.compiled.push(...presetResult.compiled) result.errors.push(...presetResult.errors) if (!presetResult.success) result.success = false @@ -146,7 +153,72 @@ class NoirCircuitBuilder { console.log(` 📋 Set Noir config to: ${configModule} (preset: ${preset})`) } - private async buildForPreset(preset: CircuitPreset): Promise { + private presetStampPath(preset: string): string { + return join(this.options.outputDir!, preset, '.build-stamp.json') + } + + private readPresetStamp(preset: string): PresetBuildStamp | null { + const stampPath = this.presetStampPath(preset) + if (!existsSync(stampPath)) return null + try { + return JSON.parse(readFileSync(stampPath, 'utf-8')) as PresetBuildStamp + } catch { + return null + } + } + + private writePresetStamp(preset: string, sourceHash: string): void { + const stamp: PresetBuildStamp = { + preset, + sourceHash, + builtAt: new Date().toISOString(), + } + mkdirSync(join(this.options.outputDir!, preset), { recursive: true }) + writeFileSync(this.presetStampPath(preset), JSON.stringify(stamp, null, 2) + '\n') + } + + /** Marker files required by `test_trbfv_actor` / gas extraction (dist + circuits/bin targets). */ + private requiredPresetMarkers(preset: string): string[] { + const dist = join(this.options.outputDir!, preset) + const bin = this.circuitsDir + return [ + join(dist, CIRCUIT_VARIANTS.DEFAULT, CIRCUIT_GROUPS.AGGREGATION, 'dkg_aggregator', 'dkg_aggregator.json'), + join(dist, CIRCUIT_VARIANTS.DEFAULT, CIRCUIT_GROUPS.AGGREGATION, 'decryption_aggregator', 'decryption_aggregator.json'), + join(bin, CIRCUIT_GROUPS.AGGREGATION, 'dkg_aggregator', 'target', 'dkg_aggregator.json'), + join(bin, CIRCUIT_GROUPS.AGGREGATION, 'dkg_aggregator', 'target', 'dkg_aggregator.vk_recursive'), + join(bin, CIRCUIT_GROUPS.AGGREGATION, 'decryption_aggregator', 'target', 'decryption_aggregator.json'), + join(bin, CIRCUIT_GROUPS.AGGREGATION, 'decryption_aggregator', 'target', 'decryption_aggregator.vk_recursive'), + join(bin, CIRCUIT_GROUPS.DKG, 'target', 'pk.json'), + join(bin, CIRCUIT_GROUPS.THRESHOLD, 'target', 'pk_aggregation.json'), + ] + } + + private isPresetUpToDate(preset: string, sourceHash: string): boolean { + const stamp = this.readPresetStamp(preset) + if (!stamp?.sourceHash || stamp.sourceHash !== sourceHash) return false + return this.requiredPresetMarkers(preset).every((path) => existsSync(path)) + } + + private logSkipIfBuiltBlocked(preset: string, sourceHash: string): void { + const stamp = this.readPresetStamp(preset) + const stampPath = this.presetStampPath(preset) + if (!stamp?.sourceHash) { + console.log(` ℹ️ --skip-if-built: no stamp at ${stampPath}`) + return + } + if (stamp.sourceHash !== sourceHash) { + console.log( + ` ℹ️ --skip-if-built: circuit sources changed (stamp ${stamp.sourceHash} → ${sourceHash}). ` + + `Run without --skip-if-built or \`pnpm build:circuits --preset ${preset}\` once to refresh.`, + ) + } + const missing = this.requiredPresetMarkers(preset).filter((path) => !existsSync(path)) + if (missing.length > 0) { + console.log(` ℹ️ --skip-if-built: missing ${missing.length} marker artifact(s), e.g. ${missing[0]}`) + } + } + + private async buildForPreset(preset: CircuitPreset, modNrPath?: string): Promise { const result: BuildResult = { success: true, compiled: [], errors: [] } const presetOutputDir = join(this.options.outputDir!, preset) @@ -169,10 +241,28 @@ class NoirCircuitBuilder { return result } - this.cleanTargetDirs(circuits) - mkdirSync(presetOutputDir, { recursive: true }) + const sourceHash = this.computeSourceHash(preset) + result.sourceHash = sourceHash - result.sourceHash = this.computeSourceHash() + if (this.options.skipIfBuilt) { + if (this.isPresetUpToDate(preset, sourceHash)) { + console.log( + ` ⏭️ Skipping preset ${preset} (artifacts up to date; source_hash=${sourceHash}). ` + + `Use a full rebuild without --skip-if-built to refresh.`, + ) + return result + } + this.logSkipIfBuiltBlocked(preset, sourceHash) + } + + if (modNrPath) { + this.setNoirConfigPreset(modNrPath, preset) + } + + if (!this.options.noCleanTargets) { + this.cleanTargetDirs(circuits) + } + mkdirSync(presetOutputDir, { recursive: true }) for (const circuit of circuits) { try { @@ -184,6 +274,9 @@ class NoirCircuitBuilder { } this.copyArtifacts(result.compiled, presetOutputDir, preset) + if (result.errors.length === 0) { + this.writePresetStamp(preset, sourceHash) + } console.log(`\n✅ Built ${result.compiled.length} circuits for preset: ${preset}`) if (result.errors.length > 0) { console.error('\n❌ Failed circuits:') @@ -599,16 +692,23 @@ class NoirCircuitBuilder { return outputDir } - computeSourceHash(): string { + computeSourceHash(preset?: CircuitPreset): string { const hash = createHash('sha256') + if (preset !== undefined) { + hash.update(`preset:${preset}\n`) + hash.update(`noir_config:${PRESET_NOIR_CONFIG[preset]}\n`) + } const circuits = this.discoverCircuits().sort((a, b) => `${a.group}/${a.name}`.localeCompare(`${b.group}/${b.name}`)) for (const c of circuits) this.hashDir(c.path, hash) return hash.digest('hex').substring(0, 16) } + /** Generated at bench time; must not invalidate `--skip-if-built` between ensure passes. */ + private static readonly SKIP_SOURCE_HASH_ENTRIES = new Set(['target', 'Prover.toml', 'Witness.toml']) + private hashDir(dirPath: string, hash: ReturnType, relativePath = ''): void { for (const entry of readdirSync(dirPath).sort()) { - if (entry === 'target' || entry.startsWith('.')) continue + if (entry.startsWith('.') || NoirCircuitBuilder.SKIP_SOURCE_HASH_ENTRIES.has(entry)) continue const fullPath = join(dirPath, entry) const entryRelativePath = relativePath ? `${relativePath}/${entry}` : entry const stat = statSync(fullPath) @@ -651,6 +751,8 @@ async function main() { else if (arg === '--skip-checksums') options.skipChecksums = true else if (arg === '--skip-vk') options.skipVk = true else if (arg === '--no-clean') options.clean = false + else if (arg === '--no-clean-targets') options.noCleanTargets = true + else if (arg === '--skip-if-built') options.skipIfBuilt = true else if (arg === '--group') options.groups = args[++i]?.split(',') as CircuitGroup[] else if (arg === '--circuit') (options.circuits ??= []).push(args[++i]) else if (arg === '-o' || arg === '--output') options.outputDir = resolve(args[++i]) @@ -667,7 +769,8 @@ async function main() { const builder = new NoirCircuitBuilder(undefined, options) if (command === 'hash') { - const hash = builder.computeSourceHash() + const preset = options.preset === 'all' ? undefined : options.preset + const hash = builder.computeSourceHash(preset) console.log(hash) if (process.env.GITHUB_OUTPUT) appendFileSync(process.env.GITHUB_OUTPUT, `source_hash=${hash}\n`) } else { @@ -692,6 +795,8 @@ Options: -o, --output Output directory (default: dist/circuits) --dry-run Show what would be built --no-clean Don't clean output directory + --no-clean-targets Don't delete circuits/bin target dirs before compiling + --skip-if-built Skip preset when dist stamp + marker artifacts match circuit sources -h, --help Show help `) } diff --git a/scripts/generate-verifiers.ts b/scripts/generate-verifiers.ts index bed14998a0..88a556869f 100644 --- a/scripts/generate-verifiers.ts +++ b/scripts/generate-verifiers.ts @@ -18,6 +18,7 @@ * pnpm generate:verifiers --circuits pk,fold # Specific circuits * pnpm generate:verifiers --clean # Remove existing verifiers first * pnpm generate:verifiers --dry-run # Show what would be generated + * pnpm generate:verifiers --no-compile # Use artifacts from build:circuits (skips target cleanup) */ import { execSync } from 'child_process' @@ -49,6 +50,7 @@ interface GenerateOptions { clean?: boolean dryRun?: boolean compile?: boolean // compile circuits before generating verifiers + noCleanTargets?: boolean // skip deleting nargo target dirs before generation } // --------------------------------------------------------------------------- @@ -93,8 +95,10 @@ class VerifierGenerator { return } - // Clean stale nargo build caches to prevent using outdated artifacts - this.cleanTargetDirs(circuits) + // Clean stale nargo build caches unless caller just ran build:circuits (--no-compile / --no-clean-targets). + if (!this.options.noCleanTargets && this.options.compile !== false) { + this.cleanTargetDirs(circuits) + } // Prepare output directory if (this.options.clean && existsSync(this.verifierDir)) { @@ -375,6 +379,9 @@ async function main() { options.clean = true } else if (arg === '--no-compile') { options.compile = false + options.noCleanTargets = true + } else if (arg === '--no-clean-targets') { + options.noCleanTargets = true } else if (arg === '--group') { const value = args[++i] if (!value || value.startsWith('--')) { @@ -407,7 +414,9 @@ Options: --circuits Circuit names (comma-separated). When omitted, generates all circuits. --group Circuit groups (comma-separated: dkg,threshold,recursive_aggregation) --clean Remove existing verifier directory before generating - --no-compile Don't compile circuits automatically (fail if not already compiled) + --no-compile Don't compile circuits automatically (fail if not already compiled); + also skips cleaning nargo target dirs (use after build:circuits) + --no-clean-targets Don't delete nargo target dirs before generating verifiers --dry-run Show what would be generated without doing anything -h, --help Show this help message diff --git a/tests/integration/base.sh b/tests/integration/base.sh index 4ab21fa397..89450ca2c6 100755 --- a/tests/integration/base.sh +++ b/tests/integration/base.sh @@ -72,7 +72,8 @@ pnpm committee:new \ --input-window-start "$INPUT_WINDOW_START" \ --input-window-end "$INPUT_WINDOW_END" \ --e3-params "$ENCODED_PARAMS" \ - --committee-size 0 + --committee-size 0 \ + --proof-aggregation-enabled false wait_for_committee_pubkey 0 "$SCRIPT_DIR/output/pubkey.bin"