From b6fd9146690f979944edb6a852d847751f1f2c69 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 00:34:55 +0200 Subject: [PATCH 01/11] connnect ciphertext output hash --- agent/flow-trace/00_INDEX.md | 11 +- agent/flow-trace/04_DKG_AND_COMPUTATION.md | 29 +- .../crisp_verify_gas.json | 92 +----- .../integration_summary.json | 134 ++++---- .../results_insecure_minimum/report.md | 289 +++++++++--------- .../decryption_aggregator/src/main.nr | 10 + .../compute-provider/src/ciphertext_output.rs | 1 + crates/compute-provider/src/compute_input.rs | 13 + crates/data/src/commit_log_event_log.rs | 1 + .../ciphertext_output_published.rs | 1 + crates/evm-helpers/src/contracts.rs | 9 +- crates/evm-helpers/src/events.rs | 3 +- .../tests/fixtures/fake_interfold.sol | 10 +- crates/evm/src/contracts.rs | 3 +- crates/evm/src/interfold/events.rs | 1 + crates/indexer/src/indexer.rs | 3 + crates/indexer/src/models.rs | 2 + crates/indexer/src/repo.rs | 14 + .../indexer/tests/fixtures/fake_interfold.sol | 10 +- crates/indexer/tests/integration.rs | 4 +- crates/support/README.md | 2 +- crates/tests/tests/integration.rs | 2 + .../src/circuits/aggregation/node_dkg_fold.rs | 10 + docs/pages/cryptography.mdx | 6 +- docs/pages/internals/dkg.mdx | 11 +- docs/pages/sdk.mdx | 4 +- examples/CRISP/server/src/server/models.rs | 3 + .../CRISP/server/src/server/routes/state.rs | 9 +- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IInterfold.sol/IInterfold.json | 28 +- .../ISlashingManager.json | 2 +- .../contracts/Interfold.sol | 9 +- .../interfaces/IDecryptionVerifier.sol | 9 +- .../contracts/interfaces/IE3.sol | 4 +- .../contracts/interfaces/IInterfold.sol | 6 +- .../contracts/lib/InterfoldPricing.sol | 2 + .../contracts/test/MockDecryptionVerifier.sol | 1 + .../contracts/test/MockE3Program.sol | 7 +- .../verifiers/bfv/BfvDecryptionVerifier.sol | 30 +- .../bfv/honk/DecryptionAggregatorVerifier.sol | 98 +++--- .../scripts/benchmarkGasFromRaw.ts | 5 + packages/interfold-contracts/scripts/utils.ts | 9 +- .../interfold-contracts/tasks/interfold.ts | 12 +- .../test/BfvDecryptionVerifier.spec.ts | 49 +++ .../test/BfvVkBindingIntegration.spec.ts | 5 + .../test/E3Lifecycle/E3Integration.spec.ts | 29 +- .../test/Interfold.spec.ts | 100 +++++- .../test/Pricing/DustRotation.spec.ts | 7 +- .../test/Pricing/Pricing.spec.ts | 14 +- .../Pricing/PullPaymentsAndAllowlist.spec.ts | 14 +- .../bfv_vk_binding/folded_artifacts.json | 8 +- packages/interfold-sdk/README.md | 2 +- .../src/contracts/contract-client.ts | 3 +- packages/interfold-sdk/src/contracts/types.ts | 1 + packages/interfold-sdk/src/events/types.ts | 2 + packages/interfold-sdk/src/interfold-sdk.ts | 3 +- templates/default/server/index.ts | 16 +- 58 files changed, 711 insertions(+), 455 deletions(-) diff --git a/agent/flow-trace/00_INDEX.md b/agent/flow-trace/00_INDEX.md index 55f32699ba..3b385ff487 100644 --- a/agent/flow-trace/00_INDEX.md +++ b/agent/flow-trace/00_INDEX.md @@ -189,11 +189,12 @@ _Found during source-code cross-referencing of these trace documents._ ### Circuit Audit Remediations -| Finding | Status | Implemented behavior | -| ----------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **IF-001 — unconstrained U64 modular division** | Fixed | `ModU64::div_mod` verifies the hinted quotient satisfies `result * divisor == dividend (mod modulus)`; the Noir suite includes a non-invertible-divisor regression test. | -| **IF-002 — conditional C7 decoding equality** | Fixed | C7 compares every decoded coefficient with the claimed message, including zero coefficients; a focused regression test rejects a nonzero decoded value claimed as zero. | -| **IF-003 — decryption proof phase and party binding** | Fixed | `decryption_aggregator` requires 1-indexed, strictly increasing party IDs, while `BfvDecryptionVerifier` checks the surfaced SK/ESM commitments against the E3's registry-backed DKG anchors. | +| Finding | Status | Implemented behavior | +| ----------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **IF-001 — unconstrained U64 modular division** | Fixed | `ModU64::div_mod` verifies the hinted quotient satisfies `result * divisor == dividend (mod modulus)`; the Noir suite includes a non-invertible-divisor regression test. | +| **IF-002 — conditional C7 decoding equality** | Fixed | C7 compares every decoded coefficient with the claimed message, including zero coefficients; a focused regression test rejects a nonzero decoded value claimed as zero. | +| **IF-003 — decryption proof phase and party binding** | Fixed | `decryption_aggregator` requires 1-indexed, strictly increasing party IDs, while `BfvDecryptionVerifier` checks the surfaced SK/ESM commitments against the E3's registry-backed DKG anchors. | +| **IF-004 — ciphertext commitment binding** | Fixed | The off-chain SAFE commitment is stored at ciphertext publication, propagated as a final decryption-proof public input, and compared on-chain without attempting BFV decoding or Poseidon2 execution in Solidity. | ### Protocol Design Concerns diff --git a/agent/flow-trace/04_DKG_AND_COMPUTATION.md b/agent/flow-trace/04_DKG_AND_COMPUTATION.md index 2e177c3f73..b828cc3a83 100644 --- a/agent/flow-trace/04_DKG_AND_COMPUTATION.md +++ b/agent/flow-trace/04_DKG_AND_COMPUTATION.md @@ -414,8 +414,9 @@ ShareVerificationActor receives ShareVerificationDispatched(kind=ShareProofs) │ │ │ C4a→C6 (SameParty): C4a's commitment == C6's expected_sk_commitment │ │ │ C4b→C6 (SameParty): C4b's commitment == C6's expected_e_sm_commitment │ │ │ C6→C7 (CrossParty): C6's d_commitment matches C7's expected_d_commitment -│ │ │ (on-chain / E3 state) C3/C6 ciphertext commitments are checked against their ciphertext witnesses off-chain; -│ │ │ the final EVM proof does not yet expose a ciphertext commitment for comparison with `keccak256(e3.ciphertextOutput)` +│ │ │ (on-chain / E3 state) C3/C6 ciphertext commitments are checked against their ciphertext witnesses; +│ │ │ the final decryption proof exposes the SAFE commitment and the wrapper compares it with +│ │ │ the commitment stored at ciphertext publication. Keccak(raw output) remains separate. │ │ │ │ │ ├─ On mismatch: publishes CommitmentConsistencyViolation │ │ │ → AccusationManager initiates accusation quorum (see Part 5) @@ -704,13 +705,14 @@ on-chain; the explicit test/CI skip mode works only with mock verifiers that tru > additionally compares the immutable VK hashes with the version-controlled circuit artifacts. The decryption wrapper exposes -`verify(e3Id, decryptionDomain, plaintextOutputHash, committeeHash, proof)`. `Interfold` recomputes -`decryptionDomain` over +`verify(e3Id, decryptionDomain, plaintextOutputHash, committeeHash, ciphertextCommitment, proof)`. +`Interfold` recomputes `decryptionDomain` over `(chainId, Interfold address, e3Id, committeeHash, ciphertextOutputHash, committeePublicKey)`. The -wrapper checks the domain limbs in the final proof, then uses the separate `e3Id` to resolve the -registry's stored DKG anchors and compares every surfaced party ID, secret-key commitment, and -smudging-noise commitment. The party IDs are circuit-side 1-indexed Shamir coordinates and are -translated to the registry's 0-indexed committee slots for this comparison. +wrapper checks the domain limbs and SAFE ciphertext commitment in the final proof, then uses the +separate `e3Id` to resolve the registry's stored DKG anchors and compares every surfaced party ID, +secret-key commitment, and smudging-noise commitment. The party IDs are circuit-side 1-indexed +Shamir coordinates and are translated to the registry's 0-indexed committee slots for this +comparison. --- @@ -732,24 +734,25 @@ Data providers submit encrypted inputs: ``` Compute provider runs computation on encrypted data: │ -└─ Interfold.publishCiphertextOutput(e3Id, ciphertextOutput, proof) +└─ Interfold.publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof) │ │ ┌─── ON-CHAIN (Interfold.sol) ─────────────────────────────┐ │ │ │ - │ │ publishCiphertextOutput(e3Id, output, proof) { │ +│ │ publishCiphertextOutput(e3Id, output, commitment, proof) { │ │ │ 1. require(stage == KeyPublished) │ │ │ 2. require(block.timestamp <= computeDeadline) │ │ │ 3. require(block.timestamp >= inputWindow[1]) │ │ │ → Input window must have closed │ │ │ 4. require(e3.ciphertextOutput == 0) │ │ │ → Can only publish once │ - │ │ 5. e3.ciphertextOutput = keccak256(output) │ - │ │ 6. e3Program.verify(e3Id, hash, proof) │ +│ │ 5. e3.ciphertextOutput = keccak256(output) │ +│ │ e3.ciphertextCommitment = commitment │ +│ │ 6. e3Program.verify(e3Id, hash, proof) │ │ │ → Program verifies computation correctness │ │ │ → Must return true │ │ │ 7. stage = CiphertextReady │ │ │ 8. decryptionDeadline = now + decryptionWindow │ - │ │ 9. Emit CiphertextOutputPublished(e3Id, output) │ +│ │ 9. Emit CiphertextOutputPublished(e3Id, output, commitment) │ │ │ 10. Emit E3StageChanged(CiphertextReady) │ │ │ } │ │ └─────────────────────────────────────────────────────────┘ diff --git a/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json b/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json index 6f0d86e50c..55c2acc233 100644 --- a/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json +++ b/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json @@ -1,8 +1,8 @@ { "verify_gas": { - "dkg": 3119505, + "dkg": 3119663, "user": null, - "dec": 3672202 + "dec": 3674782 }, "source": "folded_proof_export_plus_crisp_verify_test", "artifact_sizes_bytes": { @@ -12,94 +12,22 @@ }, "dec": { "proof": 10944, - "public_inputs": 3616 + "public_inputs": 3648 } }, "calldata_gas": { "dkg": { - "proof": 170028, - "public_inputs": 4992, - "total": 175020 + "proof": 170196, + "public_inputs": 4980, + "total": 175176 }, "dec": { - "proof": 169944, - "public_inputs": 17956, - "total": 187900 - } - }, - "integration_summary": { - "integration_test": "test_trbfv_actor", - "benchmark_config": { - "mode": "insecure", - "bfv_preset_subdir": "insecure-512", - "bfv_preset": "InsecureThreshold512", - "lambda": 2, - "proof_aggregation_enabled": true, - "multithread_concurrent_jobs": 13, - "committee_h": 2, - "committee_n": 3, - "committee_t": 1, - "nodes_spawned": 7, - "network_model": "in_process_bus", - "testmode_harness": true - }, - "proof_aggregation_enabled": true, - "dkg_fold_attestation_verifier": "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0", - "multithread": { "rayon_threads": 13, "max_simultaneous_rayon_tasks": 13, "cores_available": 14 }, - "operation_timings": [ - { "name": "CalculateDecryptionKey", "avg_seconds": 0.004326667, "runs": 3, "total_seconds": 0.012980001 }, - { "name": "CalculateDecryptionShare", "avg_seconds": 0.022016291, "runs": 3, "total_seconds": 0.066048875 }, - { "name": "CalculateThresholdDecryption", "avg_seconds": 0.020120625, "runs": 1, "total_seconds": 0.020120625 }, - { "name": "GenEsiSss", "avg_seconds": 0.007776041, "runs": 3, "total_seconds": 0.023328125 }, - { "name": "GenPkShareAndSkSss", "avg_seconds": 0.011192708, "runs": 3, "total_seconds": 0.033578125 }, - { "name": "NodeDkgFold/c2ab_fold", "avg_seconds": 18.821508069, "runs": 3, "total_seconds": 56.464524208 }, - { "name": "NodeDkgFold/c3a_fold", "avg_seconds": 73.488805041, "runs": 3, "total_seconds": 220.466415124 }, - { "name": "NodeDkgFold/c3ab_fold", "avg_seconds": 7.851751111, "runs": 3, "total_seconds": 23.555253334 }, - { "name": "NodeDkgFold/c3b_fold", "avg_seconds": 73.173327319, "runs": 3, "total_seconds": 219.519981959 }, - { "name": "NodeDkgFold/c4ab_fold", "avg_seconds": 8.281481527, "runs": 3, "total_seconds": 24.844444583 }, - { "name": "NodeDkgFold/node_fold", "avg_seconds": 18.939945583, "runs": 3, "total_seconds": 56.81983675 }, - { "name": "ZkDecryptedSharesAggregation", "avg_seconds": 1.593031959, "runs": 1, "total_seconds": 1.593031959 }, - { "name": "ZkDecryptionAggregation", "avg_seconds": 49.684318333, "runs": 1, "total_seconds": 49.684318333 }, - { "name": "ZkDkgAggregation", "avg_seconds": 5.735565959, "runs": 1, "total_seconds": 5.735565959 }, - { "name": "ZkDkgShareDecryption", "avg_seconds": 0.948800333, "runs": 6, "total_seconds": 5.692802 }, - { "name": "ZkNodeDkgFold", "avg_seconds": 108.814322347, "runs": 3, "total_seconds": 326.442967043 }, - { "name": "ZkNodesFoldStep", "avg_seconds": 5.313063916, "runs": 2, "total_seconds": 10.626127833 }, - { "name": "ZkPkAggregation", "avg_seconds": 0.29689275, "runs": 1, "total_seconds": 0.29689275 }, - { "name": "ZkPkBfv", "avg_seconds": 0.229513319, "runs": 3, "total_seconds": 0.688539958 }, - { "name": "ZkPkGeneration", "avg_seconds": 3.607771166, "runs": 3, "total_seconds": 10.823313499 }, - { "name": "ZkShareComputation", "avg_seconds": 2.617024506, "runs": 6, "total_seconds": 15.702147041 }, - { "name": "ZkShareEncryption", "avg_seconds": 3.672300166, "runs": 24, "total_seconds": 88.135204 }, - { "name": "ZkThresholdShareDecryption", "avg_seconds": 3.494414028, "runs": 3, "total_seconds": 10.483242084 }, - { "name": "ZkVerifyShareDecryptionProofs", "avg_seconds": 0.082335722, "runs": 3, "total_seconds": 0.247007167 }, - { "name": "ZkVerifyShareProofs", "avg_seconds": 0.244133875, "runs": 5, "total_seconds": 1.220669376 } - ], - "operation_timings_total_seconds": 1129.198340711, - "operation_timings_metric": "tracked_job_wall", - "phase_timings": [ - { "label": "Starting trbfv actor test", "seconds": 0e-9, "metric": "wall_clock" }, - { "label": "Setup completed", "seconds": 1.017932541, "metric": "wall_clock" }, - { "label": "Committee Setup Completed", "seconds": 7.022026041, "metric": "wall_clock" }, - { "label": "Committee Finalization Complete", "seconds": 0.001739292, "metric": "wall_clock" }, - { "label": "Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)", "seconds": 125.46852, "metric": "wall_clock" }, - { "label": "ThresholdShares -> PublicKeyAggregated", "seconds": 137.630169125, "metric": "wall_clock" }, - { "label": "E3Request -> PublicKeyAggregated", "seconds": 138.13360025, "metric": "wall_clock" }, - { "label": "Application CT Gen", "seconds": 0.009520666, "metric": "wall_clock" }, - { "label": "Running FHE Application", "seconds": 0.000055291, "metric": "wall_clock" }, - { "label": "Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)", "seconds": 51.290023, "metric": "wall_clock" }, - { "label": "Ciphertext published -> PlaintextAggregated", "seconds": 55.067765875, "metric": "wall_clock" }, - { "label": "Entire Test", "seconds": 201.252351625, "metric": "wall_clock" } - ], - "folded_artifacts": { - "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000893e2589fc7272df300000000000000000000000000000000000000000000000f9cacd727086112c2000000000000000000000000000000000000000000000001087d088d5e0eb68400000000000000000000000000000000000000000000000000012265e9d423bc00000000000000000000000000000000000000000000000848d741a33c08ace2000000000000000000000000000000000000000000000008900eb4f01074c33d00000000000000000000000000000000000000000000000bb603d265d0e8c3f300000000000000000000000000000000000000000000000000008a6c01ce44080000000000000000000000000000000000000000000000056a1f3c8c8cd10298000000000000000000000000000000000000000000000000f4913d1f1efea4390000000000000000000000000000000000000000000000055187776dfc7e27c200000000000000000000000000000000000000000000000000020e60b75114b80000000000000000000000000000000000000000000000037252d99ba4b6b4e600000000000000000000000000000000000000000000000774c7a54897b11a9500000000000000000000000000000000000000000000000fdd40227ec51bf31f00000000000000000000000000000000000000000000000000019c9203decfb90e15854237f5c72c41d9082a4545b24694b629e686c58d51412f7fd32e13d5cc131b256d0eae84688fba4f2c0c00f84a33ccf9eff8eaf9f96b18557d2a7019f3034e1dcf5038db8476b5ce28e0eb6d0b588a3d92abeccb8acadcf67559752b4820a6ae16edfdf62f6c4ff6f5dac318c159ed8b8a98adb2c907a21b91bb74450924ad1b7b0beae123ea31c74f103bd2f0d7838483cf5960db17d47b987b8eb9f41868dcc4c2d77185ff80d4213515aa90244fec519f8b4a3b94b789e212393534132732aa313e4296df8b5f17497adfb0e14abd79fd3d54f953825f194baa0bfa1b5875c2c1b1876a47dbde1ed563a4d0dedc8c3686bf29a39fcabb4f4d138a4305b305e25ea240ee1a7676ee159c5c0cee9881d575d82a8436a3047e0b16bd4d040372200291485daa1ef88b8e351a3aaff641c72510b642515345321f0aacdc2f1138db62d6540fd8f07939380763a72892091168fcae86a010b455afa401db031ecd41783b303eb5655e67ceec7775594faf23d9531c1e438fbb2a504a956e1b7bf6f6a9a1199f84d5430aad0d3d92f6f4040ef2b13539270b3a40d7505f931eca2310d783a3021e50216a221b41b08ac834737f354d673289128fd36786d6136e38d2f4d0b07b8cc1bb220bc7b8e57024195931350e83657d029a83dc34b7193c7c10e5f817db7d9edeb2e56536938360ba7662c40955cdb42cfba3ffe3471db3b457f7abc3da3b5c6cc1235d1443340fcc130ea8c7a1a27bd327b204b8bb1444f7df9b30ec99fb363c05cd8a95c8911703089acebf0e5374476e5b04ccac0ba4bae2950a693e469306142da1c9a6803cc03aa6751a5ede2660b6456d7ff50a22b46ecb26c32f8483b832badb3bd261b76147946ccf32ccc7df80755c970323abfd79e860344af0a77ef4158a686473f2ee44b9463c55a5fbba510f61820608315d582ea7ff959f9e0e0ece8f579c13bc173a81802641c6d59db9ccd02fb8222df1d855fb1a085663adbff7682626e7364c355592466ad27289f4e763e4150e11f707808d36e43f0942b2bce4623a17f32342e6159406377ddfc6a610497d064214c534db9af22e91fc4790d334549474cb3808889a7b233902313e8c9c1a078389b9a6bc5837f2c323f9c93da198c6f7ffc7e8506c22b6ea42e0bc92a9691e98e4a0334ff82dc0c51dbedecf9540cec8d166f3abb7acec918dd96d10159f277c4473b121ba1b35f5a6af679116f5bc600f42b77326cc2369b623347572731e3e5c676b3c710d4d76049409b96139a19caa6f489579243903a78bb5cc6d8d26546bd4ab3e7cf4e832a8158c91ba19a9e56101f466aadd4a5f6bfb7f8825d72c83d4e8965ba1468c1e93822666884990221c364cc3d56baf7b47217699b7af230b7d3b3d622b2ed8763f89c57955223d99ca2203786ae090d3a65884abcc6b117cd2bd54d1df58312861771bf6a290452d4c980ad6d8d77ef4455012bc47911e89bf3e709ae1bfb2731c4aa674fde1de69a4801e10c4923c4de7f339f85d5b2f00e7fe872d692fe397164968df3140ba2a3e8758c9a0e530903b569bc20ac6186844791c107f85970ed03a94a4120914c716a0f0606f6f66bdefb596ea706821ecbc8bd8932e21da71ded29557eb4172d7c4545a93a547fdf16e2768e3ec322d0658c1aa5b422e4fa9772c6222e1018db983236a2fe4afbc28e3a7d49aae3d0ab553e9239d3502e082ec865748cc118e8c4940a2096666785cbe269d84a3140ad922d438f9351ee68dcced4be0cc1be0096a717b090898c7a4b42c709cb2321d461e8c48dc9abfef867f2605097e9cafceaaa1c13117593bf3e4a47c350aea0f9fafad053548201fb07ac10455f6921da3e042a0af83797c1f518766fd5d9b1eee4e50d2912eb8059b9828ca6e9abcf7fbc8ca9fd31040dcf1a854b7ddce1823db49a85ae8c738472c347d5d332b51435ff82b2f9be8299e4c25ec3cdad2cf2372f312ed18b598f946ca078925c6511a63fcf014e95611009c314dbe8251d12ae84067c4f60fa43342708a96c72c8384fd3dd8510180f6b49dcbb0d6b0facc1431f6c045348ce0bd87ef9a7236126248b2cccc0697081632bc406775d2a81908d720f4faf784847862ee70967996516e8b1e6c36ce347628104e81f7537c972c8e4ab9c91a6f1f77edc7342c14fab39f3a89e3c77f02d08d5a46f3e07b31cf0f6fdeeceeba4efec088c521ff006ff8c62dcb71f444d65a28749a9192cf0a5c285a1f5ff79e8b76c3d4b15ba348b53041aa272efae3b2e1229e5b848a53180f2dfcdbfca0b368a59895ad8ef89c2db406b321ef980a673d66af38309bd1f8c02f01c5dc5bc307f642fa10ea809a214a256ac01aadafaec2fc8afb7e9a9060002c308f5e70b3ddc778f6aaa93630cbd17812cb210d316ea765117de0d6a975d52be3b032ae5b4f7f8efd0c387d042777cc46081a21b01929a0e851439ebcf53206053531bb680c462e2d8384ab322ff49426713b8a51aa30799d442c3772e7d72e53de315a6be54e85a3cc8b085e2837708d04206ef9ed7c075e54a3a1afd1ba122d34c298db267bf0de8979d3ea39981d8b826674c14bfcc73e1a40363a6a8d29858aa7a71cf3b41962433b4d4c38e6551698c82f67f33d41e13280121e551306c57d9e157f35ea90947e3e0eca751dfebb4528f409f8b7afa242345596fbb005cc617209a7bc2349235d7a01cbada55d7e457da18c3dd779f95a045a29187a18f7c25c8cfa61c702da793c22ba1ce87f369d82e49eaed8d7d99942de1e71cd05211c1a0da9dceb8776cba9c9de442336c572ea4d9deccc148b68b634693f0c2e17a10268df741e380d585ff3ea618b550537330b5b4c046c79c1419c7b494b02096cf7ab81dfae1a38d3e1956558869d84bb362b3fecdfc06c0dce58493bba2eb27fc58a2bdc4ed36c00bf922c5c1db5de02a4c432050a51ded9b099b41cbc061cc328788be07e4ccafd40b6bcd297b04797b97014eb32d258ee1ee2db13720122e99e0da54f6fb50245e680a31f64f621db6d92742171234e7586eb47891506f63d0daa7f8830c7f1367784020113578b8aa8b5dd4afc9fc9cd33172555c01eae152d42a6ac71c10bd1bb6480b7e40f8c3e2479d6c13e6b170811614e30c10797e04f4a794b23ad86dce7b68cb182d3d85328272e204224e373c5e5d7b41d29f8ec5570fad365770fa970af609eefc121da6206dc0d7f9391279e1948767c2eba3e936dbdc0cf22b8c0c670eb33a91a751d1580e32024a2a348e43c54a1f524c5c7dee7bf08b6407a4131bb7930d20fb78abc761d045841181c23b71807742e66ddd71bceaad5da2812d15f6bd7bf4b7abc39a746237b0ba166a1eff6a6361dce8dd8adb27ab557342db41bb92bb4dc1cee964d945cb4498628d373105d6a13ac28ffd7e9d74791f69bea43c9a30cc3d94d596f9680c3f04eda944c3eacab279565526a000489a00586d9867741b8c2bca52d99f56569164586ef339b1d0928cf8a27507b425f09889e3356238dcbdfe0d82ea0b25bf9fc7dd421156102771050857c3d200468629be6b8d50cb2f8ba886aa273d990d7253872a176ecfe2b2447b44957ad7a69fa0fba44fd137cf23203058c369401d2a8968b310b41600a1a8cca2c4f7eb5c10fabfb3912f6b4508b1499b61689286c92e2e10253fc62050db4c54731b5dd71fd020918713df81f373894c9e02ac407850911f7c65385a52ed9beb9b040e0f864d586e70ef47a84ab8009b1c26a482c661cc055921580f222932759de0b675fc5798bbcb1c97100d0e1178c3a9fdd87016ad164dc955b140721c4a127104109b1c4341dea673452c92a61455d7428e3fb33661a9cc6e805090b9f3af1250dc3692e5059ebf26b55ed24a1d17aac0b68cf098f87e87ca7cf0ee33d642a56905b9fa1ef08da3c79561b196b80e60928ed00339f73fb46fa1414a894a6a398d2881b92cb79476d91e9f05b709bd710e917802dc6cd31b342070d5aa5d7c38d8cc4e50461596b5d7240aac423856b44ac1d7695422ef9d190410a475b3de9d662aa4db4bfa5ff7f48cf9134f88de6e3824fed4fa82b8ea0eb7c0841152da5d56674987df02cb6d40314192857fdbf1e72ee745126823d350b1b2755e28a5733de1c902e753dfeb0345c45374985a8230c4719ce19642a6b39c001e40f6a1550dc098de688f2e5c20ffeff195bea4e58d45266c19d09ac4dd1c919f7d04b1c9017f95e5d6cece41b7f51fa6a767a74629c3fbf7f8a8c53b87e14172b8536b1752f50f587b3e87d1d32fc1aaf8f5c8097788a181144d396004ea52c248fc06ca0532f69b66a94287f5465e274cdf660854ef5812e9bd7d202cd361a6c9ab24c0d08eaeb17234f7b649849b17a82d2b4628e601165cbfa735b4a970d74e6fbfdeaacc9d23d2b7552f3e2e7f9cf36f245d72b9b0562233134fbfef13017c428b5d653681f822febb94d0d5787caa2fdf62a065b3cbd9cf7411fce960208555c6f62f6d0a9753d603c45b0ff2c26f61463fca3e9cc701ae605828152173319e1ba545079e1622b6313a693e3c91a61280b07b454303170ae71ed3fbf10221f39c22c89c3dc16ee2a8d3ab33f3e044bbcafceb519c20a6da079f6e3d818ce53aaa8f48a1cab2e844af148fa69cb3352af974d9161b8e46e514a39aafc211918caa8dbaa52c6d92b19a3c0e7aa2e5315f646464aba9c170dc165f088d92d3eb20cb4e9b6df442a4581f7bd621f7359e7107aaf2d6a96c8fa679b61d5ea263408751bca74056732ca92490d524dd393dd1920ad5d73bf36978c69c5a91413eeb815b94283fc18604a92c7d581223a897972e1d11f5d5fb18ea39d2c7c082c2f92b900e56c6e89559a144646c92f7172428ed7dad04833905b40d9fe3d02175c54ec7dd5eec77a2f83459dad2c7ea0afbfd3990e2af01d3adc3bbd2d4bdb2cd9e668a481f993b20b52d6695d4cab937d3388872e7f5292a2be8f19e912c51cfa1edf49b1f17a32fe84c10339ef67123b970a0ee9c32c498275c4069d665010942d89642d918d1608275e3683a6965334ec106a0f33fe20bb6e2cc35d65020c2abc37ef27b01b8baf7861ff6e75a6c878ec9ae8518d3193d7ba6211cf17610dbf3da6d82edfbd998175540b07c81b9b82554e8595e48c14f31e6fd979fd120b504192bbb4041af130e3443a95d694f484a388ffbc15a9f5cbe69ec8df85971e971559580e062fec279baec48c4c980a5b3ee9d9468135b28e6456c38722b024717827fd83ed7c07213e618ab3fc32e8a7afb39c5c295edd906eff182638a527576cde3d29dc6ee178378731bde6dc6b6d3f86eb97ead0f38894d9ccddbfc7009cafa51d2cab27496ad63f1e8dd6fba1d0f8d2ed6472d4d1b0fd0bd84185161bc89f8431adc4ae1c564fd79f0cdf3d331699e02813f944dded4444da20694722d06a7a3b2f66252781c0702e08d8d6eac0cac41111e1f19cee0b32ed5e4de626ab830809f85471c97ee8d18f0e49a9f59e23e2ddf20651ec29cd4b358c6c061cdb615bf651f6007a2074e4f5679dda0f83be4de87b9649ad16fbdd7e951c2d10afe06e9a07edbe7d7ac216cb7210f5d829c8e094aec84046bc73b3ddc8eb0d1a70e728e336cdad54f8c03670cc53a4efb8ccb1c64bd687395eb426c63fc3701284e98f30c881e829a47207642ad663d6fcf23733f0703a62f76b9d612c642910524dfbc4ad584ecc9aba8883766d6ff71b5bdf87de0301b7ac966efc5cfea32df53aa6133c431afc06ffe5fd7f230dabb3791045aa1b06df3031c9af4007ff16ecba9d8d3dcf9bc228867fb0d0cb6f7cbbb301bbea190b19d53dea570589ad22f0a4c22f7c143798bddbb1db1ec81e892ee35b7bc566412706f6ba39db47222c5b24ceaa70b934f696b3042014f4d71242f3465fd6bbba7fc2aeb209da45d8168749bf202b7d7751a2c7a6738b0dff17d8ed462a2a4d03940f089083b3e07113931a991816788c975e884ed4fabe62624354c7d7cbbb444f09226f28bf4c88180f64406dd0a9d860333e34601b154a0f617b129b91b798f2d6642b1b3f6f4d048d5f4ccab3a704884851c7dac301d61e83eb8650b4101bd0b5b2d97ec88c5022f0f15f227881968414436094841db6d1ba966046c9f9896f897c62811da7f10c2bb7650d2a76e618119fcf7be78384e4802def8df8e81700da1295a32a138e2020174ac7aa7bd8b333d9ce80f19d89cde515e77c87894c45bd66435f5603240a0656a475363a01ad7fc570af47536e52d70592ce4e9a8b45480aa2dcbfa1da14c96f85e04ec5c925b1fe7a72e20ad432f905dad4c272b7cb948147daecbda602fc461ce29574a5feab8a23c9f5c9530f4de936aaf119781321b8eb04fd221123971631c97621631d403795d5d9908aeb33310de43fea8007077a7acd121ce220cc548aec560ee0fb11777ee0fb6034800a009353c47fd8d9f59fdf1812f0e6165cd6906e559d0639f2b89305ed45e9de8ab19564a549b7d128fa38685eba0618a16438b5e899b824ab31a49706b90bcb5c838d18b9e70376a54ac54cd871a60c49d283b19468ee15da356cb55ac7aa8ee6a356dfb951dbb8fb928d79cb39791ff85032801bc21e98725d3fd417d948194e8f93d330586082493206aeee5f672b47cbef3d769fd4c06e2adcc54b93df406d84ef63f6e8142746767963f1e4031a9e7ff72c05e1551d2626d1472dafcf890c11f1baaaab1bdcff02968609f6f4154a817867460ffa14261ad963b2976cd6d9944338acdb4a91c2a15a421d577b1f0cd6eafde870d2d1fcd8b3d03873bb113f133f2165785cbb4ec4b99137a4dc2db3313338c4bf136ac9c39b4053ab91a5017676f447a5ca720db1c5f33ba2e0203d82562b9dbfdd0b5464cf411a4ec39ff798b2abd5479d68a18480641310eb05c1fca5bf8c5132330c5c54bc23c7913e2b315d9a8271db1b621b500612a25e23482623e037b0b6773980a4275e42c137330ebfbf721a39196f153b0328130c0b2aca7467cfef01cc4dbbf9a8a0926c340a58883e4b0b59b9afe62a8c62d08d18562a4fd95a6a3d70dfd90fa1a15d6952d83a85dcb3ab079a91ba67cbff6775082abd4ab25e8feb4e83857e5eab021ae8a4505dbe7a3dde2d36aa0ebc508cae1b49c818f5c7165e7ff39a473235a75a9b2333e588211d0ef5e7129d3986e9e0213d2de49dbfb62daf700bffebc1727aa70907b77e8cb713c6ba8cad1f0d0c800864d208c935343fdd3740cfb370faac2a80961a0f3b8b35d0447005fc0e82022d949031d5062d4f8aa744cc623c4d6d671768c62cc023a0a2461b3988214b8f215ce83ad729227f4a3400be99c58bfabafab8ad4af06c17e28a10ec8f8af06626e1454f2963138e56c19a4f6ac189a552f48179a0605425fcdfe1ca7a403cf2297e9a7392ef35241d75085a64983b8d68eafc54dac726b6d84a94e16874e0860c6f472b3b0981400901922b07f2fcf01a54c30cf6825b20dbbe1146991b852c1a9a6878a7f1f43af6a26a880f0798ede86d0430bde95fa493eb91880e91285f2230058a0cd7f392a407d2058b56af8f3dca57b484ec6ca4526ee5e1ae36f79401ac6be0ec199215cbbb9342f6fa48ee5fc2079c21a44fe98d901c0c437ded112b20f9e1d14722d0a1a6f8e3c5ae5542b664e996bbac6184959b6007b43d9c960561005f6d238f5d3bc6ce60731faa20b64e59ac0cd270533f6c44cc6e9d5bdc057500afdd58bd889de4b82459f36be31db8afb91574243c8e1acdb67828f1e9183add21c8cbffd759306175151d5c4fa4f472b2b75c86e3e25480cf56c48ce4141595fca7a27e81a3c41d623170d54577eef77228a740c5f72b306348fb220d2e48fdd3a7d964de9ba0cf246c99d67200ee6e340a0c8367579e674a4a5f33512944c67f47c50e3570a3b47ae1929539f12c92075d326900f390b576aeebe9e6094000860a65184372332c28dfd700c53451f69568ea99c67309a4f07fe9965e12ef213d1b038709b1befd318e147d81e508fb2bdef04cd29f9a67fb0d4a1ee312e3f5792c46144ddb8352c4f042e61ed5a9a3850fd9850c9c7f1cf0630b3a6a1ec33bf3df6527fe4b12da199a1e9f94e31021debbb6ffedd6f10b71a1cdabf91e082b655ae4cc1d2e1b60ab79a92a5885e534006c0bbc303120f2d6824a10f10bb91d471511c9c24acf37c1061aa87aec6cf9f3660ba178576a0f482364dfbd15bde29fcfe07eb227db46d853af20da62ac6469a7e96e1e1d423177fc3309ad15ac488adaa1731baec815d86b4dfe6804690606a8822238f26b3c16b105dac12757991e46ac2def906b4a5ce65aea1d35ff0eabeb4f0845f583899205f33925087b24680062abf2bfacce5706551a5db92655b0311e8956ee3bc0d8a34b4a83244d664d1f71d3f4f807e7530c496f3504363d1e2462f35204e1b5fd4b7592e318ed8d0ba6c6cf82eea8fe98f6a3bbbcd3ee9c6c7672b4cba6773d47df0686b3051385b0d91358f0e9c73f6e71a93c15342fc46a0aaabf3379116dd12f95a2e30f7168937816ce74020682f78f0f15a4eca7870bdc17d4f0b36fb6db0eba34a517d878fcfe8f2160a608e9872198e628d47f55301e95e72184f9232b641a9f7a061c56f08d53de42e7f013c1112f76d21023a517b7d31548c2eab75c92c8d8311df000ef658c3423d9a2689069ce94d84a3d4f0d22781c03580962692d7776b4189c2722e1d652a5c109bae7de3860a66cc7b24d72860e3f43e9d0525bd21c9925e3b3e4130a73259fe1f10e44eef6a44da0dbe5f23dd48f8487f0bb7944f6280a507cab9587d26c812f6157deb1f312c53454e855a178d8282c34d93f20f06f1ab53520ad6cca61d9526c18ff7a37c60c431994b63d90fa5a7a16e4d34a1ddc0440c54904a6a94980e95c17224c4729862a9d26e7148fcdd79479f431732ed609664b7264eeacdb27c0400293f46c5e78edc80fd0d329cebbd45774ec88a46404c02b85d4ea7fd4ad0af626ef8268dc528e42d88c78c30757b285f07d2391fc0a6b4b8a4594c528d07833f1799e521fbf56aededc873143d5e7f027602e3cf308e4696ba7074107e534a1a545a613362eab5fdcf4a7e24ed0131349f0a138ad2d06b11d96c5b243992d1043952d17c7c4e294863c4a935fdd19dafe178bdc722ab0484766b0df419faf509b15a221d03428158513c3976eb5fe8d608ad3cf2b288fd1cbb13ef5861622006944f60a12f6bbf6bea0716f0814994dcba71de0f002b63902f9a23d06619abe4bb5eb4765dd8a51dbf12f94deaea567e45397211818ab423556e04576e23da8465df309f46b735955dae455c92dd8e9a1108a41d50e8efe970196f109d249c781077ad9f6454fdefb125ac4018a77e78ff1dff9c106f125c8952b7af0c9cc3e31879428adbc797c0da2d0a15caebaa50e95d965d80f9e7ccab0c03042033c2324b455283f43230e429523ee4f5959abbf2c434df007b5f1d715595f140e0c8f40b7ea9e7421d20fea459089b89dfaf43f0c88551b27a3e65b3945e380221082caa460e084b04aa109b767292d056c9ee9f33d5cb10b1b1f59a0279318cfde05d94c06b3fdc481219467bb3bec6bda69c67d53ed402be155f263eee937cb54155b12136a89a46e1734f4deccdb583e7540c400dea115a04cd09b2f88dbf70ee025cb3683b16c9e4243eda18272a727ef90ac558262191c9cb273d4f774631c1bc62857719ca60acdc1b962c2c94e43fd2a7fa99d5f0ecd0b58485875e38d85a12f1ff83a20691b7990b0fdfb562835c47435700ab01f5cd6728582866d6417bdad24896d682f57327f3f357f92e231d7445a88e8d62a31657804bda891fbff40aebfa7f1998e0238556c88b06cad3e4649fb8ae0561742e4f0a5470ff1d960765815806655e27dc35a481884aef885816125ddc6eb204e45cc9e3a72bf6baa8b8c842c5fa47837fb7f939bcd87abde3aabd1e81a732bd2dcf1d6945a33155ae5040e039f4873ac6d10baf1a9e43eb12078833541b2076327aa6d55a090b541f4810fa7b8884ea88c34ee43cbff40d44adb4fdbef702bb488a88099a373799583c0cb80dd2d248b42ee1b654fff03b3806ee493b2720c9b3aadc29bf471698a900bac7456c00b3f89e208250d841ca24424ef4c6e3b07ae9aa5a00ed1f766b7a929a6de5e3a70dbab9c142a3510bbcf84f88c347400197ff4a9f7da8346713e664a231959802d7a6cf75c2a173c2db344e6d4a5d56f14ac840a76697737e218df841fbb7a8f3f08513b3c542e52cc31b94ebdc443d1078b4decdf9a75e95e8aba608d33431ec59b57febae0f555880e116c692c2e9f1a9a65de6bc2837c768c3eb51683d2847d094b175a879ed511e66165f1de8abd1dcd23cac7c1ec82d9a52e308e963a77cf65dca0f0db111d46ea30706015beb00ec729304e0794895cf4c9ffee381b9dc4db3fc4d44181e018a6ee8000b868ef0f6160804464b254d14be3559d4caf9678b5de7b7b1a7a9070d0cf44ffd032e70fcc92e5bbd5cf184b555b97e34c458f87a09abe6de3908048bcc6f5507a73b2223ecf3d9c29f17f00bdf6d61e208cb9005a768db218320e7e978fc959b55e7302ac695dc17885a23246b49bfd619e57d49863161c31abfeaf8f8cdf8833eca414424e4e8845f127a575087d5913b89395ef2aa55d3cf8b3b483f396b713c65a0ba185653e2986e5115071a047fcaf0ae1fa19ae7b04081b1310982d392383bb222ebfa5ba52744e12a72513e438cf6d03af216476c26994891acb28f59838741142ef12497861ec13abc8acbb2466268e8caec8284202d03fcaded555ed974b17d41c330f848d0e2f1b5a9108855768efac063c9920ac12b6a879a08948d0f9200ef3f75da5f41b2f543761bf7d0d86e56cc989297922460db73a03ce84ccc4030fa70397fb5ebc5cbc8f6cf421f23c44bc6189df836d6ed6a0fc78038a5a8608036e674999c34a70fb35b8465c0d6758728acb8d73eabb3ac644d6758c0c73296083f3954c9432d9ed6c71996b021695e7d65b5375b2895a334009edfc2a6919cfc3eec78ad4b9287987f1299da8bedbec20a505cfdbb44723d4bc3cd2d1fe12f00b19849d6f72a610abe23dcbffc8ade7ec3bd0317af222b65c7ff5b5495220fc13e5cda3fa09da3f95fe2d8d76d6e5445d3dc1643b9c66b9c7c8107ed50a0a29b31e66402fea924c509767ad063dfffa4ad6d54d7f58544f1bc2358feb112f8ea19d97c6eb91cb5f369ad9b4107d899d1cae3e5c724bffa48b87ca17f35306d3812384215d1abf008a7b907ad0858d50c125139dcffeaba4361b7f953f6a03f074cca6df53e91ff16c78827e83f0ee880f4f5195310028394fa5c5f3ba09186284bc29f4b6e8416a138505cf499953a2c6c8ccf9a564873d76e865c9910a20d228283e2cd33fc3f56c013a8d7d07716f9d818dd161199b436dd88262394d1a87a38a541a85f8b7eb998dd13fe030b3724d081dea153fce02a84f5558de530c44755f6a9881fdf2e0ace74e8717b9ac72bd9eaaff7885cc06859aa9aebddf0ef40c17f2d1a683b99702ad953a8ca9a51ec84692e1aa88ceea09f4bf605ce20b8cdeda1e3a28db51fbc731c8849bf745eb4e8d856bd9693e77980f418550012794cc6d95b22716d9afe4d185781264b1192ad706040d0e15d4821e30e08f34048456ffd93f3155194cbd076c24c1f5684354f0739143b8211d2991f08e454427e459b107a71f3e0b5f0606c9daa4b4dd3fa76c853bc858ee103e50e7faaeb02a3421bd55fa8a9e287bd2e05ee9a2084aef08260f837b4c3013fe8e3f6cf9420fe4d218ce62b4da5abae4361e0e5e97561c9d68188229a44b345cf28257cf8f053e9f953d6e47e881c8cddc7c1bbfdc923ea870e8c241ef5e7902e730fcf0292ce2643a1ee75a36fd97025cc20e150b3080d378d6046ad87a77ee7263472719181de493b6074cf5a8c4582b691c75bd21d7affa7719d90ef574240bfb654be3072740670a8f778713f5e79fa0343d7c94951d4e1dda38945c1f1c4c79b0f46b1794adf40742c52f886c76405a4e43249a6cd0ad084b03e2523c8631e348666d2f48aa9e998b93e0e25dceab0e1a7ef1a55f7c65f19211cee7cc13f85450317d0b12dbed6276515724929d660a69001e89c88430b48d4aa0c27214317d9ae2931b35e51fc52919c6c6587d109f3ee90e3e0d362188a26ae5ce80ddd83b702b7424ea9db01b49731ecc57445d651091b4bbe3d1bc220b3e5185a8d49a1fe80a831ea7e2fe521e3e04fb11b42c2e4a609ad6015bedee86f0189457819e71f14c3627b9f45f6ecc3447684d160ea4ac997c73642271ce1e6a46ecb8bde88038c39d123f4959a78f0c8007855cab251e8d3da4d630000ecd9126e6833d63328a24c422fc59d9359e12dfcf27d0c5f0199b4821e3cd1de1ff163fc49a9df289a9974503df73519f1552e44e1a98569af102affe855d8f39d6a34742ab7064c82c88bf08e8a01352a500a36f795cdc0b4037aac666c88bd9871982bb6ff04dc88a5245039e2ab2ad19240ea285951e6177b10884632b34fad1217a07b38d550559090520a9e1b863b056838b479879f1895435aa98220a8f9a6d76db3473a6d3847f65040f7ba4d761ee389d4da5f3413232a7046c0abf5070c8b99d88e641b201f5da1c9afdc9edff2bcdc2f470f991089f05dd50150db240ef0f642d811eee33b99129b73f096d8cdddcd5859c0d2e197a96707b15cb6b3702c6682907c8688922ee114ddd36d9907ceb5259cd5bba0084a436ecd1642d23b7f66c6ce0c64185c7d8258c977a52178a57b60b41ab9ece7b84aae11bb5950bbff2dacda0d64240fcb40409ed7a53e69477d230f149529d3fe6428682453d6251fd921c8688547eedd51b5c68844880751a48612aed8826a37576d2bdd8005f765ac392551ff70cde90073d7f0b5512a16dd2034c1376a4080032dc0abe900746558ce59dd2c4d231a706d2665067273dde3df674cfa4ccbadb598f42e13e846fc4a22035f9b854af3c2500eb992c01097039140dd976c37dd9fb5be240f8f89ffeb634aeea48d28b8c04660eceb21c793218ca51e92982bf6e6f26922df5298239c4a89714e8a751cd02a659df9529860a1514f1a38629a5873ddd9b6090e6a39a042002ede0e9cbc9296ccb230a9bae17171ba4ef5cd6001157c8984f129d7b7a851066bd1fbfd5d40418eb076677587b8ad3f0d30aee8b11a1b309a2a4aa67cb340ffd2c851a80ad034548f1cdd55bceb68bc6d92b9b9d2a6e0fe0df3fd0bb95a18ef580e85c6b74262443a276a822babfcf27aae1c1c34816f3ebc80506330c8a1061dab2f6ac40053a62579fbadd88d3554c4ce5b6831fee23a3a531d1ba63e53bca00bb43fc391d63f59a67199feda087c1165c1d5995d0720990e89c48cef7b25de004fdc9190a298c67c460d776b1841fb80ea780f7df5acf91dc80087a3ab194c2a97729c024e42668964e26f5375a7fbe24c1520643ad2f349fcaf537c48bf433f5b9a45b012ebda2247a0f0bbe48f1b1d0e846714989b47d6f92f0d88f5c8739a31bf4133023e14fa286411665dc848f4d58d344698847724fc929854caf1cde8ea0d09c07b9f92374962f73f2d1f40e3902cb7d56b15e7d0eefcb961882c0dde1878b362784afc69cb0794f0fd51b61c1b9d03a02fc47ae558dd9f4deabc27b59977f492e1614d7e474614fd8dbee719e0f69a2f0ce128a6f34032ccb3c35f82d313e590947f4f99ea483df92e7639d67d072741304e8e0bc74dbd0b23f3cb45d85a3bb26374a4396eb3b6a4c00355fb8cc775aaf6703f201ff59b1b4f27a182df262d7089677abe9ae5698d33b15fb7d4dd4ca5c3d907daf4b549e07f51ae0b484c99614a72ed2a0e63935ddee0ba964ae607aba417e84221123ab810580d225047f4929582b6a546e716b2b9c090d4b9ef3ee96ae81e494a5e9adaf4e9643b9612c332e3cc93d565710a48f6e2090808a46e14fd79075d0a72f700e01ecfc85af725a14440a5a40c1004d11b0332ca006e574f5b101aae2b380d39a2a74073f9506bf2e0a6db9e9d44f3c0b34d8f4691cefaddac68fe1f4b9217b8da1ad1c6832af7516ff283f1c24162d5c9d43c6535af3b663c8f6b317999b5a467360cdbc798b621d6450be808681e1ef26c3b9b41b45b8f6ed4a6a3595a19a15eda260e91cf4bd27cc6c4a9a88936d82713001dfb2cad647702a2bc220ae6081bbbc13c83d4d4e062801150d72d7e5118df025a8358f40f4210d7ccd0c64a724bfe36e0a125e3f2f7a19d5762c83f155a224598217f7bb4e7888d0aa934e3093280e049c77787906ec5f65b531dd8523c41c007152ee734bb9f3b41c5ac053e08c2a114b7cc8570dd2060156591ffa67b27471a6d3670e9084e2723e81f98deedafabecd6903aa119e5a8e848c7516df9aa6642fe93d368010ecca14808cbf3b997b04f3bede532447812f18f9dff221fbe5c04e44c2a574bdd76c15b1f60c84093c165abd36b325478cec46b35db110fec226147ac00e55ebc8c2d694c9c5a5a94fdcc3ae9bf905c8a7aaea5c51011c79bf922985e92c6e34eb378a308336dfb376803039ce0e234d2d8a3a1a0ee6b3ccfed7b2e36176bdf444da598ba702c752e2fcfd2e98a4", - "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f710ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c9904fcf7f4ac91f0dc986701c89901fb7d914b8da5dcd57d430d860c3979baf98a" - }, - "decryption_aggregator": { - "proof_hex": "0x0000000000000000000000000000000000000000000000056cad7c4d4ab29b08000000000000000000000000000000000000000000000001c619e9b18c75b568000000000000000000000000000000000000000000000005d70fe88223230f090000000000000000000000000000000000000000000000000000f4d3fe76e6b400000000000000000000000000000000000000000000000f3b1e196b01bccf7500000000000000000000000000000000000000000000000b6a2a87540a20bf3600000000000000000000000000000000000000000000000daa621f0595b95f1a00000000000000000000000000000000000000000000000000008d5a8ba7f638000000000000000000000000000000000000000000000001accc4779895fcbaf000000000000000000000000000000000000000000000000668ea7d6e9d31a1f0000000000000000000000000000000000000000000000044b0fb30c4478834500000000000000000000000000000000000000000000000000006bfc6495aec80000000000000000000000000000000000000000000000004f4f3c14746f379b0000000000000000000000000000000000000000000000088dbe00e529eda58c00000000000000000000000000000000000000000000000f2605405f1946fd4000000000000000000000000000000000000000000000000000025b1f866541452ef1d421942cbeb1c5cfb5397da431759d5d9a9c317d36a930660d1bc170b4702ef125b0f2c11c7a4326be8bccade5618401aefc5255a1c696e6e85324f1050f268c15d9ee4f26e41b34cf4f0d5cfb130caf915adfd5ba31f1bcc79825f919471d415c3651ca431b5f3cd654858e981efe0855a21b2e38d123135b44710f1cab2c035e4105d4bdd3529bb5fe9188da07432c5a89e76b8f89a6fa18f3529cc0bd0cd2927992356821b6e43d1bc83f471bd00bc8f49254474a4f608093bfed179125ae77567866514f161a7684c7e6f6655e7b13e3372a7134f9af19d9f684fceb06f4c1e272c65fdd85029c7fb523f641d823a62439843c26aa5cacb8fcf0dfa10446d9cf70618a9814cb612660cb51726a62b6e43e543cfdddd4d001513e0d9529b98f6dfe08ba29b43c0328d7f11c2aaa68a41680f6c09512906652df9b07b81922552a60c62d7866bfc580eee4c7a39fd466127d0467fd96a77f978a90deff11f53d729bdcfdf44340633294c43751c8ed5297483960c58ab9f5e4313a5e58037cc3e1e0d78015e20d0d922b7dc641a5d1ea3ccdd01925140b4035dc0576c415198c1b75ba202af61715a9e087da1e48acf524606b9345ba54bc72b3447cbb24b16a9c8665ed01f422f4fc43ce9b9b4f3fd06dd1e170974b8f58d297c6998219adee798f050eb69bc48e574c8cc88e5f54a599078596ab2010dee8ad7fd671166a365ee47c4303fb7f3814118d649b5ca3d5f81e8532255ed0a010c6f264b0270b360e011a625807a323e92b639d9c82d3ab7fddb9c617a42b341b7da8cc8f2f3a68ea0915dcc62b8ac703522c1ebbe5530bc3f347537fef899406586e07d21d6e94d5208ecdf0a86971102ce7d61860e0bd1b5125ce717315f91e4d3bd4100f7b505fad6af8e3abbdd4f0759813aae3a05e90c23b4ba78c93b25b1711b9082145f3fd8aea81849b9eb991eae4d7047d7d03ddd13acca9a9777f25674154e60e060bb5c5c7be3c78c5b31e43a5c897e4caffa9f7a1784a3421260ea5aee2d02e6433c0b5662245c4120deabd578c95be23824fddcf69241423fff241f95fba244ad1484c09e631e1b800a5d1ddbc91300085db9bacef86ed1c4d3cb780781e1c9e02ad787c161b5797f8f0659efa8344be77edca236a9fd2bf7bf2de0aa7be073b7654a7dab5618a0ce0309e58b827ba0946e73ef577921924d315838740ff2f02dd4e38468fe93cf477bd8895f1dcc5cf8ad4183ca384bdfbe3d46e4bfdfc13fddd978b48eb5ae0468a16c16e3a40d52eb88c6698a26fe59aa829d3548cea01f8791499143a368cc10df96dd9383f216939090abd0f703ffb62811e52d2361b848b466597ff32c1b723f6160f5e2a142b2eb8e636375a1dd708b9593913d80d2443dbfdb9aa76ec2b2a38a38b13f6511248a7c672e7b2361228788754d4c622966be5bbb77049e05d240123925a9c1cfdb7abab0f41c94d1874090481f9110dcb0a7e51c334aa75119c70b570e358ebbe6a273ae63baf45a461b2508e220422a32a363f8a7c9a1b2b2d5d5477762295c405aaab172eeccf35f892a410c5d9098bd985c36b0c0e5027c47d43d38200babc0cc31af1b49741a4af672038927004aeba9f5a687164f44ce33aee7a5c026f2213eaaa2e1a637d9c946bae55bb171e53d2d5e5c60820d878b6e6a3eeda0199fa2608e90a08b0fbdcd80e5f445c6e0667b98efc1f4fd2b08b320aa8a56807767a8d607c28db5ea61a5ecf9976ce281908a1c40c1000f3038f9196f47dc0ffd1d74305a28ba020cd726f6896f7fe390225cd292aeac8305388b6b765ca96d911283e733663900abcdc06ef4fa7570b15b7c47708512ad8abeb9173b1e6871fbf4315c843b2ea3a91afe5b23b82139d12c032c998348c3f44ed226fe1afc990192fe8bbcaa51e4547def8bb76c8a866192b0dfb27ba2db74f99b66881b6b9259e30e7795eb7524f2b82a997ec646e53031ec3c5b8b34022c16181257ec59b0884c7b4fd20d4b9425e8bd1f375deeba525971ea65b4a5f4256dd47880339f6ee908843d7d2cef8dad1fbdb75c2ca6ada1415f83c7b02138f0602169c0f75725ccf52dfeac97bbe61f439738325607a9e255e82ea48ed8af7f60d3a6b9f4f7c15250688bce43dc311e4e382a8ab0c3dba06c7b8c5ede63770e92feeeb31591d9e35f0db391bbdd3602b73bf8a0f0e91892a7acdc0a53834569dc6b661f12588133c0782d14b3516d4a9b5fe5e9c9df5df0c89c531e0bae4e6050957ba7ef3bfb44bf0bfc1a8d9b5b3d72de063dba8772e0f21894b3966a410b2cc849d184369cbfc20a8d2e76494c73f6294745e969f521f0fd22cf1b3dead3888791fe3a073b7be51f92c285ebe305ebb9cc691bb38b02a7360b39a0cd4db80dce561d9e798ae3bef95013b7e9dd5e43c630b824ece8b023679d5122e7dc07c95c35f9e2ef131138a07bf9020d1b62c389fe33b90552304be90309b9169733745f5900911312d4684235470faca34ed59582d1e2d380f22090616478eaddb735390bf840de0e5751ad629e8413921c82423fe4626c0812b612cc2cd48365f7ad6bb8e932a405567f4cafa3e3fd446e2713f9c626c6ff925a4b25d6a356314bd347906144b57400a22f588169bf9d4f30e77b9c6126a7c26970872791915f48f15f1a6378a83f588850df74ad183e97a9c4ce006b3ac640d2a650b8f228902eed1d0c2786300bdafed28dc54498c78ea482dc2e893a60a017389725f4f281f267191e72df183a69e0902c10081a40fc3da3aed353f03222db1ac7af26d0bec38702928d402544f59e76e0bec359e880fa2843665a0beec29bca4e0d866154021b0e26dcd7fd75b17625bfd982e699790f08ac3a44f584a2923094ff82c4b714ff0dc3a3cd156e174bb08f35a56b7cb2c261a886dea21321c20cc2635ffa25ec21be53e93e63a8267a43e3bac1a43172cda46e031b297a72abd0445f4d8bb99f2554e6f539a71cf629a62cbc7d0c64a3b9dbe0d19f4b4620d83e8ad85e85da1a6a18a22d261a036180ac1c3378c125e4a0c03aab46378780672aa764d1267a28d7048f775faace9735fc5ee7afdc9e17fa5a9721e976f842f007d8690aa54a60c95bd9a013a80b59b6a22324bf2c90740967c080bcb48140eeb8246e3d623b8d388a455c9cf7f1c26b5e98226b396810015c7caa384cdaf07b549ad42aab158f69f3da72c1ea1a5c7cf00b7781f5e5b62ab04838c2f6586209c0cdf477aaa4ba459141775b67218e064b09af3be3f2a03854839a097e3a214f03e13ec21145ebb5ff5c81e1c84a8dfe3bcf4892c79d741144d2a996bd8422321999bc8e0395ff453438bbe7395e0695e49bba09ef3d8764948e1ea9cbccf2fe535c918810038418b8fd8f048d0db49bf6c1bfd553b0c394c8f043240a1a01d143cc3c50f981f3e7d6f6826ce7c2af850858753ae5454281ca9f929134e6805f200d4d7e2d7fea1b738f97037402dc6a3494b951274051f848c485d860c2812c2e371e5630f2ab4e56da8b2818468f4927c63699d3fb07611c88e0f2983b6294f3d21bd180cc64a5a2896d472e5b3383194141ee6003b2827513c89e48b0c235cfe5a962ffe156f1875f202fb14d1ef70eca3a0ea8877981010027167b2be0aed6b04ca467b3d9a477a1cf3f9759f2878e237c85a88ce01ee2f97fd97aa750f2c78111ff70bc2d8a535235222a617573f21dce2cf3dd25b70854b9ffd85350129a858ee033ad5f7fc66562f89d87afae6c544a8686499572a035e5995916e183df4a63d8feb24590f28621073a966a61699cd2377125be6043365010e08c61ed3b9c3d001d9c6cafdd4ea120e46860fbca37108a9a5b9a9f2cfaa8446a25b204c4f28ad5e52ab1695fe49da8663e90c2f797425ae367a7b4a42dcd5bd3fe926070c3ebcdba9804cd4a74722f73b0e5fef3e34743e1182ab54cd798228db6315c57f09394125bb7cba5c9d572ad6d255b4b632732cd4ec7063d63eedb4218e1f4f7caf1d3dd25167dd22623aaab18ca729628705911872313ffaf322ce01cc11c936d0dbb5b63c16ee60ad0a85b8964093eb18a940250ebda39766907bce66207f7dc441572f9677aef7a72d3e5fcec0c942e33315dc4ebbbab927bd09a2cd215d120ba8493452622c212d0aab531d9a7733ac743f52608390995cc2f752570304dad42f576fa8c181604c68f2cf87555228663a7c714e26eeb2c6e5035dc80ccb8b814f89a2383e642b8f829691753053f8140819204bd2180ef8c80e93c8230f81025fc3a42a1aa003c9b8eca00e0e3b850fd88c7e61e94d38b4eebb1c47059fd472bc0b8a3b70517698c7b74bb5e00def97185cd883247b4ddba10739fe06a3379164463d5854dd9a241327e5b419a2993704a75b513977b69b96b8fe8b0c7dd4726e5551284268a6c2e2667e0dbb3b28219223bb18f9e5af9d6709cff22b6a031590edb6b989b09732ed7a0a228a67856f391442545e2e1f737606bedc08f6e378d3ad8b0ba6db8d32942fef5e5378046832541b2d12a81ab902352efb246b2c10091c47689a425ec24e5b7f7bc59198f6f27189a2d7f42fa42b6205ac2e6aedf6cb543d0f606d543198e92acf412b5d884cf750f3b73f8897f702656901a19db1c90575af7dedd38bfb74229699003b67fbf938473413c61fb5e6c78b0878fb7a5db4a5b662313d0612e4c04a4464a176e06b478b5cf83921b18342452f324d99695dcf4ce33ff8efc3fd088f49d0747ff112006b954de65c9c8817af0ee60d9137093a9d4197437d2c57fe12ba577ea475d60906732c5746849cbc50162474e22b1c3c16e4d35f0e6a19c5ba983c4a1112f9281cb1f7bfc916a4caa92485487447bb3393167202c3696aaa302c00a8330093f3a1f3ff72baf44420392e5d2dadcad2bbf8303c926c7039c3c79c2041922c6b26504cc48eb5d12c2abd0a7515c373df38a8b44f793ee83bedffd35934f865ea07f10c96fe43e8857907000a4208a2703d320f159a24f346e3bf840260d052179f50919568d032a820df2b38066eba1ea7cffc02ce4c988b4787d58bdf85849317f0f8bd4f715314438f2237e14e38785e43212317697684d4a412ab17cfa0b6a64c8129424b6c7acb8d1cba0efa1a00b3e405602e7d00df2956376dccbae81d3faef40fca3ac6dcbf4f180f72866e5852fc2f0a5890da5d880214ebd2e79b04deda1742a1859f6f089b292e1c10696a966de1ee893258d934f9e851cdc77e848105dedf1f8337b074861e9774475e00815c94a84286c14d1e346f7da8d89ecc16a0c57e32813be3df9f2ac706f1fc284f222caf7608782ca6c7b7fd86c694a5ee6bfccf9eacdb748d332fb4ba7fb8df774b85b2d1f3adb3534985a4437db9ecfdcbbf9e0314a37b7c72205e241cccd78355ac99944501cfaf2c4ee0d0326ffcfe04e80b51d98b4f520e2e9e0f49718ba976711a22332e887c80194195721841e7490949f926bca49c0e2c5ac948fa21bb642670664aad40c4ce3f3ea70cf7902fff4b3debf9857dfc9c096ac7c71452d53f6a34686ff32984305fdcfed1fe0f995a35894efc50182965109605b2c39700a0ad4041c6541186a45e8d8218f4f4b3fe80b45ad08fdc4adf19f15e6beaaef77a30d12b3ca4303b4f55a4db68894cb4916a602f937439cb652f9b0798be3ed4da72c3fa8c0e1652baa9f88e53d45b7f1d762a91733b7b91a913790a477fe63688116c2b9f014462bf1b667c1e4f402a456bd1274c0f34236d06ed70c9b73a587e902443ce4853bad73c7ae5a937a1e5abb4a9bbf069b2ddb4214bb100536bbb39181927d13f2807691da20dfefa9459e9b0dd21bc3e8c33590686c366bcc30074314e6f086c6384de4ad088a49b786d4fe564b3e460fb97e00fd0cb2dcf6a4019d49fb759201a1509e305a20b0f87e49b3eae7218fca5f0b423824dc2d2ae4cab3aa343abe18d31c9e8a7ec65b6e8ef1e7365d2799b931a4c0b2afd800a183d8e0150007ffe345b3693f3acbb7ed7deaed961da6606e00b6f1b7a15f59ea2046f9375819019b86a5c67d16d94ed5b0d64295a6e9e9be90c853062c4bf2127f94e4398de65e83eec4f2e925f51ac77acd291fe3c4408f006040a91726760ea896b5c3dbb049108f42de5f968db4ca92e3341ecbfbbc8bd7968251f3fa3b07e2549cfe3232195b62b1b328895a777653358631d9ccdfa2f4b05199da8bd676437df062fdba92c8d9363bbbfd2cfa9b522c295983cceaf011e002198f97129a3e9981798ea7fd7049cd1514fb8163b0cb39dc8bdc58221cc19062ca8191c9b30ca4b8a7dcfa8066d6491e7e320a0b07c9b907d489911b05be0a726273667acb63e98cb324ca9064fe9a3e625634edd6683e695b5daf6c04ce97c198d7a2448ce0a0cb26b7ecff1ccbaa524dd91b62dbe5517a89643df21a01f1105aad045e0e4151c8ce7f781b40b424b1a071c214c86e28ea60d2489e594830d2a4bd978bf37e94f0f6824811131f99f95e4d63e6a0b13318639f9b78caa1cff2efa88000f5f654df97206a86ff10504529a5371babf812f2f9507b156639609268cc19ce52b7d8582cd9b3c2c12c2a152a085df6366ecab2be22b8620e077c30d95f6757d5f87a031d47d6497a2e59fa8bf4ac2cbbd7a58bb2f2aec7d8af2be0cb08139cc64f33d98e0c462602b4577ea1f0dc893671a4bee327c9b74b7db2d13ce138d323d1f035f1e3e4e0fd6eb69ecab1fe9ec5d2d3984318a0bb7e65c091c416fdf7cc647b1d3db7d46a8fb1e013a33a8f23ac33987832dd47178a51b2e0eec25fdade8e4794a3ee602f3a41f157191b3859a0b5f91f9dbf921cba24eef05f02af93c999a3d7e457d4a94a393daa7ee8dcdb9ee235cd52bbfb650aa70240cee561b03784a493a7109a40e337d51e55ae3de94bea91662a9dc7f3bf8e4d32f3d70587403d8280e55dc12f0afe0e6dafe9c19f2c0abebb0381546a5debccf264e53483931fb53449130f47d1407cd0c372637c0a644bdb8b25561bb28fa030f303a7d9bbbc6f0d2d80986a300cacba5276340a6f95f5a58dcb62d64218ba208aae2a01c8f4dfb42a5f93d44e870b78edd5bcf239888d6692eed1a118b799705f7b93c34b05ce3ae60f439c1742e22d456d35909b541df1efadd8e19eed68f1295e0e404fce2abb84fdb20c7fb59a1796b7db57ede655778fa81bdf6bddc000f06181a177c30403b7a3a75b0dd16518d63cd9e9168c7b891692816985882e40f1d0bce30a24709a075b64799d5b3e42f16d794f34eba8158f842a4b04e46cc1464e3d7f0282d9a85913fa90267ee8565d27fd10e28a2a1495b6ac494faeb9b0ba366816bdf54e694c63b753d9b66ede27540e3082b8a7172755882f56769130f0af577b8c3ede6e8eecc9425911787b62c5468a9ffea09e7257883b554d17704a23942749653ad9a87c8728fbfa56864e69bb8ae9607228bffd91643a828b31357a199ce3f2e4dc3fd57cb963d783242f9369e886376f57b9497504ebb04311eeec6e6c20c50d981fa9719fc9ed87480ddf9799ad62e7b1996293e2d57b0d92d05db41076cd3d90c81f793e57eda1191e5bdd40fc9d4831fccb2d33e8a569e009580985e29d40823ea35fbccb800afebdb2083a963ad2e72bfb0907cbb026e1224c0ce5f59107ac18b03307bf581f6ebcf3ce7800eb87b02a4d25c3c0780690a714e8aef53ad3e7ee56dc8760a1c6ac40b67dc97386716d8b7c8411f8e0fc10885b65982e9844784a2de0689a608bd2b3acb490d4a1a2a8902ffa562e20fea0b3ec2e1baf84eaa8955f757f304d164da3c8c1583567ee07a64bfa1e740f09427fa58b4185e625c869f6220eabe5b2f89ed573e76807d6834a6d93cf392b87e2911224dbd6ba3729d896600bf314e476e43c599de5b638ada7d19530fe557dd1401d2b9f08ce9d2c5fa7935c57f42fc83467dae1943d6c27882686e3f02cdaf1c23df9d61bd4f2b709fa7d2f488f999653318d8cfda4b40f774190c6ae7c68d04892a4456ad9ce39c61f7ccd63bae1f8735f269382ddab8f29590a03db7cc081f900b5fcfbc91245d4cf6e5d757439efc2b1606fbd5d2f98ee420a6b195a7322557b58063144c3b79efa8ca875cb186d97494f99c68ab9216d3a2e281d7d40f158b4dcce0f341a6ec3b566b77c8475f582af06b323c9dcc48fb8f6e4c24d8bd2b6ded7c6bafe9cb0d8dcca57887b1f03e43d8d38b7907ff65a37b78e7cf0648123971a67c2d9dd6a0138b2002ace0cc4839566f50d6095a9aa06a96083951752e8f860211deb7f9eab0bb30f442879145f272c019d2abc5206aae3924a75010275119d2ab7cef59e1636fad4e8bcad6589ba476e38ba5fc71e968541b1820b12ad654f7ebd9a2522d51d47dc5563ea7766799dd694bdba53b7bc2d2ee15f66e0e3fc5a203198545ca949fdff3dae7e730716d079ad70b35a4a3f49c32526592177f84da459ef90637dd637adbeac1f397ac1a8fa7da7d92e2057284b7afa34a03ec549f7e4965203ef4c0f6af45483907c7953bcf8c7c889f8540b93c48a746229d7a407e0b5589707b9bd26b0d13a7dbad9932aeeb8b7e532566cd92a882042b82821e5a9f5116c612818f9b586b639eba41e67d6c42528bca99a7189bbf2428231bf5a4a55bb5412bce1e75a98aae332ed95fcc476a9e18c5b2a90eac937a016a2a3d1ddc5fe9386871595a4c43ae2a5eea44746228ffb79ac2d9e4bb1d9e19cdf2ad6516c16897028def75fe6a78ff95e7062bfed70f2398582e004f7bcc030954895873d6342cbd903dbbe4b6f2f96b7d64579c9a8fca8996188fa3d9861501fe6f36e13a3c12589da13ee190064cdb3abc7143800a2098120cd0636aba23f08f43ddd021e098bfc75ed28215ba4459610ce3e6ee8194d76d83dc50cff7212d421e7d53f7a8dd7c2e1e37ffe54918f94f9aeba116460e76ac28e44f1c3b266386ba3d0083f22cf5e82672ff1bae279291e5eca52f58b928c5e2543af0e20fd256fbfe682dac42b71e11f695165cb77b9c7dab72d4021899aff8c9359ddc2d3310c8c8bcc83fd122e51bd5dea954f2970c5678b2b7e162a9d491a33e1a1b18a7c052d67d102b81301b710279d85f6ae7fb27eca6387bf45bfa08405fb9bb0449911ac0eb0b98c492b3675f3c8b17d8d4071115048d93ea92df10dd66c26523424c8b0d693ff682420404b198302eee8075c3ea7718467b0ea47e54768edc1e5bd11b2690c72032d1762d2bd386a76e7755b63a2d91f3c20a915289a334d82bed12ce87366262c75696163c36ff5b6533912e2416c90b6e307fa71935a5352a78296eb10928a01c2c4a651a4eb3d84093e27e6350fad6ead63ca737eff9ba04a9b5d17b1c78e1bed6711d5479d8d7590f3f050b7bdb7b15df86cba06af51c2a3341060130da96b435ca1e503c509f8e6efb90fd78840546f24a21472c757d0683c8408285b2c5268c325330e3e318ad6f968d606f1f6ba481531195bf905823fdec89b3dec12f3055bfb8f4e93c5756c65f5ba4fbb00e089e1780abcdd4260ad3487daa873a8913b4c45e3b7f68ceb9212a3672bf84f085d7efa6f261d7e42399de655fa523d772ab1c1977833438eff839b68adeb8fe5aa8e59d12c1d70c2ab4d524888f9758141a552238aa961345d98586a78b2ac3038c8db17f6df1d82d04959c242a3e53a402fd87da822dd33050d9629f63bc27f00a9d46cbadee3508dc65c0df4d1bc81f673be17aac5ae7f3f69fcf7a6b1cbbd3258a666c9886f229bc5e356436ac2d1f53b33a5edd19e1a77a12b2149b6a5adfc40ce4f4963a8f1a06ca726e4ac8dcb3631b1423719308baef7996d574b9bb675f8ffe769dba96276d992c218ea1f31ba038b6452bed51cdb97a78433976a53e90ae82249499dc21c8b280bd34f8521011e2f3bd49c88c90af6ec95104bf11178901157fdbc2f205c3f2f523575b57798ecb059e9c04d14156d2cb37bc8e01ad4d01ac1d8a3b2c1a85415be0a1c245d9caa40076146e69123ea7d79e8f66266677141acbb866f813be14adfd28d46f6c387185fe1ca5e7682b6e6349157ec34ac1d1c98c423c220dc47665532a35946c67453844da63cf704e5292f04b810d0e7fa57c3150759b17598d227e1b98cb744472c8235c725f62484f50516e8e3cabaf70e078e0e3a7116e076bb902491083e6e377440b879c0bcae990baaa3a8e9b75459ab5ce62d60fbe4f0a324270050f7aa5f71e5ba518faf8e7bece0338f44047bac43a5a464d1a5168f794f1a130f23dee9035b4aba6d81761a010944d8bc96679a812867312129fc418698487ba09bfe680bb002453bbef00fb05cb50134e0db7918dca367100aeea96655720ebaba10a03ab329a23cf9227874f3f68f4ff6aba63a1e31bf1048679a2ee2d3456d9682bd89129046a3bccda5e9b7e043c4b6e83a6dcf72fe40457fe3fef8d0acee37066ff15eeb9ca6f72fa59dcedd28085f02783709c00b619ac5cd22b0d57011c94a0878f8bb99e32889ee72cae1c797d2d4a885b32d1ce09b4c591d73bbbb7d4eaf5f2de94eaaa39d8ae46abd25c998d826cd3c2b24be42ae4a7c5ca9328b5da8d991067b46dd82b083afe37b7224d60d9c36c74db94ac15662c27062eb5ba2cb387020d7cd53d674b22fc4c48f1577cb2449b81886ba12eab4237ebdce8ccd34826707beddc50db68501788cedb56a75808aa6c7d4aa406a8374eb417615dc633ffc336066aa7437b69436610335e33beefabb58b09e3235ebfbc7043637c7e9c473e3297abfb2ab388fc82c067d9291e973fa7b641530370b330aa26dfecf195301ece3360465b33ad7c72e2906eae61a109da3b01a12b370cadd8bc59bca75c47f9dfb74bc9e505f82a5a421bc28a3878487f40eb18237cb2c22e928498f304584a9aaa187372271de84eeff56f4941103ca0aaaef40b3b0a7a5967383152a13470687b76ed9bf10b3c7bf3070588acc254d0c076b61d7c5d09d43f049275e66ed27775e66a695dabc5ec9a81efa1cfca62413e7c2715246a49e59a1975a1e8c5f581c16953b3238e7100df6d281fbdd12471022d211e9aa0a04c8c5e70bd1f826f3e21f03aec6849a2bd4278dd034fcab56000f1522b39c1bb9086f00b8c3ca230210495fa2eec66b9e4f1605d6dc58ca2464454e404b80261081908b90d9356638dd7b9240375955d9408ad152408cb84c9b3a4f803d4112f330f636ba8078fe23dbdf44f578540434812e91782f9c476a732cc501d8e7f8a273d121de7c3aa317a277c651fd752cf71d02e2fca19761aa849e2ee2d0aac369adbafb47aa9c60d463225df053213140ae24ab4616518ba9cbabcbe2826a8c47881114d6fc61bd001c4f9eae70bbbabcd40b7f46bf03e9247316e981e48219d24777d9e0dd124bf616f6934f8f03ec89abc05987b272f245882d0eb2da402dac09a7b9efa1ce83b590025507e87eb8a4530c77b478ce8b57332df3621a3363ff40d176d60230a289da7fc40d10b6f39be7dab90796d50bf1cd522021b7c8dad848ad2d32698805a7aaa0b7da3a07ce883c27a90f052b3f5c923c0b21051870d5512241f7bf97c74b83b88c648b7a93c2e18c0553ab6054b7d6652060af7808738a79ce157b6cf189d872c3985c4c25402b164ac64cfcec5e751adb3272894740a4a28c7f5c50e676720a3bb3330c596d1b51b40973744fab0f4066a2ef475f092e495adc50e181438b163624430e3289fa7e53bd79e8aedfd1a52141a59a4c51992a031afad71f74321b61e02102daf44c12787fb487e28f020045c2554b70eafaef11bd3b4473da7fa1171d61a148611b91e857db371a6021e02e5082465d45da6c5799563395c7cccc8dc061dc80d09f2a3834dc88ef7e61b45452aa2073ef7f495b56e50e1e7313a17ed454432a9ce4cae176b67b553badf02372fccd7a69af10c16f409533a7e7a7538d1e0604e93e978dbfbebecdfa78d812e11b390a2a02210f434d15b4a58cf4ef045d66d8c411af62d8578f68208aa70b827f8a69a1b792983f900cc2533a01089fd28ea6b83679cbff1fa567930b411b129c86a45349ea27d2850596c0bd0b9153caa96182ae15c2ec6985782b68cc0f12f2d147d2245c42323ec127108569230a4a6a796cc78f730d86bae5ba49997f111467f3da1fc7da088cf349a40e0d69d5d65df21492d82259acd9ca6f97079f7094cf842aa652186162248fc9f05e452c75f78f79f34b0ceda9d1b5bffbae06b08ace101deb3f05e5fbe700a98c259e1527e01be26cbb7aa3f2e7302489f67210225b03b9a82a5ff486478d3e248d9b0ef0c12e8c2a4a94df156b02e7175dcba0fdd5a9c960a8e915edb6bdd2596529c88f4a10ec7be746be2c056b7d9030aa31050256ea76a82ab8c18d53ba8848d8dbdf070cbab935ae371fc200aa8f858762f072ea8b58db1ee4ba00bf879153fdc81ab8fc745472a1ce17139221ab8ba3f24fae60f84f8815319eaeee9edc8dd43285aeaaca0dfa81d95923810e891d50e1f05570e981b9dbe1758bce636d067ed5d29c5c56c133e83e1545014bea6c55612c41bc021267dcc97203ebbae4be62e5f4f05c579ac4e0b550520668fb26a3e21bca88d9323106c35aabedffb98e83679d39c15bc618ca10e2b7c593b2b6e940bb54d775929f73d8e1d674564291b82a8292adef3495560185db0fb6ce8d479203547fe0a5d369e6253126731a156f003a388674cf6f1f1ffd04416edd62df101bf6fd3ac11e48a7bdee8c49d2775abcd563f4259e2bf92002ee822b6436a2e2c95cfbeb3a90669e505da14754dcff65e62d41f84657e33f15e8c3bf939faec2170671f1e6291e9c234edca69495daea06624af464327803b6369a6c536dd9e1faa338562348d3b8183999edfef72f3cc469dc65912ec86b31587856cddd7a60703129f723525803622560a1ca5491c1cab508b55b80caa329d932834aed32324943bd0827b144b4480c7403b30850fae68fd05be4bcfb4b2ce08d74afd147b2b5eb2b56bcd1fa9ad1657d3a6f3f5d0ad5a2a88d9ea287fde5b14f393355c7c218d23792a7020955fca0672dfd551994178df882d67d9b8833cc2763f390c572b2c2bcbcf6f73a56e126464cf60fe45c6b9b04474f05aee1b9e1573e12bad042deb273bacc444a207e11e8e4c047699014d99cc8c45be5db22815e9982bfe391d1968cfc83a1156a5f9211ba8e93d584d0e4a1de08fa3680546163b245bc8d20fb9ac25bcee5fc0f1b48589051ecb1856fd73f9979b1fbabf4dfb4858952d8d11114326a0fdf9729f2b4a305f5c5da2fd96789a25334ce9b29267314198d95e1569ece283d7b30452e9548c23b31c04019fbd1a7ec52097248c683ddaa69f800145cc51b9a45465d0d480a6914e57fc276596e67fa7a986507ffa4275e6c4d50970302cd091a4a8be2125afdb79384433025caefacfa08235f3f8863cd727d920d0aabc78030e70badd682205e4460eb96e24a8773c81fccd810548c7e2ea99292c5096aee3e1c3c96f0105b5e953e61fd2a139c311e53958af1e82411de02b18196bbb223f4f1f3c526ed3bda944ce929e99b8bddb999bd4d4a055a647b35a124bfe368aff68530d057103fc14b6343c9f6574971ebe03ba3a60c6cbc115c41095420da866b399218277a6a497dffd4f565ae24a2e961dada56b3fa30e4de600d30b82e9bce89cf1b8a67b9f9df4e19e98a203ad8ee0603c9b4d04ef96fea02ec5a3e0869195ac1fecf1aa7456f12a00fe30de4ca88255a5798292f8fd1ed12bd16d8770a1e938acd64621d25b319a09778ea95d5d62fa1087366893b689bc0a48b705c9c8e3c656a8cbad9b13ee4c32906f11e2e985127f5e6ee9298f8a5e1559fa1080bb2251b3433df3b369ff51198d29becad63a2662348404cae1dcf325e207fdeada5171927e9fb74abbb31fbf6f71b6ef4db87176bcf88895653a8528dbde3a3b7081f6e02199d067917d6d80c5cdfece94d3f8c8b39aaaa23e6c371173c2843e76b27011348dc6d9b1387a5ed4ddd05234fd7634c4d29c7a1aaf0c0892efbb8d90bdcb2a75ddd1610c1fb997136b361a72fa06e7dd10e0ff9deea60cf890ef3654011ec6bc245ea07272f1c76cf7da601bd9468ae7221b4c880ad5292921ae1e99b829ea974691ecab3aefc1320aebd275709b159a724c601749c52e1ccf6cfda239095cad645145801c9b4f9c2f9bf3dc5098602ba08f4c17add030395a4d37d68664d28214cb83addb4a361a0979108a8c12cf4f1024985554fb2dc77d514c86fdbdcfc0e136d2a050cd8ae5b7cb34e25f64080b100c7e75fa3c052900b6cf63b8be429867a37d8e13db462bd9a96a713bec5e8ad3c35722375b0db5b4daf2f9fb4f63cd4e8684b42582dc4df2b398e3ec51fc454c7647e4cdfe0061699e4d745a79b019b3b890652b297394d4783f44993c466ab44102f450450758052669d8a9b1b0e6e8185906a9168a75babaa95e15deaebf931c5361f21c180370c3effb062108883082b200a9eea74b5208949535ea97f57ed7fd69ab26167ab4df02686727474d80602348bfe16485e5d4999feb423380a52af2f101ea01e756031c45652577ab522390a7e364d6bf0868b58d4b5ab8b4507daa22b7c0068b7ca0af27f9610f9be95b1e8cfaf17225d5cdf6f7d4c5eead3942e9bf83ee", - "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c000000000000000000000000000000005fe27b65c562e50b0f036ea754579e4b000000000000000000000000000000004d71b2b07473783912b25cf8dd9b9c9f0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000210ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c99000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } + "proof": 169980, + "public_inputs": 18456, + "total": 188436 } }, + "integration_summary": {"integration_test":"test_trbfv_actor","benchmark_config":{"mode":"insecure","bfv_preset_subdir":"insecure-512","bfv_preset":"InsecureThreshold512","lambda":2,"proof_aggregation_enabled":true,"multithread_concurrent_jobs":13,"committee_h":2,"committee_n":3,"committee_t":1,"nodes_spawned":7,"network_model":"in_process_bus","testmode_harness":true},"proof_aggregation_enabled":true,"dkg_fold_attestation_verifier":"0x7969c5eD335650692Bc04293B07F5BF2e7A673C0","multithread":{"rayon_threads":13,"max_simultaneous_rayon_tasks":13,"cores_available":14},"operation_timings":[{"name":"CalculateDecryptionKey","avg_seconds":0.004105569,"runs":3,"total_seconds":0.012316708},{"name":"CalculateDecryptionShare","avg_seconds":0.021735208,"runs":3,"total_seconds":0.065205626},{"name":"CalculateThresholdDecryption","avg_seconds":0.021883708,"runs":1,"total_seconds":0.021883708},{"name":"GenEsiSss","avg_seconds":0.006303152,"runs":3,"total_seconds":0.018909457},{"name":"GenPkShareAndSkSss","avg_seconds":0.011035416,"runs":3,"total_seconds":0.033106250},{"name":"NodeDkgFold/c2ab_fold","avg_seconds":19.281920111,"runs":3,"total_seconds":57.845760334},{"name":"NodeDkgFold/c3a_fold","avg_seconds":72.091054403,"runs":3,"total_seconds":216.273163209},{"name":"NodeDkgFold/c3ab_fold","avg_seconds":7.793962458,"runs":3,"total_seconds":23.381887375},{"name":"NodeDkgFold/c3b_fold","avg_seconds":72.635186750,"runs":3,"total_seconds":217.905560250},{"name":"NodeDkgFold/c4ab_fold","avg_seconds":8.064746388,"runs":3,"total_seconds":24.194239166},{"name":"NodeDkgFold/node_fold","avg_seconds":18.460723180,"runs":3,"total_seconds":55.382169542},{"name":"ZkDecryptedSharesAggregation","avg_seconds":1.575791792,"runs":1,"total_seconds":1.575791792},{"name":"ZkDecryptionAggregation","avg_seconds":48.474341959,"runs":1,"total_seconds":48.474341959},{"name":"ZkDkgAggregation","avg_seconds":5.560166834,"runs":1,"total_seconds":5.560166834},{"name":"ZkDkgShareDecryption","avg_seconds":0.766792666,"runs":6,"total_seconds":4.600756000},{"name":"ZkNodeDkgFold","avg_seconds":107.170507639,"runs":3,"total_seconds":321.511522917},{"name":"ZkNodesFoldStep","avg_seconds":5.213900541,"runs":2,"total_seconds":10.427801083},{"name":"ZkPkAggregation","avg_seconds":0.397447291,"runs":1,"total_seconds":0.397447291},{"name":"ZkPkBfv","avg_seconds":0.221726250,"runs":3,"total_seconds":0.665178752},{"name":"ZkPkGeneration","avg_seconds":2.248425542,"runs":3,"total_seconds":6.745276626},{"name":"ZkShareComputation","avg_seconds":2.503326757,"runs":6,"total_seconds":15.019960542},{"name":"ZkShareEncryption","avg_seconds":3.921781749,"runs":24,"total_seconds":94.122761998},{"name":"ZkThresholdShareDecryption","avg_seconds":3.427196402,"runs":3,"total_seconds":10.281589208},{"name":"ZkVerifyShareDecryptionProofs","avg_seconds":0.154358833,"runs":3,"total_seconds":0.463076501},{"name":"ZkVerifyShareProofs","avg_seconds":0.253084125,"runs":5,"total_seconds":1.265420625}],"operation_timings_total_seconds":1116.245293753,"operation_timings_metric":"tracked_job_wall","phase_timings":[{"label":"Starting trbfv actor test","seconds":0E-9,"metric":"wall_clock"},{"label":"Setup completed","seconds":0.968119167,"metric":"wall_clock"},{"label":"Committee Setup Completed","seconds":7.026030458,"metric":"wall_clock"},{"label":"Committee Finalization Complete","seconds":0.005051750,"metric":"wall_clock"},{"label":"Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)","seconds":122.805809000,"metric":"wall_clock"},{"label":"ThresholdShares -> PublicKeyAggregated","seconds":135.105291709,"metric":"wall_clock"},{"label":"E3Request -> PublicKeyAggregated","seconds":135.613361792,"metric":"wall_clock"},{"label":"Application CT Gen","seconds":0.009316167,"metric":"wall_clock"},{"label":"Running FHE Application","seconds":0.000052625,"metric":"wall_clock"},{"label":"Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)","seconds":50.063420000,"metric":"wall_clock"},{"label":"Ciphertext published -> PlaintextAggregated","seconds":53.769554292,"metric":"wall_clock"},{"label":"Entire Test","seconds":197.387759916,"metric":"wall_clock"}],"folded_artifacts":{"dkg_aggregator":{"proof_hex":"0x0000000000000000000000000000000000000000000000050171e1c76882125000000000000000000000000000000000000000000000000cfdf1f1b488062f1e00000000000000000000000000000000000000000000000f962e434261b37a730000000000000000000000000000000000000000000000000002e0e72e3a7169000000000000000000000000000000000000000000000003632118af1fd3861600000000000000000000000000000000000000000000000f3be15fa21507e979000000000000000000000000000000000000000000000006da62c16a519156a00000000000000000000000000000000000000000000000000000ae34beccc39c00000000000000000000000000000000000000000000000c2d6c29afc67b101c000000000000000000000000000000000000000000000009cb8711b402b7afca00000000000000000000000000000000000000000000000433d081100331cf9900000000000000000000000000000000000000000000000000019240d6a5f208000000000000000000000000000000000000000000000007b680e3643ee08d4d00000000000000000000000000000000000000000000000db2f02967a31b6d1800000000000000000000000000000000000000000000000d8224e1aaf3cd44a90000000000000000000000000000000000000000000000000001e3e986df6e472a988fa1b94e96b9bcc842e1ec09ad2835ec6539b20a216d94832710f34e12a11bbedba09154d4bdb6ca8a864ed19ed0dab77199001fae75d996691767ea956b04a0389bce5a23d5fd869aaf9c5e5c443b43b84c5b41d4b2a0d90188989c511a145d2197e8a1f835404ae133ba729ff0f9e5db0e78f86e967e89a28eecd299702170e094855e18faf9b08036a4ab8cc8451b9e96d4a3e4ddb294ec58068c86cb28b5a272fe283333c466d2b063e406c9b5d5898942d5c60fcbf13a28f333c0172e75ee97db99d23fccf0100b7e768b832f63913b02f762a179772a656dd7f3eb102bf5c1f9a9bd5ca2c2ee9241a4d4088f679221c0288326ed6fb9262962ed1b10bae9d0f25b5935e7684a6e3749e9cab8e2c12d53e6d1d284267887e58c05da28603176d9f1ea891e633934fa4fca7ffc9161f5a3838dd02afd160b0233cc2f1985db340cca8b06e4ce20fb357bdb4ee18bd32fd75c0c529e114987992e62c31533f35e6e095dc8e36fd57bb8046002ae0471ec3fcde36bef53e375cd0f3e4f191a2188d3e9a6fb82792a50d4ff1360640275046de2c21d4f4a3577e8f79a8519b47cd6be30649c380eb4d735707b1c664f98421938cd63d5f656c6eef8048b3001073f0fb231803649f60355fc757e41658a95c817594e1dafd8c2691d24f00bf99821e74780d315f5c5ad75d8e983e6d5085993e102017a72b2fa266960920a8e7e77a2ee6d59d798f12d92b424782833dbc7d235ec3e43373ad3e404f1cb1e08a2bd553428c3accdeb393846323c7c78adaa32f740afcc9ac4d264b3ed09297b45a3413e22cc62390354d759b264a96544e1662be66950fd42c67f2dc79c046b48d8eaf419dd29c1de1171719708091ab038efedbcab7ce18f60d73cf851144e9914268e22dbed233813cbb531e7cc338776a52b34c5b445336a93a82a3505ee10cb945134e955f56c92798fcfacec8ab4312b370d08ba9e13c6822f7b2b251218642289c021af15cc46ee027d7b415eec7ac6d8701d066c7ea7fbad0fff1f44ed8fbfd3209ca7c67443b852e7eb2153ead095fca5a334f74adb331a85071d37e4d8fef5c820bebfb6f8ef7cbbe9e595b09b923eaa754d813eecb8b431b6252e189fa9fd09540008f1a366d44aec26b5f3d6b88219b8acc0132af1175d1303948e2483093e739c7657de30ffc650be6016e8b7b644f1706af4f10794917723b79318a87138a13ddb9ee54f5a386fd236ec981a583a22c69f30ddd9d7684e2cdd842c10629c9b803f04e709db227ac8c2618b2ab90b7e272e60602fea839906c91883e1ba386f54311b5f8dc3e654a0d4ec89e0e84c28bc6de587d46fcda612aa42f202b2336dee7da1bb663559552831351bd8506a5e95299a7305b38f87141a1d53d730ea5f7e8327f36f8046b96f06be138f225d542397e91de2db853c118243d8072071c8c2b6c9b8319b2364cf2058d3ae62883cd328faed3808687d1e6bcd832417a660a93375eb3b6949753531fbcaf3e9dfda64319654db11377d0d30a54dc8104f72b9ada7db131094a3d563bda7a350f045ba02572b53152c9f0b81b3d85c069c07f10b478b5e43103026fe9054094913d3939a7dfede87684e2ccd8b577e3eef430358e620b504e70597c6fdef4fafcba52e4ecb198fdd7d7e2ded4feaa5e0f4e46f5928eb7cbef54804310bb28444bdd8db0c2aba73c31c7019870268b2c4ef8557b3adea63df71d1ab57662ef45b9340068707f834268fe72215eb567a317d10a1184f97b55c41dedcb2b3fde60bf5b36f8db7ae9a86679e033d6ab5ae65925449813af86b5ddc4e84247246cc5979716414f6543895abac01e65a1745a512cfa85259e0704601b4e96f4fa2acb1810d93f6f5f7c3c3facd28d37db2dda672619c9a74af9fc8590f1e019816aed3efd4f2431c42aa49707f2bc202af6e47cd30525b3176d9f656c8f38188e47b4010e170a5c9540e8d446907662106b2f16ebaa6d3b31f76676b63b88f6b5f201fc55b64fd485a05dc54e82ea332f1cf2a5e4a3ba0fb92db8a4e2582d696f0e3e9544f1df54d2a150928a21c64166a1eee5a7acf0ca354f1ef2c597a915abf5eb1f2f17f4444a14ab73d25291fd606842f6d46c423a3d5002ad5d1d85e8f2d5aa6facf93d277e8ada5be2d281e1d086b9900f04949511c28d3e5e5c042336a9c38d499e0d9d4a0e22a011c2c1d46ab3419b71c538300bf07222fac1ee50f30f59fd1606b7a733cb89d47c01f240b094462a58c6a48f2f22ea0c311cf71059da4b6eccec988af99298b19851a03b84a54289cd63995596220af919f2ace0b6855f018780539198fa2b546722a38ca2bcc9ef20fe97d16857bc21184cb8c26ca77dd0a48d21e63a4d2e309941336a5aaf3f8d884fb066e1be202f0a5824698aedc16b097163316f2e9637c3e0b20b792a3ce06ffaccc8c01feb75db6c1a8a5f691fd6f0457b21d6f96014d97181c7e28a5e38a313ba81781b44d944fa5180921b4e3a685c67e7b5ba54522b12067ea024995c2b4d39a4378e235bc9617cd45226b0b462acc8268376f09ded9148ae0c2c54cb0572c7ceb489276b6f9865480d1328e52c20b2a87bb25f8f8fe19c2f1f9253a2f9d91ce5f306a71365388975e901501ed2061722b40b39cc5e126be39f84c67f5d309093a230fd41635b221b3a842bffc6c82b439bb4f30c82a0e455c77499e96fca527260c2387b5b33a342fb731983cf4493ce8616a7a53c020b4cc0c3be0b632c8ec769378bb66387a1f5aef060a93837742564a44d13f722b3c33c50977596828429b4d9cfd84efdebb1716ad8865c2bb0b7a428dbb76a510b3144751ed6f56f3e4a1725894ae0491db526f33ff61610340d0ae06c3c2090a090850b2deca290112c8c9ee587277a28c6783c18de6edb089175f09c0cba60ceb6596411449d0e45ac2e45a96fbccd16876400fe6be3abe02546874f1bb2c02ee37e4891c999df82ab2e71bdc4b8565e904d46de6572a8e13bbd57bbc7666076ab48a848eb008f5d150b8f34e2950e07418dcd2ae4d4618bbc20d3ef16d280e138a7bdbc01702cb05e90d7216c66cb9f4ddb7036ba9a8e490c2d6706f6ac61e64503d935535e808a69eaf53e3c6529734aaf10bf83f868f942f8532031fea1b8462e093707d67a47944a349411088c6642cd6a7686fef5a7e239b0697054c11236b5d3764b83f9a409821ce9b4b87bedd5ceb3f4fe6afe7a7c894738d1c35296c66c8d85376b5a864281a54897b64e90cc5bbf2778ab3edf83387c80734661b77c4e4eebdbefd15d57a22abfa5662ad616b857f09acc5f7c03503dd36f569035c3c9ff43a306932b0c6921ec3ab08210793ff101a1cdb4d52ada493df83561c674eaca29b3732bfeb35648633817b65654639049f14ed8eab71d7cadc6a472d72dedc4c511dfe6eec2d6f780d3cda952417d70927de7c890c822180b751cb22efb494f2c65804b31df2d6fc8b2e02b1c3da3f32183ebcab8662f9dec0b9db27970150805f57492628d4f2e5cefeca33c80f49d769038ecea2193dcf848bf626721a1fc9537290fccd8957f41fea37a04af789d5a699ec186f0c5195b9da3a0d289910128a71cc047bb54a1a2348c809d62257a294655ff515866421c786c31b60373c7229263449b97139a1e73d1632c5c655a5298e01e0d93090bd458b562571a3466918118d55c7653f72fabdbd090983f3d374b657938439592f27e63519b3836279b0887e21105c5b699c6402bf9926c8774566b8696178ca6e6019d60fa85a2daf85687adf80a426ac4b3280a35fa0a03fdf7caa03453744d3c95876267ae5a2ec7cd9bea56c9f4791aabb88c44f77aeb2be859b01c3e657343a1fbc0301584b569bb2677bfe761033251f642a36db5fe7a900eda00a899c6436b3552257ba5af5060156dc3cf16a744e6bb61f304c2e8b882dc5d920a2eae4e5d8930a12791bbc837f109d715e94b6f43c0ea0f912edfa65b296b79fd2fafb4eb80d294d411f94f57fa6561c81af4590e4f64e246346c585b9b1825e260618666d790d3976646b3eaed0b62adcf8ca1eaedaafa642b99b0c668fb2ca646cf83ac831284183eaf859b2dde29a5bc4ed0fe1ed9f3b3e4b66b5b1b1b8e2ccaceff284570e94b8e30962aa3f7834b8ba1ea36a8ae66af7c05c9f26ece5af36d3e62503790341dd82ae3f277043cdf576765127e8b1ef261938dad94d9253166b12e3012a098cd13cac7440a796ab7cdd143141d75646524728a119a9b8b7a6bad74992b229f1da3b792912490932d69dcda2f002679624dea63b05b8a626d29cf0a21e281008deaebe2011441e2251c4163f566316b754bd68de1e29d872314f14c98acf06c65072574039e59a4be896da9457287d943daa8124c8112cfd53d8416b5dbe2389f9b0e142bf22bb249b8a65aea8678c3f8e337d8d01cb053da0865c48b95c2a98cf96bf95776f89fe16e6e735b6ff6d77d65b19c713ad94b2d833e274b28a1d83ecb08d14c57a21c6fc084500a03f20d2f2f4e113c6234631c4a4c862c8452d8619e2fb00d51f4660d7eebe5d0b485331281e6e4fecab05ee5b39fd5a576007a02effe3276eb44bc256394bb45df037d31b8a03d4dbff274b7d4dff96796329900a5f0ddf1afc22b52b45204173e66c015f00c263df12c81244e6aa531df60424de20721c938a170a8ecae4ca005937a20beb47b21d5114dc6acf93ea1612242dc85ca47576a18571f7ac8619b4ed0fab62fbc14c988ea251c175ecbaba5a2120eaef75b4a23de5516c4409c15984f80e7a2754be08f8d8a586921d36da642bde79fe59910f9c9dd77ea3043601e017b911b2bf632d7638bfa2a0df8dc4a4158571fa1f23328c3780dbed7d136816beccfc88d346a328a9b5bfbeef4bc0ce04edc95d456661d0eb8b84b5f49bd166423dfe4e44d292b5c221b1a9249bcb09094fc663b9b1a33ac12f371616bc82907844262a4257f3b0f30494ec53318e4208e1927d77cae51515142b0379df332b1a69430dc6b1faac64d7d5c4ea9b87a71af3ad9c2c137e8f0720aa216af2f0869467dbaab2593db8e98a43a77e2c688e0f4ee2b6e37d294f473cd9933f3ddf4a6ed9b6c32bbc46c95db64abdc2c665b60f30f0494c32e794f78d06cc07204763c577e6ea2807cd9129ef13c0c63d564026df11741e1c38e336332e811beaf01a8336ce345ac7558d23ced7c63d4f7a6109116d2f26b10687f2fec3bdc80ab96f9d6cd940dbba2096f69f4cc07cf9b05007073bfce2438fdc73e5d2187e676f286fbee1c9ce169d1ca1bcc3a71d5b515a2cea999f3f4b8b2000e1944945a0ec5719f2ff71908c8903f2ab1ebf811139bc1ace82e5ed82e865146a52e18acc699d0583a4b0b8469387b04045acffcc9b8a1faaac1d47dbf656c92156fa8b864b34d75e6ef4e7dc75b031b2a6f48e9eaa2d2fb3c68e3adbb2caaf732d6f6ea726b8904a855196a864e5a2f835935b51efd00bcf1ff872cb1b4135fcdbd5d1e96a7a58df82a1a2ecfcbf69f5c0a9c093333417d3dd49754668e48b033d2dec98fa0a2adcffa47985e039acc5e49d12377a9f0271e8ebd87fb374d9f854def3b254c1495cd5722b58cb04b6da4484293adc012b3ba3498c119faaebc4d3d3e7b54bc4ed8b68415797a813ae76c4fc43a7818008ad9f53cb63132d925fc1f285b75966339371c9447b2c45f9610fab11b15598273da77731e94ebda44ee2fb236383a0a0deeaaa0ed802dad3b9cbf991474c9f012afcdb34fa6eddc42fb1d2599c2b38fc70c4baabf6d787bdea3ff8bc2cf9631517c0ddbdb7ee2e008622cbeddf715fdceff1bd1aa94a5a280b1308b9751304250c62c27c3989eac079c11f437c3414111356ea1d7987befc81438ae97b6b632e61faec19757d01bb5c31c78b0c90d26a3b71709ea3626198c5562241b226cb1157ee972eb53a12fb593b473df72aa843e1450832cfc721fd2fd7f037c1b6d4263a464d40a4302aa2495b9d9be79915f656fc201bfb43f1e6c11fe7acbaccf803259bcebde2dcc3056bcc63c53d6b292095447edfc39d783edaad8a5e798f1728c64ab0b1c0489089ea5b8ebc7b53209ca084d722795ba667a77ce7f6b45aaa17c68ebda1440c7545e684bbf9e648ce2fb4c2429968a2204695e3e28b1b6ae90b2837fddfb5e70cf62e75c6a0b446125f793cbfd4bdf28d9f6b99da1e276ec12f63b8210c9faaeaabff24bff05d89539e3d6753a5d63ac9c8d6a05482bfb13e0fc8f6a95809478289e225f918f6baf43748868b25d45f846e604fef59e5d00b109fbc8e63307141368905dc9d3d0d0cb3028d7f778215822a3fe943c1f746711fbd74bfe4b4189f88173b2223c3c0266b82b6ecdaba2542723592c530aaf2301a76a882bd71dff78c2d22603790c9650b2e1e1170d05125af5d0a319d745b2e149f60779eca2908fab92f744af749856fe553d3c6a29651aa82d2f1dc8743a8171861bca3e373e295d7ad740a458d2e648c1d0172b1fc6466fc2e6a67abb97712a837b4085cd6a5c5447ba344c977d514eec63dae387e57bbea863222aeae2f17c9f83f0915c8437b28107dd00705f2dcccbc6b5b86c6cf65e7b67229bf72ae1ab5db1316dd37ddc470c48ee9c01f73f4eb0a5a661939aababee0eb10cceb7f259142020f2f2c2cfdcf7e1a73a9788ed61dfc804d1be7e5d2a6c4697a5b1d8a0c647fe72135aebf86f18b0db90bb6bd0ccc896829725c28651d7e1307fcfcee2f4cf4809ab83585d0bdfcc0b7f11245df7eb373b7639e41cd6947e49dc05d1d24e93ae6b006bede35d521db286ea335822967251ca8b1e75fe98c6d323a52810912269918429ae971037503f97fc1930fbba65055167a1142c4029bbd13815d298a459d0d17f83607b8e553b645b928e12a5ba47c3a29411d4660bfd27b522d2238834c52fd7d29853a9e34abfb12528f33fb3d27618e6da73288e1a0ae3b9c011810f73a0e7f5e4a53700d0486e2c7b89210ee348db7ef440502b39a6cf72e127e0a7f12d0b42ebd927e5f3c91f306c2755a4d4870e0fd4145c4a868afae772138c4188bcc47eabb5c045ad1a6d677212baae9ef7ead5989fa664cf1afd35e2a0f79fecdbe7b8023c60ae6f6daea7891ca68e8e995afca7c1ef6a39f24711e02416e6b298dc891eb5a6f85afdd0a44d8a071b576fa14236debe858125378cf160831e632c434b386866c9f6ee7c589a9b181956360d998d1e2ee3cf4d79e832ea36e916003c90f97ff0487542b33d0332cf34ae74a654da9e4e5a40e8e9bdf1651b3d3197f8097eee61ed1d6425eb1975712095712a5c7038285ee4fd16be228d77c66915e9524b9b0cdcfaf9ecd26b4b3f10a4e425f44480cebd3003b70290bbc5398f1229c4a19810868a35504068ac01326812b8a0e9f665d9195d64bd42397b246030c014d748e4be99065f8ea3c72c983aab168cbb76a70e6a8760bda15d4d22844d77f4323526f30c54d604c493f223f4a341675b2696e4ed812bbd81516245b2e5c3879275d6e7a6cdbc6b978064be19dbbb1f656d4c803aab83786302a6b5a5a43a22f99887ea0a812fa8b51aa8637e5df1d7ed5cd318fc5d00766082bcc1def74470c7a872302bed39e8e051ebe2ff94c45217cf79b2a4615a41c126eae2b56037c4399d124d085ebb06d53917a7bd73c1413756a8a78125a64c4227444263469b7b5edb028c7b98d313831c93cbff689080d1bdb6f166644284b25e9704af7c3ad31b34253207d2064f36eb67cefe487b6fae26969b8289ca5290953c82bcd3454e8ba7bde204b4f5be3e8b5afeb15bd8e20986fcccb93d08e8825e988859679b51fa0f938c7476f55dc3929998d1761c7aa25e390caf801f8ff0fe2d77cd8755a04a4671dfb8d0ae1d2e917a66802e786425e13cd695a631705284bd012acd166ef99c75099b6f603dfde93e2623cf6e47753c76e2f3d8ce507298f3e71c7340938679cbfe5e5bc22a969f08c3372c9c084c2636a1cd76fb2e906095782c9c1a9643c968d0b146233a57ad730d77332c10c8167cb180dd3512c24a02e872ca9f98fbba84d23141cf5d66207f879a928bfcd22e5692396ddc80c2b9b1b8b50b8de8cece0a17d3c8ca30c36e9cdf045e4924494d6c99b29e929bc2d117ff452edfd85f7c4adcd9cbbc8a3ff76011351aecd157070ff978a6048dc08412b512073bb2152f681f316f1f0625fba865a9acdb19f3992e9fdca4189d520b9f5aa6e222057b464a80a4d04b2fc7b9f92a5a8667eab1faa27945e0081d61fdd29f1a7d5444f74f09a2f30044d16ef1bf6531a0ed6d1151cd35a1b6283c222185f0aff47c7e7a37a6fa0846c983103871dd1870824b8d18f2163da9bf2a70038b0facf58a67165abd01d21cf2429ec7153fac53e2b6e335142fd2cb3aaa02423e67047c73fc811b4ad3c8b452fe327d594d9e7e1d51417edef03990949db1f7e274080f76644ec70b2b6c05267ddb2d6c806e0966303c77105a1ff0aeba72558dac392c66ef60efd29a6357cc644348b8b9ce3c39243e41d3a107355ca050109fab6c07380c8ca191e908c144271b2b55a8490d28296b0bdaa34911268801aba316c2967dac2ada95da9e41c72427c498ea387de3d234e5d728959fcddec1d48b05c86337c38dc83ee23caa8079d5f809ab2d1f30dbfeaed4ea7e4b87fec0424d66e7ef425245355ba9994876e17000b875b53053eaf8f38e6937aa4f0ea2e8d25d8a5e2087be8f9392bd56e9d95520efbfecbe8d312e374bd8fb10a6dba08de8a096af917c4affc0b27e093ae6d1ed63b70b0b88dae467bcac39f7fc88c1a08ba9b1d4db0dc16e2df05e265019349f8c250b2966754bd3aee8abfc280bf03c7dcb8d5c003eb7afa191842ddffbbb7e624da7f397fe89f90b12d349826d807a2e3f357a0912d5af5b2273b32ec9974f43f163f2aff433cd805f30e26edf12f3a6d67ead33ad272e4908cf00568cfbc7ca9b12e9b15631814e547d6569d910866261e817e204b0410ba0fa7511d7878dbddd4e456b5aed444d8f730b5ced605209c97a9c9b775e9679c3664e2dd37ef7618fdac726bb36ac97ec093ce3a85241b49b290fee4fd53ecc38866dda42ad9e89d81512cd5482f6feba6b84d099f1e0d9d2544c2462149b6304394161e678132031158b1bd24066fd2e943adcb202d4136b5fce7facbab01cbdc9352aa2e773c8a40fa8fb735facfd70c685cb4941818959346ef51c68ebff31f6886fff418c58b64d22b17c70ede38ee5048c06e1c47d7159575e4b31acdf5e1132543dc1a394dde58683bf6839e222d0da5303e1eaf022ed8ff621c383856539f24839aa597a53329b6153c1c663d94558289991e0efd67c8971dfeeb6f36e712e835ca6d6b12cb8deb7a39e5686d0b7105d0f00aff977aaf69f9d045f19a01d2aeaa20d181dcf04f46f5557e34205686f4ef090aa0dc2f18d59f049b313b135c52f2a6276928cc0f11ab4948bb463b12ea9e3e2aacb661846247a5c3e3d349e822594b61dc48cdd93e68f559cf6d834acc90e728dd3288e94b99740ce069be51320defa30e03fb5799a33d7440673bb536d34817b1ded0cd3003019ab911bdf5d0384d48152312612aad122f8975d4b358bd2900dfb7e65ca31b2f7be187ef465777c278f670ddbd71deca7d5598a7b734913a13762531d2b2add16d5e37c92e7a1544011be58bca9f05750b4d86c9fd2abac413244404d2e8247dfab02c91ce8f4e6e0c9731cc82cded1c6527a844df0d6da324a192aeebcdd9f6bbe1db18a50813421271ed0678a8595c0bff9393ff84db4702f02eca84f25ca461eb06c310e1ecb75863860e47be4117884f075626c716af125b03ca92208379f81dcc34e4f41a414ab8b5edde232f8fc280ab049fd082fb2a8973bbc3e8fa46937704993202d184e17f80c74d3d66fdf28510fb1b1916ed1bc7414792af8f0bb1c5029dc468e3931fdcba416def99099cb00e85e695b28903636b366320015aeda121084dfb493171d0f84cc3708bb15a827b9f4f8af6782cf047a876096716594c6042e2c62770c37c86a6992e26561b4937be8deddf762235bd98c8a4abe96acd8f44943988932da6622c996564e8e4bd6d86044becb1005c7014222588fced532f040d85f21b694a4e940b7292545c9d7cc033b6ad4c1508dc7da02701d8d5c819deef613ac4d2f6170cab35ebbde63859a3f1a4397e24c51253418723f2a37e50d1cec94e0a1ea1e3f4b9ab19bcbb1fe320081e89f122d5592111cd83b86ca5d74db8aa45644280938af94f30c246de5a9e42a4e7c806aa4f6bbc0b40b66650fae09f068980329ee6ded77e255033c84f9fbe734bcd2bc175d335b3549a3567f0a5a242cee45c1d37f0dc7c0e091404b766ca4e37d40a3520a2538997773fad1285b4da877cff9e302bf838ba0dcef08c346bba42cf17e1addce3b129357a52ca15e1847649deb1725b35a6f92cb599de7ae5bfe1312cbc1e5327770be0eff878e8f1bde2a21467e5fbecab7290a1ede10b9df07eaf0b04d69ffbdaa12b51d1fa9522f982c4d89239d47f4b56ffbb8fd630b3e6636d257e22d3f31fd1f59eae4428b42fc9ccfac6cec11aff3ea7d88d37f45b013c340faf832ca6f3044dc026011db9172ebd8a50ab81f86db195239097ad5226b5fb07ae137250b94a651e40711a345ac56fdd076f56f9d2edad70356c1647853a562df655a338313805345bdc388451870364269856156ba27dbf9f013a86580a58275c3a0c96db3c6bd69e69c6627e8b37c77000cae86f388c855d88138a1d540510b7590554caf3b3ee1c4de0004826ded89c3c2d886255eb6c352df92ef402d404b008751a6219cea7831bbe590fb7484973247e7eed62a41fda7fe1b4c517852f9c46a3caa152a6ba19ed81d68060ab7de2ce648f2e959149627345df0af88013a778e50256572cd0f0db53e6bfbd0b265226056157d842adf904d66f68f5e82ffaf7d267bc206cf126453fbf97aadc413e8bfd0980f6d2e51fd12c6b8c450d22a7632ff78cda0c94ec01807bba33e809a36bf6d5c3e15a65d0380bfb5738f20fe99bcc5c24df1f7dfaaed12790f48d695d10fc94448aaa6483cfc44c668d2823977f80ca02bb04aa050e297c39a336ba8ab7392f3f0ea13924ba2e4cfe4c5320f0a6ad82e7eccc5de9b85d68ae340c4d1340b64fc691e2f6d976db379468c80f1a2f8ca7bd84540963fadc8241efac5f7808f44d7f7b65c84a9e597b4a8f820a8643ddc0b3bdc9b3ad0bb1c3af39bd93187e37b6adfc8acb7985898f3f7f08076f5a84e1f44007572f1cab6721c2d2e5ba74f0237b384b3d2f801cb2adacd71e00f0c0d1e7c25ef230bb81a52cfa718ab44ecaf68ae3cb224ccb24b78ab3f60e445b67fc38fb2b395346370197aaaac7517d2b2aeef97769479d46358d8b5f0737c3304ef4cb623a9edf6f53b433d4ba88f2a71de5a9560c0494de2cdb2be50b0b228b1051a2708fdc673fa6df41fbea855fac8594d675b7782b86d3fbe2d010a001a81c82e8de37b026d989c382b2a463ae5855553d2a2fd4fc239307dc2006cffd98ea7ea19c1ab6f29976568c0180742ceb1389f2b787525d75964aaacc03b7945f1be91dbe8b9671553c5390fc4e6b504216f535c8898e54e8343676c61faa9650f3b1ac01af6629a87cf78d157ebf2576dfd4035a5c94876d5c46051919c6574b57939fd6ae2fd2128fbcccaa43675804486b48088d076b167a6932c10094d9cd0a0d704ce50bf44c160e3a4dd947e18398f8951353bd2f7d10901fcc1e467e5ed14b5ff29adf1db4fa4c1ff120a9b6e96b2d96267b24de93e5b58a730355b647a71f8c66bcd9f005eae5f2621d4e95a0e8f0040dea08c5dabb08af7e06e3e7e082a4cd093c840486db4b508ee370979ec8e7556050b81517a42b7f5428e3e929a0b36862db159a17b53ed64e3b19824f29a4690b403e1a06aeccbfe523887a99b8bb389be92479bf4a88bad4e9fa0765e38cabe9b4cb0f8359ac291513e1ab0cbe99a58ba6fb01277bb092f76bf72ff69b056c808302a73c303dc03422672236fc9f0e0e3584834fb3e666af49172fccf5e62e37a5d8ef3c30eb7598053a03524e50e3629e114de48ff812d3ac27f69fab79374e24008af2c22ab922189f58e73e3e2d433cb8691dc28d394416c53adad6433b24c756158e5183a4c72b6217027bb06d3abac3724ff8f65085c9c274f4361f4ffa696c196a5ce5c06d015a4869aa4894f7f23c2c9b723dc88b32d23c7f7b17fe0d960e75d43247e3122149af32b83259e273124e2b7fbba33da026be409cd308e87b99fbd4dc4e3b1e2f82b41ef4d94c4833b737775282fd5879f57b19f814322fe572a1e83eff8e7c211aedfc9ad3826d4fd63e00ad3f6f5d7846c028f58bd97fcf048a65858a6f8d29d245380da910de6a206c761b8f6d9adff7ab770385fb81143e96c8b1b1b50d3038cb42e6627becb2b3f0e88797ec28531752945b90c789487c5d82b46de770143ddef2bd48fd0e0b784ce88b32b93672ff466514e73d0058366d015eec42d82ac2416739bc1d07425ff2cc7b40ca139ac01509eba5b9202e7e721a4e4d372e1e98d84308869f428f96548f633864a57b7eba50b38e021a6226e28072096f713051f0b0f6ccf473d4b76cd400ec3d2fde6d77af2fdbd7e813730995deb9066629002d655f6405da3e09e52f70fde13e5a8002f9984148df1c0ff041ce4a51150e7a76c3cd5eade0672438a5ea1d1dd22bf7a77b23ef9faf91d032eb18c6ccc507582531d1d7879ab921faf19cb135501352150dcaefcd82dc1ffef26d41ef2228297b04cc49e099ea7290257eb1683b9bdcd3bd34921f0ddc415d4e79498d580f340704eeb78eb63816c3bbcf6482e4c2ffeeb356cf808367622288839785f02da91875ebd91f8271b60ced8088c8c10e1591c64dc26baea11805b46580dd9f10a9102266062bee1e3e475b80079c900faf306e1eaf8f1aaf4484f0000ea75d17a0b8d9ac1d396615d1aca3af0b0a9f6a3d86f798679c129e6022522ac7785f06b97e54dda22274b7f6b28c57df7695ccba1d1edb1ae386e8167bd352b49b54168f0b01c77ef1e91baa5223e002ad97d1a77aa9c249dddda1aa025b72ed49a10ecd92d4b1ec8011ae096e6eef733c7e305304d9a68d74a7d8abbfbd3d41ab9d05d1fdf5080883cafe6fbbcc97a843626a9541efce71c8bb4a6b50323193a2002562b7a415d4de5baa9d5c72068d1442d7498990f218fc03b5ca506e154ef325120dab908552da646fc5d6c2d2978fb3cd67bbccc28980114d084481383b60ac18d9cf5316730c0a9d02e46596426e88c854b9898b7cf798420776e779e9c51a084aa19f2c753f3de4ac67e558a6427a04705884c183295ec6c48b9b6ffa67a4258ba74b690d12381bd1a4a887e0b231ee84077fe2797b23ea41290dedfbe00a2446b17ad57771abe27f3e448bb01b17f69e74a063a253c91ffd93726a7644b12442d70b8753689a11eb6de126041730be57e8f71dfb56179d1507ae113d480827bbebcc7ace9d7ad5a46ef018734d393e98333e8b9fd0f77317ea5bb2d594722e3e43c556d5088a6b27ff4adfc0c1384a87676bb2aa30217d642bd6dd2add260d88f99572949c86c1fa4a1332bcd3728986c45ab37c9ff6db79b662323341b9013fd43f11c15eca886b4d13c8500dc1d8df937dfb49156262a412654347dcf80afc2b5ad6847a049569a52d91a93b047a0cd0836e6c165a3337adcee9620a1f19a5d392987cbf44ed846c39e36581056a5bbce8d26af5f81f9f2cb1bd58b17501e80853d15b8f735eae9ab20741f04b36654b4eb0e485b28bf7786d4ca494872c8abeae9a358850bc62b4e248201f315885a1b3007d4ab32ce52b3f4fec9968137edcec321b6f4a62112e4787b2bfbd7602cc6005b7eb482de4aac41f4f3403042c688454034386ee1aab7ef75896beaef9e6d178f650dc211a4ec50aac20e43008a659f19ff1b3b52ba2a53e0d258633e091137c025085850a13db466755fd1a387fb0b270186e001651fb51e422f31710dfce6f3a56e94cde2e9290d0cd3d1aae40949d1b7cd01599182d3a7dcdb3ae8cc005e2a14e1b39df73084f84db292aff9b4cd5373cb5a58def79c64f8f9b124ded447ca83e959ddc955e02f5786c1257a84c5697dda550ad7c7fa446840f9c52aa3673788a425a8f39898b64223b03433f14358f511051ebef163691391a110b6b9f7700ea415e2fdfaae627af710e8fed12c0e416b4c0b58b67b6de9c7aa4f5f22177786fedf9f06ce3a94d21f5221bd8961a7e292e9cf231f57117b134f0a0760a6748d626834b1e96296635c430371dbdd772bc5fd6a3a8cc16a23a23ad590243e746fee1506a882c081eeb2d1806ec3878562fd5539690873f380628c189aabae6ecef7a59a33f069aaed9dd117596a9f33de6768546b01bf20b4caf6713d148cbad539fee2b5d69c7299e5c172c53a7974407ed9212b8abdc2f9137fb7c459806fabccb825f75c3c08c0dae23d223d74d5b5890fb1e84340b3916a7cdd466379302100aa313e76ad493093d1ea729f88743430d4b9de0c070ac5e69875be9fb9302edc0b8d623750b727137108494ca5bbe9dc5605496df7869a75af39b8003e759e2c02f8463f46e93ca04","public_inputs_hex":"0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f70a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510fd2e0c74ac08efb87cf1059f1e30dcc9468113293de905e1b6098606e2dbcc3"},"decryption_aggregator":{"proof_hex":"0x0000000000000000000000000000000000000000000000032f917b0fd3ba7a530000000000000000000000000000000000000000000000035e7eee9919cfc781000000000000000000000000000000000000000000000004d01f8760c8703bfd00000000000000000000000000000000000000000000000000004d94ca153b600000000000000000000000000000000000000000000000061836908fc3b8f2a500000000000000000000000000000000000000000000000f58c698fe27f1c7ab00000000000000000000000000000000000000000000000c83238a843749bc86000000000000000000000000000000000000000000000000000212d3d108ebd200000000000000000000000000000000000000000000000ef8085780c77757ba00000000000000000000000000000000000000000000000c3c61f9d2347a2f550000000000000000000000000000000000000000000000019c6e6ab16a366da50000000000000000000000000000000000000000000000000000d7fc69b4d7cb000000000000000000000000000000000000000000000007eab1b3dcf475109c00000000000000000000000000000000000000000000000f3b81a7652ce16d66000000000000000000000000000000000000000000000000b7fbd961c0c8033300000000000000000000000000000000000000000000000000005047797e138f27e2b49d2890a1a1d7d9e9f9d5f8de1c723e2432ee10ddddd854082841a60a190d1e262fcb062cd02b7fd2f59f3a9a5270c713891c8e81a49fe088806914debc146279040a63dd82eb4ce9221aebb89787e802ddaa082e654c975d695db28095217de830d6428843cc068ed10d043596da999068b91711995406145a857879f61aac072ef64f542798bdbbbec186c9ddea949792d717af3f861c541f6d3329c8139a72a4c39e91ed9cc57640eda4f794c250d137a8490b015a87034b26243a7e2ec7f12931d3c8474fc12656898b4e3bf422912bdd4db5374ee12c8f096d74f824c025e27442c76ed1b51d39e2cf7034a4479893de172eb8b7294dc4e8d271a3231e7500f202e19d8877a126052f950431368cef6f95f062ced311b8ff6ea4a4149a4952e3d78ce456f6fe14a68b1e90adddacbbf08765d209dc70609ca6400a22b52ded226eb2c9968f70cc9e8d3ae84650a167b9c9f15c26049d55e1f4c1fa028ebcd480f734412ce5f3a2d710a6e77762d349254e59ea37ecb81347b5626e298a12385b87048dc8debad8f5b2908e0723855959723a666f21eca85d3bc8b00cd22a77a7e4e84a2b36db98f02f0eb833246fd103ab30983c6efd381068b8d71f3fbf5f01e7009b84cf9eb866f583ad0c6e4c1f1b9f457acbec88e87f5ad7642c0a219b76dbcfcdc79d797d9e36eb98bc85294d4e80f324c41aeb5d5c7e7a0024cb722fa8c2f51ebde20d08f7808d710737ca258f5d5a92b3502d21cf54b5a00f101276cd0fa6746fd15fb69b4c0e9c468793c3d9de7683305d1ac0139b3ab0101732e6eb2a8c4a782d8a4de7eec90b02a5c2d018de75c066c2494e6f51c6df134d8f766efbcf3ed54ecb62a51e4ceec128d2059759359397b487769861435d07dd738c9bfd93cdafc20a2bbfbff80b293523f1504d9eb4772de3a8799748ef0bcacec57d8ae3fc978ab8ffd64c15a20b4773db561a5a6bd51fb91ad9226911231fc9128b34c554eaf02080253b584e58ebd1cc6e6c976bd0ef8f993282680c187b610790b86b8eb17f5f46cc044b3bd1ff9adb80ca51ede5b36f46a9f62f1b1a89849470515f82eae676e8f251c869872d45d6aed4f38f7d2d0858bf1a4d93058186322e7ee8b79de71f366c9855390b46d2e6c5a6e3cf63fde1e851e03fb10b5b2399701861f4fd31c8bfd664c4c928f3413f55049a1d90c671e9a1614ee127e412345224047f85d7049836cfc6c9a331c14c1c0857dd0199a233c2d6392e1bc381eb283dd577441c23d64f5878e6d627ce803cca051052a1c74c8b66aa69162662c26b7c6664b363e0727e1e9844ce3d2662ab8fb678d1b192fef266bb0b1dfcc5caee4ca0fd5c615ed966245a26131a576c846c2475ba08597e43b5902e103e051dec1ac8f79d07c157ce88a7b2411788658e0df6dd5c23266a513e8b7a0db93f7d5689d0ca3b5c090b9258bd3a8cd939ceac84c1c2f61915d50904a9de29d376f9dd4674ed7e648efe0ce4c0e5634d8d90b6d1e569955fd105ff2751070c70d8bfc9e75ff4894afd01cc06dabca071edf803c9e8e1ce9637e0825ff5fb0305b5ca6feb8d9c1b0fe37be80ac5be9cdeef33956bdeee9d489a5e18f31b83265c9780c4ac8f0c6460997b3e829684c20823762e4850c2156c80ad47db73440f3887deb40f6d3eb415e4cf5a468ad78053028f2d41fa55af530a305d496a1902183d1853eaaa7e4d7470a5520f2142865d8575bb4d1116da36cad00fce14e000315b8a500a1a46059103ee9b2aa0d9a3a9deaaf941369b4b9d8b08ea36cd12179d921c8ffa4d2f47b68b438df65c265dcc076c2777f8611d75cbd6b1aca59119d3221631736761f87dc3fad1d9f71a4ea8ecfb742b1376c06cec1d524858892e1429670e288a4b876c12b4079cebe718f43fc9acf25e76662faba622d990ff214913406b10cd7b24a94127550adeded67a6d29e5600363f247650fa3bbf1650d9dc9af7da683071fd81e8950edec9bebdabe1f7cfe0195e098339f5bdf2a021d02d26abe670315342dd239fb6bf77024da51b7fe27526e111afa16b312bc0f009f4f13105af83dd8e15a51a81d2ead3d76f67962073d80ad460517b6444342298f836107bd20a98b029f5cdaadcd3918c2d9f1d2596d121dde8456565ec01b1db9eb5e4e16f246568c72c64a8ff78927b7ba1d22a89dc0415f084bf1a5c5e307d2fefe8c7c73dc9ca90b4fd975943518f3f9c1dfe083278ba5064e5ffb805d2bf413130a56e5a4a3eab4bad0dc4a5fdd4611ece922af711f0b99815012b2862d53fba4d59d04810bfda4945dd3c93229b1a143e5db3749c6fa8eb30ca3c6a313d74b0604a7f3fd97373f21d8235ce46c550cfa3c02f082ea381467461261022f035b91ad4e1fa0a244b68d9f81e6c2883473f7317cbc990ab7bb71f52630930b4f7231da195bd1bd644b5b2fe16173e5738fc7b368ba6f1014c055cafeefa21e4f186454ff08d1b64548b75dc5c7febb1c27ec3fc5bb59f5efdc25633386cd2fbd6acc0ce26ea7c11e8f2ff5c03cc27e6dde633edb6703664d9b25ede6297308b872b62066969fe13dffad85fb79b12a7f2ee224c2fd4e4cce55b45e4170c7125ed83804f3316f5c17470b160dde071c81d0e9d5e50f766fdf519bf945bd5921b8d4a8af0f1ee513b5d173b3b1ead3c348bd0038ed7b159be86de0109eb8082ad018b9f99c8d7eff3c28494bed4179c43636eb858bbb17987308b52bece0c10589dd01c8d6c6bce012ec221617cb673e673b8052e7e2254e9e08d84190c6c6258ee080fc0fbf163d24a91a2fc4208add9b98bef160bce94b7f6ea671407c150a42dad24823acbe16ab2537442d072a3f6c339581fd33a1749608fcba9193cd0339b24b250972378b10b92cc76c073072924728ee1f9c112abb15ad1e00396d060b30b0d3b8f3b09d8be157157e00d9bb6de1e8c4e899b78212151aaab332b504383516b0755074c07c61d550b5a354fd1204decf0b6d123acb7442f4925d18041a45eb9aec1f8a6edd6969bb0eaf06b2857963547d0ffd277173ee6a2ea831182263aa5773b19ea5cf9b871bc36a39ae544d732858f70057aa6ad36967f4613041fd1eca6bc20777d0a2e58598b67dc69eebb72d472c989d7604004de653ed0cd21ea34fd34c069dd87215a779a6a01d40d7b7333b8be940d34e3889bf96dc07149af5cbeb8494c5a7cceecdfa9ab4b9a7dc5101745b0876706a9f0fb1d05f16ebca6656b0a546606866f3493164c7c7d2617947d68e2c21c89df9e02b5e821c16f98ffb550e9eb98a1a926a7955b91366fa057df7a701e6b22becba0d5ee20388cdaeeeb6ce41b68cfe8b3d1c0d18948490c8f65bd028e3f8ac92f43f99001a8585ea21888777e6f4b0c393b95f64228971149dcd8ed62ac2245ec2453ec809a4c281ede4c0f8fead07d9c33e8fad95f36e6d71aadc7c2fcd88fcedf2c2780816bccb4df8d7a8a6b0a323a72954c8f469031663d7d150619ef3fe21ceb5de2793216c0e79a32438808983c1cceec67fc5b86965315828795a44245f82de0a1cccb11d340ed2183ead2c424b3fd032fdbdaf9e93b314d7de104100b508ef8b07f682297ad47f5a43693b375e85d181090fa4cbba644ab99bdb3aeee7cbe0a123b1680007468d2376fa4b087198a880b7d943122c64e2739285cb197ad6d87c0f8410a1295bff339df55e97c9e2869a3ad39ebee71f0442026725e13c7894701294e42521fbff09cc72bca14c6ee12055e93eb6a36c3dead6bae7ff69e214e5157a8f7b3ee1cc9a630892352325cdfe7f4673bf9b250f74b0d53a9ec62275ed08fa47c06229ee7065a4200e5d2de129180e4a3e2d896d322166a0dd71bc8ab00cae7d08c8e4ce746faa6ef6b7cedb1987db5a46bb1a78d01235dccf1967f4ce133d4a0e336c78fde09b78763813bfe420d501fa1bb77fd59dfb7e9a5df034a30286ebeffc596cc19e89ccedfa81795a7aebbcc9aba21dffc3e0245246f1099d1aaaa6598a814cd0d504a677008cb789c2eaf178e159f5c20aafb301b4f0e8df2479de0f3717d4e4ef7dc83d738610d2f9bcd50d73dbb619b8074f392837dae12bb62b06a460bc9beae70d089fc01a43d5b6c01d6ca2e3037adaf61eb04dc2ae27c47045ac7caf828a562ae12da800e7732b3bc8c550cf584f515f680fbb2b2f28fe7a9e126ac1e7262fc0c4c15a8524ffec6e26abdb450e445cb62a54df6120269fefb17a52977bc955fed6ffa537a1b1d8194c864fcf06ec5d6b129a2e319227a8fadd3a40dfa0d6819498951b4867672fc74428d26c7d490f3a2718ff46a029357e4d83809324bad732e822805a0136e3765feba528bceb2317fa20879da32961662f7a785dce16e500991e0b9c32f5e1a9b80300876499c96b3d3369232e22522f6faa2ef3d05f5fd66d54f0ff085ffff1777b5eedc80bd244a8247be09d299994111e6aa8d0b60c75a68fa4aec522abeaa11c977b175e7c7ccf154c0bcc19ac59eb945f924d1936e318d57d6418989e411ca5870b79984a5a54e32c1d18128c3ae13bf6ae39462c274431cfafdf4b5901872c1e7277a5f9e9833618290e0e06311671aa5e3416015247a0e2bac183c27dc687571b0b581dd3f6adb8962415c7097dc3d0f19f6ee891547d6a619bb3e3f1cf9bbaf99060d8556daef9b16b05416869515e72d011820ff51de020a7c702c7a7942be41bd5efd5e3e96dc3181c682616910eb09cedaee661f46ceb5918d74d23a760d7555a14bd4d012e90d713fb7320d715910b14bbe9439e621e34a1496e8b60e628c9dd5b7bc1115588c107eebb6e62f46011149032423e6ba742d8f8c8a0cf39605e7539f0f809646a3b25db17eaf635e9d1217fd85dfede27881235abe9479fb8ff0bd5be4af87059ae0b42476793bd6e018178fe9a74b84718d5bbbca46087842120e036b0bd3c578f1e76504ad8ef04a719ed739a9583fc3a4b9563d1904c92849a4be6c57f7d596729fd36cbe2dc3855351d29dc4a90ed15ff56fd6fea033728b792ab1183f256f4304280a6041459cf3e6f67b86373d6e4bec24c6484c623721f39814f7ab9b41b0ce2a10a6bdbc16d0f6603a4b0c15b492dd147edbbb3cd16b9d461c2556cd4302dff6cd7ba49ab4c5f3e468b5569adbe825f835d9290467ca676e8e2ea39f1dc294d245771466cdc3546c0624a2d325be31fd9b5d6cdfee83414c334812883b50b6e68e3c8623d0fe6aa870ef8cc6015754b26cf8e215aca15de566a1cf0e9ac0f017fc5385f6873161c7cdaa3b77538dbb5ae5b74f28dfc76d6e0076523c91312b14d00e6c72ab2a16d0c46f6b5739a3b177cea1aac83de18861d4b1bafe05a11f1cd72972a8db708107cfeb0af3487cdf6528735cd20472c1d59d4d8f1ff4209165bd6a83a3819b94428cfbbfb80252a5891c75da8dd740dd53b8badf933662994154da3d0032bdcebaef3cfa3733ffa311dd21b7f7f2e207797deb1a884a1205c698d5ae5b8290c9471ceed6e6c079e0b4f85e98da71f0456a72fca9bd9d628d04e9af4a48f36345b40e585e0aa98d56c46e59612d8e54c397a06850c45c3051be842965eb9f23840f18ee68e27147a5efedbb04efe0937418da83cc0567a079b805d9b638d171a7c59843997ff23b71ea76ea6d6800eaff14d3f79b4165a22c6451ad1775fd4d26d722bf23f89fee41e312ea67679b1fb12ce5369b497262a1f271bcda2d8b84b17c57de10e2721dc36bac0cbd65b5f9376644d05d110561a00dc9f73a118f8b7bc5ae3c6536bae7ae50f220221c018eb59ac638ea67d7313fe05a2c460ec78ec1fca5b0daf64d4c4bb9a72cbf6be833a3b0b2668bb512c23aa5a8cb69c355e5e0e8d5d0f56bb3868029a33963f3bd54a22cddfecb7953d149acfcdf891b6b5515802e2b341d5b058e0e24d56549defc46bf686bc6fe41e1293f7dea651f9c7024bdebfd07b25b7fe9d1433c0c93188c4d56635d75a808a0e8896aab641b65ecad603341135b0b2f3a3b442e05e7a63befedb318467b2ca253f5bd3a72ac1fe96d7a8399e8e5f5baaaa2daf8798e7652e9e11f8f0f524a8161953d5721896c1806a2e245581dd941fd36674ac0beb499d3531155ff4fe0d20f461de9d964337cf3d6dfa698cbd8d731c91741b16f0a7b018a8f3f85a2d842d1caa900206db1de437e9925ee8ea5a0b63cd2d7fb16f358decba50a96160b52b37ef68a5ef127e7f7226d854dd9a6834d2346ce42b3214bf811823183f3bce29a0742bc573a50a950f17d924fa0152192d75027aea786510faa92fa84aa6d722a2230b297f3225a520b30a9c719a1ed90f1c41e0b857c79671d1c8e86d639517505a2d38d3d6ccfdb9cf0be4243edcf0bd9d9919ff3c1e1423587b86902b6b1b76e4c6801996135d3a5b12325a996971feb683407d29c778a0503df7ddca671ea0fb59d11d0cc0307fa4de218be33e88dec7f09231ad19bbef47a9968884db2b9269ac913dcedd940b1c3c556243184680339d304710414288abdc275f5d331dc0edf3ab16f486919ed31e9edb034ea7548d0093cbc255136f2bda7da0439f1392cc549dfe75586cdb78594cef6290c938aa07916c0312b51733f6f03b1c7d1068ba9fb6d003144f42d11f81618c601f6dbd903082b3aa57ad3ae70e32095f171b7135ac8b3add2620cf85c589fb513c4f0d0778ac8b895180ab9088eb270a2ddb28186c6a7715a004da3c73bba9b0301d0627a70229eb9322cd1bc705f54a1f7a778414f4b7510dddfa983a039e1f35e44611da8d5e362f94a8c5b1eb74360ae4f7a7fa0af058f75ee1fdf6844c43e374bdae0a0326d2996c735914cb999504b98ae3afeeca586dc66712fb5cacdedfc84b5fc2cd440e0e98a9b43807a67128bd8c4f473fcbc4b3515924e638d31db8368b06a1ac274ff1d88cd782337c8d13c3e4a706650ee60fda16e68ad2f012a56639ff3bee948229a4ed8d9c386e222223e4f32c02efd03009b0fbf87f63d798094ddb110f9471180732ed2a461cdc2647fd700c40446c1c60e2ad89da7a5df1917822b47b358092a2bb74628d0b251d52d41534aa1ad6e94ebb146fd01ccb98bf7185bfd8b03cdebc5a337cf813450cae2b75fe2cf53bea9b36071ff4b9fa31e1f24038fc7608ea85c6c3b82a84472fc0fcf682228465a07c7d32e8472ec21e0753539adf4885e88b1bdc3350138118c811a01ad8b224bf573095db46b4647dd23ac9030691f2930b097d8ec5dd100760d78d282354c618343787d24bdec98d94bcaf21ccd2983f1bcd16552c2a50253f8802ddc74ea576d7394758ac7217b42c46c076d68bfd316bef99b75e06a416efaa9597b1f085ac6f74cc6334f4708200c4cf3591d47f0f2349d4fea8e2e406987be467dcbe38ddc69127225d20957a15c981020fd96407f2768b2f03688b1c913d9f79fbd9f2886304da7654a180fed16df5011cf9667271813f73a4688b027f9e524698c2cbaa6a88f6e3e76a6c148bc06930fbcccb6782a2a4791242600950c371942d8bd2dc889606dd9515fdd31e146aa7c8ca5eb676717c58ef26112c127d36931d54ecbf4bef7a2f12aea92d47f98cc0dc4d281ede2170413a7898293f5eae5485ee18bac0fa0adf41e3dbafdefb9d9baea98cb05ecc6b633fbcf9282bb4dffe6f83c61655df8b489fb4c01db5f7e2690b255adf3c6e885599084b07c2514a723274817c1f43a9eea8d89e5770c75dba6e113b6eb2938e772ae5011007ac68d590074f3dcd0dcd7d66607dc6105f65dc98c974e07e388029e132231ba3ca3c3929ef1200454504e844c1967fd6c5fea75f01ef3bc5d64b2b8c1f2217bf3df18b7f0e5c4b29ff22f236f48e9bc20443cc75495e3011b66033d753970e28c4adae4607318ab0569c6ddfcbfbea5ee2322832b980bfef0a1db53fb02a2b0eb14c6176a62015852a72640d1bf6f6c542f7ee40ecdefa5d3acb97cddb170f1db88477068182e6be7206269247888df636da9b456f70590c09149bcbf46a19a9d3bc40996abe93b1d5f3dcb11b526ea1d2e959d5bd5437fa4cf91969adae1b0a097d4b17e7b98449f2a90cf905e3eeaa21426ef43224e1adfa70397b968b086613a03251962c98a0ee883329f02c7e859472dde1b90b17c0ff876213a2b02a8cc443ffea3b98cbdf501f3e3e065a2c5d024e7deac62f86af4be112e0c2e41977a2a34885d25ab9a930ceac1a8be6976d64d16d8f7ba2b18440fd9e3049320e24155f1964f8562c19ffd4e30137d0df78c914369c6cfa7fb3a34500ce9169074953563f9312b4c3fe4415159d65210cd379a5bfc6fd2af934b41367886cb30988aceb17be1331db76c60f96c2844989fb22047a619fca5d9434d25d70a1670d197f70c2c89684a98d3381a81123cfa247f4a35bd976852cd73d43a4d02e5a18af2db1a2374dee122147b825440736b4ba20e8d3d680dc8650ee5a9a8a9a301c2b17a1147e43fb585c32e2cda06ce3d54af93d022a4635cf25a4fb78249f0b25bc8ba2e8fb929885b9a19cb9fbd12a676313fd3edf4066b01a779190f4e648118ad0da745bd19017cc131305257f322f323b1f92aa8155829695dc9afe423a0c988765a8719d6f25df1571bd2543f6ba16b19311483a74c784b90b27ddb3b22d6064e4447182baf8dc307320f3029b20cbb8c8896c54226e0e85d4fd70067b0d854dfd5d25f82aeee8aef6e967b52e77caf4e2d93623c85cf63996d182bf5404d4a6ad89410e41775d0876a535c834f85ade195d0b00b462293316a9df7ee12dfc932fa7fc97f276ee49631067d06ccb97b2a260417a009b500958558bbbca05fb66776dc7d15293db5eb8d19df4f3373a6a17a6c3106652fe96751eaf492509f36c9658c35b2ccdad5886ee631cd2e58412a5e503fccdf4bb71771c0947f70db6388d35cb0038e98fe8b78edf81b51a6bacfcb40b93f8636cf07adc589f0f147a7446ff1d2022274ce3b89baf6df657de69aa0cd1c957d8c9f9de2f15ec2e0f7ff502368270a30276308c2f09d0f35de5d0c784c8c45c9482a1f789d021e325c3c8a18dae526ca06a6e6558c6c41fc8af0bdb17fc360cf744c4cd891805a92fe989e097d5ad743ddf07094129c0d1e503511d4f81190723f7956335c2d9110d24f22584b4c727560b83aabdcf961b690ba845788039718a4506dcd048e8dc2490ff6a88b9671d9398eebc8319797bda55d642bcba47f139a231d650101aad27b12f3c069358e6b82333bcac1dded6c23d8900930f2c5fc7be3edf64874de1141fcd391a2b917da0165ab0fef51d6730ae7cd9b9b1f3d0b55fcc72eb3e17b62debe56fe2e10127f3b046cfe373456b3360509b8328fc04d54606829576c5250462738984185b20a0b7f88023f3e7777c7ea62d1a41d364c533bfb2d12fa1cd0db92d5464ba8a38133367f515e4de7d424c586306d9ce22987b7247386b01022757f4648500f17e96149cf652c6c6a28fe9f85e045be8d9d66f92ff74229299049344cc223c6f1bd7d67761c9b93ea2d8c912d34ce9af9be5aae395f497c90a0af3b013a82b622b4942d4c5e76acb383740009874450f496f32cd7517be45ca289cf4b127c67cf0155168cdbad6fdad969ed7f1c8162ba8f5f89e3886b812f91e21f02ca64205417c15bdd1379eeb814083a3c32dc715c0747dbcef6dbdd7531d4deccac77bf29d1628280a89c4848c94eaddc3b36312fe2505b37a6d75fe81045025949fbc93a3326af3fd369d39fa6c009ca3471f1113847a3919b116bdb9077a09781a3a637599df7fcc98839e11c07e695d311bc51e6b8d64b55d2f170400e634e4979be229ad38ea5e2f128d1572a85cce10f271c414c04a306c6b92002a00e00825eb99906a26d1945eda3910b84502cd3482d0d84f5847932dcc4faf0bfb0c9f3bbbefce5991057908c42d2d5920d1757da51a12d9bd5d99790f76652c4307b7d0f927786d9e6cb6c57ebb44fc5d2b04c3359d3f4e3735a45861a3ca2859d4f4306d1843f79a332294a638cb1f76622e57d50558c1f22abd370503c903caa3f08dd93e5f82833de8e6d46a3341e7a8913f2a7e22e6643bc7c6538c8e0cbbf6fbf36164fe1b6f1145dcee45960273b2891250ed461e1ae1f23b19863c0ffe0810499d5b5be47ab8bc81ed7a2e004439eb823da19d539f8e7ac1659a92096441c33583ac9c5603ccb0d44c51fed6308f069da81382b1a1d74262f89cf328243fb2580e1a1abbbe2bed12ac80e361ca6a4123461a6d8efc5eb8672dddd22320ac7c5a087b21dd48e32e8ebdb4da050b93dd294e91d28a238b59d41d6265221ceddff0fc2a28de353b6c14fc5163ef26aaf67bc153eade50130c49c682e91851b297fb64d9d792b9c9c44a8a8bd2311db7cfad7090e8d1badfa6ac6a58a207f955c456cea50f9ebc0d7f95b4bd3347b211234a55c5c4bf20a183ac9b683719f208fc6b8cc67ecc372b325a4901678b2fb9288b4ff6601097abdc14df17010ca0147edd325f460457fb6ecccae55494c61cc30f5c29cf57a424147feb0b26195c0e3e739d3b3669af537c778a151926b774187ef6000f4d7349c6d5a248352efaab21ace4fcb78b5226827b068bcdda804f14b7fd86bdafd02c95fb60def714b6962ebdb37972973f9cac5db0d6bb9793fa68f19129a098bf9919df1f9f382df39520119d0fa7c8b262361a51fef9e5c0418b4af5c082b50dd95af82039f6049c751ab056b6ca7b13a1c1fbe61d36341c4df78ef722bc37a0635e42af44201d7951639b2fc9037432aff590c41fecc465cf82a10c7385f05e4ec18243106408c4fa61fa0ee08ccae97a0f104cc9c331fd87b786a8aaf813c05d187b3e30dc240b88f66c0b8d5c82efb9952183e37131290dac7ccd34bdf015214f933e275e03583c09916c1c6ca5a79acd3042fc82c1880dafdd9c00e1ff3ad410d8547c400d58dd99c637a8087117e36ea91e6812c6742e2d7250bf9ffedc435e6f79c9ee00de2aae6f0d19c82b5c99cdeac09f23d4e9e1dc20c1aa7c40a19b175c04ed182bf3b47f5dcdea54be39082d106621c59df843109a6883e4ca3949acc4e9754f103077d98bc264134bbbaf7e90d8d842a33578a7ad26a061c9ca6b77b3587dc826b783db0e3f346007f66f31f8612359a1aa251a23fb875f7d529bcf9223978716c7f5b8879fff558c3799d234346f05d7e80789d437b4cdd55c2be81353abec17abd7d2ecd9e1450ce944d03c9e6e517075a82ce5e4193844eac41f54abbef00f86aa9bd96eebbc4a7b67067fb9de593364457f94ffbdc8776b908b68b73c9c0850cc0dbd973ba25d515ee139f15fbfc0f125e1682f8f4d42b47f7c3281c2251f2eef4b2d676d4791b21a53a281ed28902f731d256e5edca72933b79053311513bb354296f2cc4c225fed68e505bf1430b1e5350b29049107ed15530da30d8a26863fadc7374c10adba56cfce0212cf3ef17d9021f63ffcd3de6b55b89f72a22c2b59e3d3a06970bb738b602390f6695fa876d376d9c0b845fe711a85e77afc2ba278b527ee921508d815f640ec09bc8d963a6aa450b1bda744f420a23e669d2df4d35f90eb8bba6771984c28fb5575cc5628cd6437a9172bf671d6197b224726dd1157e09bafb93f5e8daad3e37eac638fe47897bb1b8f476268e2f4783096133455ec390141a1bed6103851ed452c5969ef4765c5a24f4d17d1b3676e80dd2315c58cc3c2018a9e4dfa28d965895a1eb055c7fe41eabf03d3036be840abb61301d966663a812629391084a6b445fede42b562e60e0b74bd7b7f424474f87d02f3686c606b1a96da46917a8cb070f6867b4672311e248492072364ee5e70842f52ad47f0cbc0b018fb41ef8694d08f6f604f4ca40f578a7d0c561021ee8dd62b4605620eeef24fae8d03b5ab8ff013f7181b8db77f1fb03565bd5c9d896f66285ac0f3bf9b155ce499a793df6bb993d5aa821773b92854d96b59e91f212fee2c60be3b197bcf457faa4932500e94ed760070c26e49789a33186f5ffc99447f1676d9956e30b06c28f150456073c06cd17380311cdd6e542cfe862e3a00d27017b5827b442d3af40df6449ed4c04be82015ddc6ad04112ef5f062edda022e8909cedae081e8db20856c23c6baaeb42c2c5e7b0fe8abe6ec3980efb76912aa4309f135514e65c16895796e9b278a31a747ed20eb572ab82e1a49fd8ca60a98f823cf3344f17db432a8c2f9baa00be40038c98f7c11a1b2c414e67686b77720d8137f3272f6de98b68ca04b28d2396f5a2b6d894113b7f7af32aa77200688a6952583043ef8ff22e4c1e417c68648a3380691e1d9bf55db4533703448b331fc4b1e6dc67cd32bb0f26b5cc312fbc5a8eaefb7b10ae7cd03402aa9ac3825b597d62e10e39cd2a8fd4bf1517d37255560dc77db0ea2db7edfe9cc564d0fa22ced9d2d80ee077547db7160f90ee4e7fe9f1c3235acb8323abf43e2fcfc741d5f9a9819cca25bf68ec3235595d7f0d759d661253e9ef535ef4d8e4b0096e814e013921f749227303bc67bf6cefdf344692198576b1bc4356c73ccdfaabeedbf69abde2c462f80f1980015305e52b10707bad1889f5c39f736800aa51f1501d405b3732af595b49c48b4333f160b58b87ca84c910977c93aeea98a2362e4daef3ef63f08bc094cb1019eec6c1e9f2feb2bef068c5fc563a013950433c25e7e218b66051d5a44837375c1b83c9489efe3099f427c67bf0fefb25dfd8b626c48d00c7a4b1070504657a3b7ccf42af9dfa40e93afc0e3a5e2aa92e250f2145ea915abdb6a0b78fd055839c44b13e2fd7782d67e7a0ff4e1181b4bb64124543f5438702ee42d8d8dec996a95e84c8c9f1419c5bc66b34aef3700a67786714b6aad4147643c172c4a70c0e363781f8956e374b01f88f397750c374cd7d163919d877889bd5629aa9a70dac88464aeac5a0cd4906d60979ffc1e4626b0af9aa0a22e9d3966ac2609ada8891286e5fe76227c8b5b50a267171e1d256d6468ae45360978054ab41625cffa58eae964ada1e6369b9c8b2491d372aac40aff7443366aaf6679274f26d13c1d1fd13e2ebc731975b57be4c9eee4b6dc88445d8ffb0d6de2e69b8463129087d86aea27ccefc304326063c7972ba3e80553fac7c5c488ac4545f8ead0169bf87f01acf9353d0ed6fa6a55db96bd9e41ef8fb4f1c2628e86504987acd21b9af044c092f91ead0db66966546169c32b670bfeeba5746860f83ee005d0da01bda136cef67dd3e66a111bc90cd88056b1619d90c701fcb20a7a4ac33342950f6188bb0e7d4a788e1a24808954084e37d8377cef483a9a84490b46c95d10a82c27ec6acd7128da9cd8250a45fa24b5678e94a0eead4f51b62881505463237502442e915e71adedfb9f97115ac5d150170b2d572e067a92010f51c48168fa8005fd3192e9b838c58f31b3ecfbbb078e8639ee2f3a5dbeb8dfc5ffe1175b448c00e213d2ddcead739b4563a90f47b5fdfd45eefaf5dcec0768df8490020e69282377fb10343b5a8a221bb1fea3bf8fe84a790c1adeab68779614f29c283810200156b08e06521c126199dbb9ea2f2a6af5f5b7552e40ae1555c760930577969e22c7b04ea4e95901c650a73c988c618bead593d17d5007146ea9c47dc77d14ce0e03ee7b11ce3448fdbc534f42ef81bac3bb78c15b1b3a83d56b3f36d21b62d92510252201ab1927d4ba5dbaef0f3e1c095e8c52a019da94e3560e11a83205e4276ec3235751505050679851506af768f0cabdbd6571d0995bcad6e3f6c10f6a1e09368c3547f9ad262f12a9adf34939cea2d1154acf2aec479352ded626aaef25982e7552e667fc7e4e9e6fe330dfaa6ec83fca6b2604281666f3f99c32262905e6a7d5c87d6ccbf80260ab790e02fe7f51dc8071a5fe80eebdfa76a7c258961c401120d9f12b68c977423df5af18e93b2193e9b74fe53bbcda7468f342863e08310cbff5ea6c0ff558bb83aa2bc23e8df39b3383c6ae5f86c22845edb39b2a2953297894e3c2ad4e253dca273b043ab725f81833d327159207177c0b0ec96a2a9d9dd5834c42b493856edf49a3cbe2be99b4711f6bc83e57cd41137641847a04d4127ee7420f4b77460152b4d7aefd72c105f3b834dededbdecb89a1c4d2d22831a4928e242757e1f30360cb8c0501aa4642cf791ad9246a4a49bc712086c50cf0c0067bfc80c788d426bcfa946f8830771998880594658acedbd416087f731c2d9a1f721e273a548daa7078371b7f6196244479f11b24ebaa395631e9ef1f0ae2ef0548e857f2df929518a18b8a95717f00257f6c5f133ee95ca28b76febc122ab204fe89476d434759f23f70fb44b03b5ef93011c0c147acc417dbff7800172bee75bd52030baa9d42c0be98620037f763ea2b51bbf861b8f03a03eb2d030793cc0c782cd860d2e212b7de317c1687b3a7c3338926cce04b4a79562d77ad232eca3a2901fa6cd0fff130d3e55735b134c8022dcb25f8dd068d5d1874e3572012f7a4df16d20451fc0d48ffb0b844c34d578893abe54f5da62af0c4b597b51f8f652fb2d9440c9641bf27dda51477b9d902fe04f5be88f852c3558cb1a5fb03ae2d0635da9de9c58fed8a406dd3b2d99445a575fa3864f1d4c4351617617e1ed2bb4f656f1113aca5094ec20d755d1287fededfbec38fda5c26660a292656","public_inputs_hex":"0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a00000000000000000000000000000000ae6a85768f71c83f114b20d8a933586300000000000000000000000000000000ebd03ad97202d4bf5bf80bfeb5239fba1f8e48fdae937d71edfb5a4d694a7bb5a16a0c2ed1ab32e08dd664615f32513e0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}}, "test_exit_code": { "crisp": 1, "folded_export": 0, diff --git a/circuits/benchmarks/results_insecure_minimum/integration_summary.json b/circuits/benchmarks/results_insecure_minimum/integration_summary.json index 77c5b4fcdf..aeb07b29bb 100644 --- a/circuits/benchmarks/results_insecure_minimum/integration_summary.json +++ b/circuits/benchmarks/results_insecure_minimum/integration_summary.json @@ -24,227 +24,227 @@ "operation_timings": [ { "name": "CalculateDecryptionKey", - "avg_seconds": 0.004326667, + "avg_seconds": 0.004105569, "runs": 3, - "total_seconds": 0.012980001 + "total_seconds": 0.012316708 }, { "name": "CalculateDecryptionShare", - "avg_seconds": 0.022016291, + "avg_seconds": 0.021735208, "runs": 3, - "total_seconds": 0.066048875 + "total_seconds": 0.065205626 }, { "name": "CalculateThresholdDecryption", - "avg_seconds": 0.020120625, + "avg_seconds": 0.021883708, "runs": 1, - "total_seconds": 0.020120625 + "total_seconds": 0.021883708 }, { "name": "GenEsiSss", - "avg_seconds": 0.007776041, + "avg_seconds": 0.006303152, "runs": 3, - "total_seconds": 0.023328125 + "total_seconds": 0.018909457 }, { "name": "GenPkShareAndSkSss", - "avg_seconds": 0.011192708, + "avg_seconds": 0.011035416, "runs": 3, - "total_seconds": 0.033578125 + "total_seconds": 0.033106250 }, { "name": "NodeDkgFold/c2ab_fold", - "avg_seconds": 18.821508069, + "avg_seconds": 19.281920111, "runs": 3, - "total_seconds": 56.464524208 + "total_seconds": 57.845760334 }, { "name": "NodeDkgFold/c3a_fold", - "avg_seconds": 73.488805041, + "avg_seconds": 72.091054403, "runs": 3, - "total_seconds": 220.466415124 + "total_seconds": 216.273163209 }, { "name": "NodeDkgFold/c3ab_fold", - "avg_seconds": 7.851751111, + "avg_seconds": 7.793962458, "runs": 3, - "total_seconds": 23.555253334 + "total_seconds": 23.381887375 }, { "name": "NodeDkgFold/c3b_fold", - "avg_seconds": 73.173327319, + "avg_seconds": 72.635186750, "runs": 3, - "total_seconds": 219.519981959 + "total_seconds": 217.905560250 }, { "name": "NodeDkgFold/c4ab_fold", - "avg_seconds": 8.281481527, + "avg_seconds": 8.064746388, "runs": 3, - "total_seconds": 24.844444583 + "total_seconds": 24.194239166 }, { "name": "NodeDkgFold/node_fold", - "avg_seconds": 18.939945583, + "avg_seconds": 18.460723180, "runs": 3, - "total_seconds": 56.81983675 + "total_seconds": 55.382169542 }, { "name": "ZkDecryptedSharesAggregation", - "avg_seconds": 1.593031959, + "avg_seconds": 1.575791792, "runs": 1, - "total_seconds": 1.593031959 + "total_seconds": 1.575791792 }, { "name": "ZkDecryptionAggregation", - "avg_seconds": 49.684318333, + "avg_seconds": 48.474341959, "runs": 1, - "total_seconds": 49.684318333 + "total_seconds": 48.474341959 }, { "name": "ZkDkgAggregation", - "avg_seconds": 5.735565959, + "avg_seconds": 5.560166834, "runs": 1, - "total_seconds": 5.735565959 + "total_seconds": 5.560166834 }, { "name": "ZkDkgShareDecryption", - "avg_seconds": 0.948800333, + "avg_seconds": 0.766792666, "runs": 6, - "total_seconds": 5.692802 + "total_seconds": 4.600756000 }, { "name": "ZkNodeDkgFold", - "avg_seconds": 108.814322347, + "avg_seconds": 107.170507639, "runs": 3, - "total_seconds": 326.442967043 + "total_seconds": 321.511522917 }, { "name": "ZkNodesFoldStep", - "avg_seconds": 5.313063916, + "avg_seconds": 5.213900541, "runs": 2, - "total_seconds": 10.626127833 + "total_seconds": 10.427801083 }, { "name": "ZkPkAggregation", - "avg_seconds": 0.29689275, + "avg_seconds": 0.397447291, "runs": 1, - "total_seconds": 0.29689275 + "total_seconds": 0.397447291 }, { "name": "ZkPkBfv", - "avg_seconds": 0.229513319, + "avg_seconds": 0.221726250, "runs": 3, - "total_seconds": 0.688539958 + "total_seconds": 0.665178752 }, { "name": "ZkPkGeneration", - "avg_seconds": 3.607771166, + "avg_seconds": 2.248425542, "runs": 3, - "total_seconds": 10.823313499 + "total_seconds": 6.745276626 }, { "name": "ZkShareComputation", - "avg_seconds": 2.617024506, + "avg_seconds": 2.503326757, "runs": 6, - "total_seconds": 15.702147041 + "total_seconds": 15.019960542 }, { "name": "ZkShareEncryption", - "avg_seconds": 3.672300166, + "avg_seconds": 3.921781749, "runs": 24, - "total_seconds": 88.135204 + "total_seconds": 94.122761998 }, { "name": "ZkThresholdShareDecryption", - "avg_seconds": 3.494414028, + "avg_seconds": 3.427196402, "runs": 3, - "total_seconds": 10.483242084 + "total_seconds": 10.281589208 }, { "name": "ZkVerifyShareDecryptionProofs", - "avg_seconds": 0.082335722, + "avg_seconds": 0.154358833, "runs": 3, - "total_seconds": 0.247007167 + "total_seconds": 0.463076501 }, { "name": "ZkVerifyShareProofs", - "avg_seconds": 0.244133875, + "avg_seconds": 0.253084125, "runs": 5, - "total_seconds": 1.220669376 + "total_seconds": 1.265420625 } ], - "operation_timings_total_seconds": 1129.198340711, + "operation_timings_total_seconds": 1116.245293753, "operation_timings_metric": "tracked_job_wall", "phase_timings": [ { "label": "Starting trbfv actor test", - "seconds": 0e-9, + "seconds": 0E-9, "metric": "wall_clock" }, { "label": "Setup completed", - "seconds": 1.017932541, + "seconds": 0.968119167, "metric": "wall_clock" }, { "label": "Committee Setup Completed", - "seconds": 7.022026041, + "seconds": 7.026030458, "metric": "wall_clock" }, { "label": "Committee Finalization Complete", - "seconds": 0.001739292, + "seconds": 0.005051750, "metric": "wall_clock" }, { "label": "Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)", - "seconds": 125.46852, + "seconds": 122.805809000, "metric": "wall_clock" }, { "label": "ThresholdShares -> PublicKeyAggregated", - "seconds": 137.630169125, + "seconds": 135.105291709, "metric": "wall_clock" }, { "label": "E3Request -> PublicKeyAggregated", - "seconds": 138.13360025, + "seconds": 135.613361792, "metric": "wall_clock" }, { "label": "Application CT Gen", - "seconds": 0.009520666, + "seconds": 0.009316167, "metric": "wall_clock" }, { "label": "Running FHE Application", - "seconds": 0.000055291, + "seconds": 0.000052625, "metric": "wall_clock" }, { "label": "Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)", - "seconds": 51.290023, + "seconds": 50.063420000, "metric": "wall_clock" }, { "label": "Ciphertext published -> PlaintextAggregated", - "seconds": 55.067765875, + "seconds": 53.769554292, "metric": "wall_clock" }, { "label": "Entire Test", - "seconds": 201.252351625, + "seconds": 197.387759916, "metric": "wall_clock" } ], "folded_artifacts": { "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000893e2589fc7272df300000000000000000000000000000000000000000000000f9cacd727086112c2000000000000000000000000000000000000000000000001087d088d5e0eb68400000000000000000000000000000000000000000000000000012265e9d423bc00000000000000000000000000000000000000000000000848d741a33c08ace2000000000000000000000000000000000000000000000008900eb4f01074c33d00000000000000000000000000000000000000000000000bb603d265d0e8c3f300000000000000000000000000000000000000000000000000008a6c01ce44080000000000000000000000000000000000000000000000056a1f3c8c8cd10298000000000000000000000000000000000000000000000000f4913d1f1efea4390000000000000000000000000000000000000000000000055187776dfc7e27c200000000000000000000000000000000000000000000000000020e60b75114b80000000000000000000000000000000000000000000000037252d99ba4b6b4e600000000000000000000000000000000000000000000000774c7a54897b11a9500000000000000000000000000000000000000000000000fdd40227ec51bf31f00000000000000000000000000000000000000000000000000019c9203decfb90e15854237f5c72c41d9082a4545b24694b629e686c58d51412f7fd32e13d5cc131b256d0eae84688fba4f2c0c00f84a33ccf9eff8eaf9f96b18557d2a7019f3034e1dcf5038db8476b5ce28e0eb6d0b588a3d92abeccb8acadcf67559752b4820a6ae16edfdf62f6c4ff6f5dac318c159ed8b8a98adb2c907a21b91bb74450924ad1b7b0beae123ea31c74f103bd2f0d7838483cf5960db17d47b987b8eb9f41868dcc4c2d77185ff80d4213515aa90244fec519f8b4a3b94b789e212393534132732aa313e4296df8b5f17497adfb0e14abd79fd3d54f953825f194baa0bfa1b5875c2c1b1876a47dbde1ed563a4d0dedc8c3686bf29a39fcabb4f4d138a4305b305e25ea240ee1a7676ee159c5c0cee9881d575d82a8436a3047e0b16bd4d040372200291485daa1ef88b8e351a3aaff641c72510b642515345321f0aacdc2f1138db62d6540fd8f07939380763a72892091168fcae86a010b455afa401db031ecd41783b303eb5655e67ceec7775594faf23d9531c1e438fbb2a504a956e1b7bf6f6a9a1199f84d5430aad0d3d92f6f4040ef2b13539270b3a40d7505f931eca2310d783a3021e50216a221b41b08ac834737f354d673289128fd36786d6136e38d2f4d0b07b8cc1bb220bc7b8e57024195931350e83657d029a83dc34b7193c7c10e5f817db7d9edeb2e56536938360ba7662c40955cdb42cfba3ffe3471db3b457f7abc3da3b5c6cc1235d1443340fcc130ea8c7a1a27bd327b204b8bb1444f7df9b30ec99fb363c05cd8a95c8911703089acebf0e5374476e5b04ccac0ba4bae2950a693e469306142da1c9a6803cc03aa6751a5ede2660b6456d7ff50a22b46ecb26c32f8483b832badb3bd261b76147946ccf32ccc7df80755c970323abfd79e860344af0a77ef4158a686473f2ee44b9463c55a5fbba510f61820608315d582ea7ff959f9e0e0ece8f579c13bc173a81802641c6d59db9ccd02fb8222df1d855fb1a085663adbff7682626e7364c355592466ad27289f4e763e4150e11f707808d36e43f0942b2bce4623a17f32342e6159406377ddfc6a610497d064214c534db9af22e91fc4790d334549474cb3808889a7b233902313e8c9c1a078389b9a6bc5837f2c323f9c93da198c6f7ffc7e8506c22b6ea42e0bc92a9691e98e4a0334ff82dc0c51dbedecf9540cec8d166f3abb7acec918dd96d10159f277c4473b121ba1b35f5a6af679116f5bc600f42b77326cc2369b623347572731e3e5c676b3c710d4d76049409b96139a19caa6f489579243903a78bb5cc6d8d26546bd4ab3e7cf4e832a8158c91ba19a9e56101f466aadd4a5f6bfb7f8825d72c83d4e8965ba1468c1e93822666884990221c364cc3d56baf7b47217699b7af230b7d3b3d622b2ed8763f89c57955223d99ca2203786ae090d3a65884abcc6b117cd2bd54d1df58312861771bf6a290452d4c980ad6d8d77ef4455012bc47911e89bf3e709ae1bfb2731c4aa674fde1de69a4801e10c4923c4de7f339f85d5b2f00e7fe872d692fe397164968df3140ba2a3e8758c9a0e530903b569bc20ac6186844791c107f85970ed03a94a4120914c716a0f0606f6f66bdefb596ea706821ecbc8bd8932e21da71ded29557eb4172d7c4545a93a547fdf16e2768e3ec322d0658c1aa5b422e4fa9772c6222e1018db983236a2fe4afbc28e3a7d49aae3d0ab553e9239d3502e082ec865748cc118e8c4940a2096666785cbe269d84a3140ad922d438f9351ee68dcced4be0cc1be0096a717b090898c7a4b42c709cb2321d461e8c48dc9abfef867f2605097e9cafceaaa1c13117593bf3e4a47c350aea0f9fafad053548201fb07ac10455f6921da3e042a0af83797c1f518766fd5d9b1eee4e50d2912eb8059b9828ca6e9abcf7fbc8ca9fd31040dcf1a854b7ddce1823db49a85ae8c738472c347d5d332b51435ff82b2f9be8299e4c25ec3cdad2cf2372f312ed18b598f946ca078925c6511a63fcf014e95611009c314dbe8251d12ae84067c4f60fa43342708a96c72c8384fd3dd8510180f6b49dcbb0d6b0facc1431f6c045348ce0bd87ef9a7236126248b2cccc0697081632bc406775d2a81908d720f4faf784847862ee70967996516e8b1e6c36ce347628104e81f7537c972c8e4ab9c91a6f1f77edc7342c14fab39f3a89e3c77f02d08d5a46f3e07b31cf0f6fdeeceeba4efec088c521ff006ff8c62dcb71f444d65a28749a9192cf0a5c285a1f5ff79e8b76c3d4b15ba348b53041aa272efae3b2e1229e5b848a53180f2dfcdbfca0b368a59895ad8ef89c2db406b321ef980a673d66af38309bd1f8c02f01c5dc5bc307f642fa10ea809a214a256ac01aadafaec2fc8afb7e9a9060002c308f5e70b3ddc778f6aaa93630cbd17812cb210d316ea765117de0d6a975d52be3b032ae5b4f7f8efd0c387d042777cc46081a21b01929a0e851439ebcf53206053531bb680c462e2d8384ab322ff49426713b8a51aa30799d442c3772e7d72e53de315a6be54e85a3cc8b085e2837708d04206ef9ed7c075e54a3a1afd1ba122d34c298db267bf0de8979d3ea39981d8b826674c14bfcc73e1a40363a6a8d29858aa7a71cf3b41962433b4d4c38e6551698c82f67f33d41e13280121e551306c57d9e157f35ea90947e3e0eca751dfebb4528f409f8b7afa242345596fbb005cc617209a7bc2349235d7a01cbada55d7e457da18c3dd779f95a045a29187a18f7c25c8cfa61c702da793c22ba1ce87f369d82e49eaed8d7d99942de1e71cd05211c1a0da9dceb8776cba9c9de442336c572ea4d9deccc148b68b634693f0c2e17a10268df741e380d585ff3ea618b550537330b5b4c046c79c1419c7b494b02096cf7ab81dfae1a38d3e1956558869d84bb362b3fecdfc06c0dce58493bba2eb27fc58a2bdc4ed36c00bf922c5c1db5de02a4c432050a51ded9b099b41cbc061cc328788be07e4ccafd40b6bcd297b04797b97014eb32d258ee1ee2db13720122e99e0da54f6fb50245e680a31f64f621db6d92742171234e7586eb47891506f63d0daa7f8830c7f1367784020113578b8aa8b5dd4afc9fc9cd33172555c01eae152d42a6ac71c10bd1bb6480b7e40f8c3e2479d6c13e6b170811614e30c10797e04f4a794b23ad86dce7b68cb182d3d85328272e204224e373c5e5d7b41d29f8ec5570fad365770fa970af609eefc121da6206dc0d7f9391279e1948767c2eba3e936dbdc0cf22b8c0c670eb33a91a751d1580e32024a2a348e43c54a1f524c5c7dee7bf08b6407a4131bb7930d20fb78abc761d045841181c23b71807742e66ddd71bceaad5da2812d15f6bd7bf4b7abc39a746237b0ba166a1eff6a6361dce8dd8adb27ab557342db41bb92bb4dc1cee964d945cb4498628d373105d6a13ac28ffd7e9d74791f69bea43c9a30cc3d94d596f9680c3f04eda944c3eacab279565526a000489a00586d9867741b8c2bca52d99f56569164586ef339b1d0928cf8a27507b425f09889e3356238dcbdfe0d82ea0b25bf9fc7dd421156102771050857c3d200468629be6b8d50cb2f8ba886aa273d990d7253872a176ecfe2b2447b44957ad7a69fa0fba44fd137cf23203058c369401d2a8968b310b41600a1a8cca2c4f7eb5c10fabfb3912f6b4508b1499b61689286c92e2e10253fc62050db4c54731b5dd71fd020918713df81f373894c9e02ac407850911f7c65385a52ed9beb9b040e0f864d586e70ef47a84ab8009b1c26a482c661cc055921580f222932759de0b675fc5798bbcb1c97100d0e1178c3a9fdd87016ad164dc955b140721c4a127104109b1c4341dea673452c92a61455d7428e3fb33661a9cc6e805090b9f3af1250dc3692e5059ebf26b55ed24a1d17aac0b68cf098f87e87ca7cf0ee33d642a56905b9fa1ef08da3c79561b196b80e60928ed00339f73fb46fa1414a894a6a398d2881b92cb79476d91e9f05b709bd710e917802dc6cd31b342070d5aa5d7c38d8cc4e50461596b5d7240aac423856b44ac1d7695422ef9d190410a475b3de9d662aa4db4bfa5ff7f48cf9134f88de6e3824fed4fa82b8ea0eb7c0841152da5d56674987df02cb6d40314192857fdbf1e72ee745126823d350b1b2755e28a5733de1c902e753dfeb0345c45374985a8230c4719ce19642a6b39c001e40f6a1550dc098de688f2e5c20ffeff195bea4e58d45266c19d09ac4dd1c919f7d04b1c9017f95e5d6cece41b7f51fa6a767a74629c3fbf7f8a8c53b87e14172b8536b1752f50f587b3e87d1d32fc1aaf8f5c8097788a181144d396004ea52c248fc06ca0532f69b66a94287f5465e274cdf660854ef5812e9bd7d202cd361a6c9ab24c0d08eaeb17234f7b649849b17a82d2b4628e601165cbfa735b4a970d74e6fbfdeaacc9d23d2b7552f3e2e7f9cf36f245d72b9b0562233134fbfef13017c428b5d653681f822febb94d0d5787caa2fdf62a065b3cbd9cf7411fce960208555c6f62f6d0a9753d603c45b0ff2c26f61463fca3e9cc701ae605828152173319e1ba545079e1622b6313a693e3c91a61280b07b454303170ae71ed3fbf10221f39c22c89c3dc16ee2a8d3ab33f3e044bbcafceb519c20a6da079f6e3d818ce53aaa8f48a1cab2e844af148fa69cb3352af974d9161b8e46e514a39aafc211918caa8dbaa52c6d92b19a3c0e7aa2e5315f646464aba9c170dc165f088d92d3eb20cb4e9b6df442a4581f7bd621f7359e7107aaf2d6a96c8fa679b61d5ea263408751bca74056732ca92490d524dd393dd1920ad5d73bf36978c69c5a91413eeb815b94283fc18604a92c7d581223a897972e1d11f5d5fb18ea39d2c7c082c2f92b900e56c6e89559a144646c92f7172428ed7dad04833905b40d9fe3d02175c54ec7dd5eec77a2f83459dad2c7ea0afbfd3990e2af01d3adc3bbd2d4bdb2cd9e668a481f993b20b52d6695d4cab937d3388872e7f5292a2be8f19e912c51cfa1edf49b1f17a32fe84c10339ef67123b970a0ee9c32c498275c4069d665010942d89642d918d1608275e3683a6965334ec106a0f33fe20bb6e2cc35d65020c2abc37ef27b01b8baf7861ff6e75a6c878ec9ae8518d3193d7ba6211cf17610dbf3da6d82edfbd998175540b07c81b9b82554e8595e48c14f31e6fd979fd120b504192bbb4041af130e3443a95d694f484a388ffbc15a9f5cbe69ec8df85971e971559580e062fec279baec48c4c980a5b3ee9d9468135b28e6456c38722b024717827fd83ed7c07213e618ab3fc32e8a7afb39c5c295edd906eff182638a527576cde3d29dc6ee178378731bde6dc6b6d3f86eb97ead0f38894d9ccddbfc7009cafa51d2cab27496ad63f1e8dd6fba1d0f8d2ed6472d4d1b0fd0bd84185161bc89f8431adc4ae1c564fd79f0cdf3d331699e02813f944dded4444da20694722d06a7a3b2f66252781c0702e08d8d6eac0cac41111e1f19cee0b32ed5e4de626ab830809f85471c97ee8d18f0e49a9f59e23e2ddf20651ec29cd4b358c6c061cdb615bf651f6007a2074e4f5679dda0f83be4de87b9649ad16fbdd7e951c2d10afe06e9a07edbe7d7ac216cb7210f5d829c8e094aec84046bc73b3ddc8eb0d1a70e728e336cdad54f8c03670cc53a4efb8ccb1c64bd687395eb426c63fc3701284e98f30c881e829a47207642ad663d6fcf23733f0703a62f76b9d612c642910524dfbc4ad584ecc9aba8883766d6ff71b5bdf87de0301b7ac966efc5cfea32df53aa6133c431afc06ffe5fd7f230dabb3791045aa1b06df3031c9af4007ff16ecba9d8d3dcf9bc228867fb0d0cb6f7cbbb301bbea190b19d53dea570589ad22f0a4c22f7c143798bddbb1db1ec81e892ee35b7bc566412706f6ba39db47222c5b24ceaa70b934f696b3042014f4d71242f3465fd6bbba7fc2aeb209da45d8168749bf202b7d7751a2c7a6738b0dff17d8ed462a2a4d03940f089083b3e07113931a991816788c975e884ed4fabe62624354c7d7cbbb444f09226f28bf4c88180f64406dd0a9d860333e34601b154a0f617b129b91b798f2d6642b1b3f6f4d048d5f4ccab3a704884851c7dac301d61e83eb8650b4101bd0b5b2d97ec88c5022f0f15f227881968414436094841db6d1ba966046c9f9896f897c62811da7f10c2bb7650d2a76e618119fcf7be78384e4802def8df8e81700da1295a32a138e2020174ac7aa7bd8b333d9ce80f19d89cde515e77c87894c45bd66435f5603240a0656a475363a01ad7fc570af47536e52d70592ce4e9a8b45480aa2dcbfa1da14c96f85e04ec5c925b1fe7a72e20ad432f905dad4c272b7cb948147daecbda602fc461ce29574a5feab8a23c9f5c9530f4de936aaf119781321b8eb04fd221123971631c97621631d403795d5d9908aeb33310de43fea8007077a7acd121ce220cc548aec560ee0fb11777ee0fb6034800a009353c47fd8d9f59fdf1812f0e6165cd6906e559d0639f2b89305ed45e9de8ab19564a549b7d128fa38685eba0618a16438b5e899b824ab31a49706b90bcb5c838d18b9e70376a54ac54cd871a60c49d283b19468ee15da356cb55ac7aa8ee6a356dfb951dbb8fb928d79cb39791ff85032801bc21e98725d3fd417d948194e8f93d330586082493206aeee5f672b47cbef3d769fd4c06e2adcc54b93df406d84ef63f6e8142746767963f1e4031a9e7ff72c05e1551d2626d1472dafcf890c11f1baaaab1bdcff02968609f6f4154a817867460ffa14261ad963b2976cd6d9944338acdb4a91c2a15a421d577b1f0cd6eafde870d2d1fcd8b3d03873bb113f133f2165785cbb4ec4b99137a4dc2db3313338c4bf136ac9c39b4053ab91a5017676f447a5ca720db1c5f33ba2e0203d82562b9dbfdd0b5464cf411a4ec39ff798b2abd5479d68a18480641310eb05c1fca5bf8c5132330c5c54bc23c7913e2b315d9a8271db1b621b500612a25e23482623e037b0b6773980a4275e42c137330ebfbf721a39196f153b0328130c0b2aca7467cfef01cc4dbbf9a8a0926c340a58883e4b0b59b9afe62a8c62d08d18562a4fd95a6a3d70dfd90fa1a15d6952d83a85dcb3ab079a91ba67cbff6775082abd4ab25e8feb4e83857e5eab021ae8a4505dbe7a3dde2d36aa0ebc508cae1b49c818f5c7165e7ff39a473235a75a9b2333e588211d0ef5e7129d3986e9e0213d2de49dbfb62daf700bffebc1727aa70907b77e8cb713c6ba8cad1f0d0c800864d208c935343fdd3740cfb370faac2a80961a0f3b8b35d0447005fc0e82022d949031d5062d4f8aa744cc623c4d6d671768c62cc023a0a2461b3988214b8f215ce83ad729227f4a3400be99c58bfabafab8ad4af06c17e28a10ec8f8af06626e1454f2963138e56c19a4f6ac189a552f48179a0605425fcdfe1ca7a403cf2297e9a7392ef35241d75085a64983b8d68eafc54dac726b6d84a94e16874e0860c6f472b3b0981400901922b07f2fcf01a54c30cf6825b20dbbe1146991b852c1a9a6878a7f1f43af6a26a880f0798ede86d0430bde95fa493eb91880e91285f2230058a0cd7f392a407d2058b56af8f3dca57b484ec6ca4526ee5e1ae36f79401ac6be0ec199215cbbb9342f6fa48ee5fc2079c21a44fe98d901c0c437ded112b20f9e1d14722d0a1a6f8e3c5ae5542b664e996bbac6184959b6007b43d9c960561005f6d238f5d3bc6ce60731faa20b64e59ac0cd270533f6c44cc6e9d5bdc057500afdd58bd889de4b82459f36be31db8afb91574243c8e1acdb67828f1e9183add21c8cbffd759306175151d5c4fa4f472b2b75c86e3e25480cf56c48ce4141595fca7a27e81a3c41d623170d54577eef77228a740c5f72b306348fb220d2e48fdd3a7d964de9ba0cf246c99d67200ee6e340a0c8367579e674a4a5f33512944c67f47c50e3570a3b47ae1929539f12c92075d326900f390b576aeebe9e6094000860a65184372332c28dfd700c53451f69568ea99c67309a4f07fe9965e12ef213d1b038709b1befd318e147d81e508fb2bdef04cd29f9a67fb0d4a1ee312e3f5792c46144ddb8352c4f042e61ed5a9a3850fd9850c9c7f1cf0630b3a6a1ec33bf3df6527fe4b12da199a1e9f94e31021debbb6ffedd6f10b71a1cdabf91e082b655ae4cc1d2e1b60ab79a92a5885e534006c0bbc303120f2d6824a10f10bb91d471511c9c24acf37c1061aa87aec6cf9f3660ba178576a0f482364dfbd15bde29fcfe07eb227db46d853af20da62ac6469a7e96e1e1d423177fc3309ad15ac488adaa1731baec815d86b4dfe6804690606a8822238f26b3c16b105dac12757991e46ac2def906b4a5ce65aea1d35ff0eabeb4f0845f583899205f33925087b24680062abf2bfacce5706551a5db92655b0311e8956ee3bc0d8a34b4a83244d664d1f71d3f4f807e7530c496f3504363d1e2462f35204e1b5fd4b7592e318ed8d0ba6c6cf82eea8fe98f6a3bbbcd3ee9c6c7672b4cba6773d47df0686b3051385b0d91358f0e9c73f6e71a93c15342fc46a0aaabf3379116dd12f95a2e30f7168937816ce74020682f78f0f15a4eca7870bdc17d4f0b36fb6db0eba34a517d878fcfe8f2160a608e9872198e628d47f55301e95e72184f9232b641a9f7a061c56f08d53de42e7f013c1112f76d21023a517b7d31548c2eab75c92c8d8311df000ef658c3423d9a2689069ce94d84a3d4f0d22781c03580962692d7776b4189c2722e1d652a5c109bae7de3860a66cc7b24d72860e3f43e9d0525bd21c9925e3b3e4130a73259fe1f10e44eef6a44da0dbe5f23dd48f8487f0bb7944f6280a507cab9587d26c812f6157deb1f312c53454e855a178d8282c34d93f20f06f1ab53520ad6cca61d9526c18ff7a37c60c431994b63d90fa5a7a16e4d34a1ddc0440c54904a6a94980e95c17224c4729862a9d26e7148fcdd79479f431732ed609664b7264eeacdb27c0400293f46c5e78edc80fd0d329cebbd45774ec88a46404c02b85d4ea7fd4ad0af626ef8268dc528e42d88c78c30757b285f07d2391fc0a6b4b8a4594c528d07833f1799e521fbf56aededc873143d5e7f027602e3cf308e4696ba7074107e534a1a545a613362eab5fdcf4a7e24ed0131349f0a138ad2d06b11d96c5b243992d1043952d17c7c4e294863c4a935fdd19dafe178bdc722ab0484766b0df419faf509b15a221d03428158513c3976eb5fe8d608ad3cf2b288fd1cbb13ef5861622006944f60a12f6bbf6bea0716f0814994dcba71de0f002b63902f9a23d06619abe4bb5eb4765dd8a51dbf12f94deaea567e45397211818ab423556e04576e23da8465df309f46b735955dae455c92dd8e9a1108a41d50e8efe970196f109d249c781077ad9f6454fdefb125ac4018a77e78ff1dff9c106f125c8952b7af0c9cc3e31879428adbc797c0da2d0a15caebaa50e95d965d80f9e7ccab0c03042033c2324b455283f43230e429523ee4f5959abbf2c434df007b5f1d715595f140e0c8f40b7ea9e7421d20fea459089b89dfaf43f0c88551b27a3e65b3945e380221082caa460e084b04aa109b767292d056c9ee9f33d5cb10b1b1f59a0279318cfde05d94c06b3fdc481219467bb3bec6bda69c67d53ed402be155f263eee937cb54155b12136a89a46e1734f4deccdb583e7540c400dea115a04cd09b2f88dbf70ee025cb3683b16c9e4243eda18272a727ef90ac558262191c9cb273d4f774631c1bc62857719ca60acdc1b962c2c94e43fd2a7fa99d5f0ecd0b58485875e38d85a12f1ff83a20691b7990b0fdfb562835c47435700ab01f5cd6728582866d6417bdad24896d682f57327f3f357f92e231d7445a88e8d62a31657804bda891fbff40aebfa7f1998e0238556c88b06cad3e4649fb8ae0561742e4f0a5470ff1d960765815806655e27dc35a481884aef885816125ddc6eb204e45cc9e3a72bf6baa8b8c842c5fa47837fb7f939bcd87abde3aabd1e81a732bd2dcf1d6945a33155ae5040e039f4873ac6d10baf1a9e43eb12078833541b2076327aa6d55a090b541f4810fa7b8884ea88c34ee43cbff40d44adb4fdbef702bb488a88099a373799583c0cb80dd2d248b42ee1b654fff03b3806ee493b2720c9b3aadc29bf471698a900bac7456c00b3f89e208250d841ca24424ef4c6e3b07ae9aa5a00ed1f766b7a929a6de5e3a70dbab9c142a3510bbcf84f88c347400197ff4a9f7da8346713e664a231959802d7a6cf75c2a173c2db344e6d4a5d56f14ac840a76697737e218df841fbb7a8f3f08513b3c542e52cc31b94ebdc443d1078b4decdf9a75e95e8aba608d33431ec59b57febae0f555880e116c692c2e9f1a9a65de6bc2837c768c3eb51683d2847d094b175a879ed511e66165f1de8abd1dcd23cac7c1ec82d9a52e308e963a77cf65dca0f0db111d46ea30706015beb00ec729304e0794895cf4c9ffee381b9dc4db3fc4d44181e018a6ee8000b868ef0f6160804464b254d14be3559d4caf9678b5de7b7b1a7a9070d0cf44ffd032e70fcc92e5bbd5cf184b555b97e34c458f87a09abe6de3908048bcc6f5507a73b2223ecf3d9c29f17f00bdf6d61e208cb9005a768db218320e7e978fc959b55e7302ac695dc17885a23246b49bfd619e57d49863161c31abfeaf8f8cdf8833eca414424e4e8845f127a575087d5913b89395ef2aa55d3cf8b3b483f396b713c65a0ba185653e2986e5115071a047fcaf0ae1fa19ae7b04081b1310982d392383bb222ebfa5ba52744e12a72513e438cf6d03af216476c26994891acb28f59838741142ef12497861ec13abc8acbb2466268e8caec8284202d03fcaded555ed974b17d41c330f848d0e2f1b5a9108855768efac063c9920ac12b6a879a08948d0f9200ef3f75da5f41b2f543761bf7d0d86e56cc989297922460db73a03ce84ccc4030fa70397fb5ebc5cbc8f6cf421f23c44bc6189df836d6ed6a0fc78038a5a8608036e674999c34a70fb35b8465c0d6758728acb8d73eabb3ac644d6758c0c73296083f3954c9432d9ed6c71996b021695e7d65b5375b2895a334009edfc2a6919cfc3eec78ad4b9287987f1299da8bedbec20a505cfdbb44723d4bc3cd2d1fe12f00b19849d6f72a610abe23dcbffc8ade7ec3bd0317af222b65c7ff5b5495220fc13e5cda3fa09da3f95fe2d8d76d6e5445d3dc1643b9c66b9c7c8107ed50a0a29b31e66402fea924c509767ad063dfffa4ad6d54d7f58544f1bc2358feb112f8ea19d97c6eb91cb5f369ad9b4107d899d1cae3e5c724bffa48b87ca17f35306d3812384215d1abf008a7b907ad0858d50c125139dcffeaba4361b7f953f6a03f074cca6df53e91ff16c78827e83f0ee880f4f5195310028394fa5c5f3ba09186284bc29f4b6e8416a138505cf499953a2c6c8ccf9a564873d76e865c9910a20d228283e2cd33fc3f56c013a8d7d07716f9d818dd161199b436dd88262394d1a87a38a541a85f8b7eb998dd13fe030b3724d081dea153fce02a84f5558de530c44755f6a9881fdf2e0ace74e8717b9ac72bd9eaaff7885cc06859aa9aebddf0ef40c17f2d1a683b99702ad953a8ca9a51ec84692e1aa88ceea09f4bf605ce20b8cdeda1e3a28db51fbc731c8849bf745eb4e8d856bd9693e77980f418550012794cc6d95b22716d9afe4d185781264b1192ad706040d0e15d4821e30e08f34048456ffd93f3155194cbd076c24c1f5684354f0739143b8211d2991f08e454427e459b107a71f3e0b5f0606c9daa4b4dd3fa76c853bc858ee103e50e7faaeb02a3421bd55fa8a9e287bd2e05ee9a2084aef08260f837b4c3013fe8e3f6cf9420fe4d218ce62b4da5abae4361e0e5e97561c9d68188229a44b345cf28257cf8f053e9f953d6e47e881c8cddc7c1bbfdc923ea870e8c241ef5e7902e730fcf0292ce2643a1ee75a36fd97025cc20e150b3080d378d6046ad87a77ee7263472719181de493b6074cf5a8c4582b691c75bd21d7affa7719d90ef574240bfb654be3072740670a8f778713f5e79fa0343d7c94951d4e1dda38945c1f1c4c79b0f46b1794adf40742c52f886c76405a4e43249a6cd0ad084b03e2523c8631e348666d2f48aa9e998b93e0e25dceab0e1a7ef1a55f7c65f19211cee7cc13f85450317d0b12dbed6276515724929d660a69001e89c88430b48d4aa0c27214317d9ae2931b35e51fc52919c6c6587d109f3ee90e3e0d362188a26ae5ce80ddd83b702b7424ea9db01b49731ecc57445d651091b4bbe3d1bc220b3e5185a8d49a1fe80a831ea7e2fe521e3e04fb11b42c2e4a609ad6015bedee86f0189457819e71f14c3627b9f45f6ecc3447684d160ea4ac997c73642271ce1e6a46ecb8bde88038c39d123f4959a78f0c8007855cab251e8d3da4d630000ecd9126e6833d63328a24c422fc59d9359e12dfcf27d0c5f0199b4821e3cd1de1ff163fc49a9df289a9974503df73519f1552e44e1a98569af102affe855d8f39d6a34742ab7064c82c88bf08e8a01352a500a36f795cdc0b4037aac666c88bd9871982bb6ff04dc88a5245039e2ab2ad19240ea285951e6177b10884632b34fad1217a07b38d550559090520a9e1b863b056838b479879f1895435aa98220a8f9a6d76db3473a6d3847f65040f7ba4d761ee389d4da5f3413232a7046c0abf5070c8b99d88e641b201f5da1c9afdc9edff2bcdc2f470f991089f05dd50150db240ef0f642d811eee33b99129b73f096d8cdddcd5859c0d2e197a96707b15cb6b3702c6682907c8688922ee114ddd36d9907ceb5259cd5bba0084a436ecd1642d23b7f66c6ce0c64185c7d8258c977a52178a57b60b41ab9ece7b84aae11bb5950bbff2dacda0d64240fcb40409ed7a53e69477d230f149529d3fe6428682453d6251fd921c8688547eedd51b5c68844880751a48612aed8826a37576d2bdd8005f765ac392551ff70cde90073d7f0b5512a16dd2034c1376a4080032dc0abe900746558ce59dd2c4d231a706d2665067273dde3df674cfa4ccbadb598f42e13e846fc4a22035f9b854af3c2500eb992c01097039140dd976c37dd9fb5be240f8f89ffeb634aeea48d28b8c04660eceb21c793218ca51e92982bf6e6f26922df5298239c4a89714e8a751cd02a659df9529860a1514f1a38629a5873ddd9b6090e6a39a042002ede0e9cbc9296ccb230a9bae17171ba4ef5cd6001157c8984f129d7b7a851066bd1fbfd5d40418eb076677587b8ad3f0d30aee8b11a1b309a2a4aa67cb340ffd2c851a80ad034548f1cdd55bceb68bc6d92b9b9d2a6e0fe0df3fd0bb95a18ef580e85c6b74262443a276a822babfcf27aae1c1c34816f3ebc80506330c8a1061dab2f6ac40053a62579fbadd88d3554c4ce5b6831fee23a3a531d1ba63e53bca00bb43fc391d63f59a67199feda087c1165c1d5995d0720990e89c48cef7b25de004fdc9190a298c67c460d776b1841fb80ea780f7df5acf91dc80087a3ab194c2a97729c024e42668964e26f5375a7fbe24c1520643ad2f349fcaf537c48bf433f5b9a45b012ebda2247a0f0bbe48f1b1d0e846714989b47d6f92f0d88f5c8739a31bf4133023e14fa286411665dc848f4d58d344698847724fc929854caf1cde8ea0d09c07b9f92374962f73f2d1f40e3902cb7d56b15e7d0eefcb961882c0dde1878b362784afc69cb0794f0fd51b61c1b9d03a02fc47ae558dd9f4deabc27b59977f492e1614d7e474614fd8dbee719e0f69a2f0ce128a6f34032ccb3c35f82d313e590947f4f99ea483df92e7639d67d072741304e8e0bc74dbd0b23f3cb45d85a3bb26374a4396eb3b6a4c00355fb8cc775aaf6703f201ff59b1b4f27a182df262d7089677abe9ae5698d33b15fb7d4dd4ca5c3d907daf4b549e07f51ae0b484c99614a72ed2a0e63935ddee0ba964ae607aba417e84221123ab810580d225047f4929582b6a546e716b2b9c090d4b9ef3ee96ae81e494a5e9adaf4e9643b9612c332e3cc93d565710a48f6e2090808a46e14fd79075d0a72f700e01ecfc85af725a14440a5a40c1004d11b0332ca006e574f5b101aae2b380d39a2a74073f9506bf2e0a6db9e9d44f3c0b34d8f4691cefaddac68fe1f4b9217b8da1ad1c6832af7516ff283f1c24162d5c9d43c6535af3b663c8f6b317999b5a467360cdbc798b621d6450be808681e1ef26c3b9b41b45b8f6ed4a6a3595a19a15eda260e91cf4bd27cc6c4a9a88936d82713001dfb2cad647702a2bc220ae6081bbbc13c83d4d4e062801150d72d7e5118df025a8358f40f4210d7ccd0c64a724bfe36e0a125e3f2f7a19d5762c83f155a224598217f7bb4e7888d0aa934e3093280e049c77787906ec5f65b531dd8523c41c007152ee734bb9f3b41c5ac053e08c2a114b7cc8570dd2060156591ffa67b27471a6d3670e9084e2723e81f98deedafabecd6903aa119e5a8e848c7516df9aa6642fe93d368010ecca14808cbf3b997b04f3bede532447812f18f9dff221fbe5c04e44c2a574bdd76c15b1f60c84093c165abd36b325478cec46b35db110fec226147ac00e55ebc8c2d694c9c5a5a94fdcc3ae9bf905c8a7aaea5c51011c79bf922985e92c6e34eb378a308336dfb376803039ce0e234d2d8a3a1a0ee6b3ccfed7b2e36176bdf444da598ba702c752e2fcfd2e98a4", - "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f710ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c9904fcf7f4ac91f0dc986701c89901fb7d914b8da5dcd57d430d860c3979baf98a" + "proof_hex": "0x0000000000000000000000000000000000000000000000050171e1c76882125000000000000000000000000000000000000000000000000cfdf1f1b488062f1e00000000000000000000000000000000000000000000000f962e434261b37a730000000000000000000000000000000000000000000000000002e0e72e3a7169000000000000000000000000000000000000000000000003632118af1fd3861600000000000000000000000000000000000000000000000f3be15fa21507e979000000000000000000000000000000000000000000000006da62c16a519156a00000000000000000000000000000000000000000000000000000ae34beccc39c00000000000000000000000000000000000000000000000c2d6c29afc67b101c000000000000000000000000000000000000000000000009cb8711b402b7afca00000000000000000000000000000000000000000000000433d081100331cf9900000000000000000000000000000000000000000000000000019240d6a5f208000000000000000000000000000000000000000000000007b680e3643ee08d4d00000000000000000000000000000000000000000000000db2f02967a31b6d1800000000000000000000000000000000000000000000000d8224e1aaf3cd44a90000000000000000000000000000000000000000000000000001e3e986df6e472a988fa1b94e96b9bcc842e1ec09ad2835ec6539b20a216d94832710f34e12a11bbedba09154d4bdb6ca8a864ed19ed0dab77199001fae75d996691767ea956b04a0389bce5a23d5fd869aaf9c5e5c443b43b84c5b41d4b2a0d90188989c511a145d2197e8a1f835404ae133ba729ff0f9e5db0e78f86e967e89a28eecd299702170e094855e18faf9b08036a4ab8cc8451b9e96d4a3e4ddb294ec58068c86cb28b5a272fe283333c466d2b063e406c9b5d5898942d5c60fcbf13a28f333c0172e75ee97db99d23fccf0100b7e768b832f63913b02f762a179772a656dd7f3eb102bf5c1f9a9bd5ca2c2ee9241a4d4088f679221c0288326ed6fb9262962ed1b10bae9d0f25b5935e7684a6e3749e9cab8e2c12d53e6d1d284267887e58c05da28603176d9f1ea891e633934fa4fca7ffc9161f5a3838dd02afd160b0233cc2f1985db340cca8b06e4ce20fb357bdb4ee18bd32fd75c0c529e114987992e62c31533f35e6e095dc8e36fd57bb8046002ae0471ec3fcde36bef53e375cd0f3e4f191a2188d3e9a6fb82792a50d4ff1360640275046de2c21d4f4a3577e8f79a8519b47cd6be30649c380eb4d735707b1c664f98421938cd63d5f656c6eef8048b3001073f0fb231803649f60355fc757e41658a95c817594e1dafd8c2691d24f00bf99821e74780d315f5c5ad75d8e983e6d5085993e102017a72b2fa266960920a8e7e77a2ee6d59d798f12d92b424782833dbc7d235ec3e43373ad3e404f1cb1e08a2bd553428c3accdeb393846323c7c78adaa32f740afcc9ac4d264b3ed09297b45a3413e22cc62390354d759b264a96544e1662be66950fd42c67f2dc79c046b48d8eaf419dd29c1de1171719708091ab038efedbcab7ce18f60d73cf851144e9914268e22dbed233813cbb531e7cc338776a52b34c5b445336a93a82a3505ee10cb945134e955f56c92798fcfacec8ab4312b370d08ba9e13c6822f7b2b251218642289c021af15cc46ee027d7b415eec7ac6d8701d066c7ea7fbad0fff1f44ed8fbfd3209ca7c67443b852e7eb2153ead095fca5a334f74adb331a85071d37e4d8fef5c820bebfb6f8ef7cbbe9e595b09b923eaa754d813eecb8b431b6252e189fa9fd09540008f1a366d44aec26b5f3d6b88219b8acc0132af1175d1303948e2483093e739c7657de30ffc650be6016e8b7b644f1706af4f10794917723b79318a87138a13ddb9ee54f5a386fd236ec981a583a22c69f30ddd9d7684e2cdd842c10629c9b803f04e709db227ac8c2618b2ab90b7e272e60602fea839906c91883e1ba386f54311b5f8dc3e654a0d4ec89e0e84c28bc6de587d46fcda612aa42f202b2336dee7da1bb663559552831351bd8506a5e95299a7305b38f87141a1d53d730ea5f7e8327f36f8046b96f06be138f225d542397e91de2db853c118243d8072071c8c2b6c9b8319b2364cf2058d3ae62883cd328faed3808687d1e6bcd832417a660a93375eb3b6949753531fbcaf3e9dfda64319654db11377d0d30a54dc8104f72b9ada7db131094a3d563bda7a350f045ba02572b53152c9f0b81b3d85c069c07f10b478b5e43103026fe9054094913d3939a7dfede87684e2ccd8b577e3eef430358e620b504e70597c6fdef4fafcba52e4ecb198fdd7d7e2ded4feaa5e0f4e46f5928eb7cbef54804310bb28444bdd8db0c2aba73c31c7019870268b2c4ef8557b3adea63df71d1ab57662ef45b9340068707f834268fe72215eb567a317d10a1184f97b55c41dedcb2b3fde60bf5b36f8db7ae9a86679e033d6ab5ae65925449813af86b5ddc4e84247246cc5979716414f6543895abac01e65a1745a512cfa85259e0704601b4e96f4fa2acb1810d93f6f5f7c3c3facd28d37db2dda672619c9a74af9fc8590f1e019816aed3efd4f2431c42aa49707f2bc202af6e47cd30525b3176d9f656c8f38188e47b4010e170a5c9540e8d446907662106b2f16ebaa6d3b31f76676b63b88f6b5f201fc55b64fd485a05dc54e82ea332f1cf2a5e4a3ba0fb92db8a4e2582d696f0e3e9544f1df54d2a150928a21c64166a1eee5a7acf0ca354f1ef2c597a915abf5eb1f2f17f4444a14ab73d25291fd606842f6d46c423a3d5002ad5d1d85e8f2d5aa6facf93d277e8ada5be2d281e1d086b9900f04949511c28d3e5e5c042336a9c38d499e0d9d4a0e22a011c2c1d46ab3419b71c538300bf07222fac1ee50f30f59fd1606b7a733cb89d47c01f240b094462a58c6a48f2f22ea0c311cf71059da4b6eccec988af99298b19851a03b84a54289cd63995596220af919f2ace0b6855f018780539198fa2b546722a38ca2bcc9ef20fe97d16857bc21184cb8c26ca77dd0a48d21e63a4d2e309941336a5aaf3f8d884fb066e1be202f0a5824698aedc16b097163316f2e9637c3e0b20b792a3ce06ffaccc8c01feb75db6c1a8a5f691fd6f0457b21d6f96014d97181c7e28a5e38a313ba81781b44d944fa5180921b4e3a685c67e7b5ba54522b12067ea024995c2b4d39a4378e235bc9617cd45226b0b462acc8268376f09ded9148ae0c2c54cb0572c7ceb489276b6f9865480d1328e52c20b2a87bb25f8f8fe19c2f1f9253a2f9d91ce5f306a71365388975e901501ed2061722b40b39cc5e126be39f84c67f5d309093a230fd41635b221b3a842bffc6c82b439bb4f30c82a0e455c77499e96fca527260c2387b5b33a342fb731983cf4493ce8616a7a53c020b4cc0c3be0b632c8ec769378bb66387a1f5aef060a93837742564a44d13f722b3c33c50977596828429b4d9cfd84efdebb1716ad8865c2bb0b7a428dbb76a510b3144751ed6f56f3e4a1725894ae0491db526f33ff61610340d0ae06c3c2090a090850b2deca290112c8c9ee587277a28c6783c18de6edb089175f09c0cba60ceb6596411449d0e45ac2e45a96fbccd16876400fe6be3abe02546874f1bb2c02ee37e4891c999df82ab2e71bdc4b8565e904d46de6572a8e13bbd57bbc7666076ab48a848eb008f5d150b8f34e2950e07418dcd2ae4d4618bbc20d3ef16d280e138a7bdbc01702cb05e90d7216c66cb9f4ddb7036ba9a8e490c2d6706f6ac61e64503d935535e808a69eaf53e3c6529734aaf10bf83f868f942f8532031fea1b8462e093707d67a47944a349411088c6642cd6a7686fef5a7e239b0697054c11236b5d3764b83f9a409821ce9b4b87bedd5ceb3f4fe6afe7a7c894738d1c35296c66c8d85376b5a864281a54897b64e90cc5bbf2778ab3edf83387c80734661b77c4e4eebdbefd15d57a22abfa5662ad616b857f09acc5f7c03503dd36f569035c3c9ff43a306932b0c6921ec3ab08210793ff101a1cdb4d52ada493df83561c674eaca29b3732bfeb35648633817b65654639049f14ed8eab71d7cadc6a472d72dedc4c511dfe6eec2d6f780d3cda952417d70927de7c890c822180b751cb22efb494f2c65804b31df2d6fc8b2e02b1c3da3f32183ebcab8662f9dec0b9db27970150805f57492628d4f2e5cefeca33c80f49d769038ecea2193dcf848bf626721a1fc9537290fccd8957f41fea37a04af789d5a699ec186f0c5195b9da3a0d289910128a71cc047bb54a1a2348c809d62257a294655ff515866421c786c31b60373c7229263449b97139a1e73d1632c5c655a5298e01e0d93090bd458b562571a3466918118d55c7653f72fabdbd090983f3d374b657938439592f27e63519b3836279b0887e21105c5b699c6402bf9926c8774566b8696178ca6e6019d60fa85a2daf85687adf80a426ac4b3280a35fa0a03fdf7caa03453744d3c95876267ae5a2ec7cd9bea56c9f4791aabb88c44f77aeb2be859b01c3e657343a1fbc0301584b569bb2677bfe761033251f642a36db5fe7a900eda00a899c6436b3552257ba5af5060156dc3cf16a744e6bb61f304c2e8b882dc5d920a2eae4e5d8930a12791bbc837f109d715e94b6f43c0ea0f912edfa65b296b79fd2fafb4eb80d294d411f94f57fa6561c81af4590e4f64e246346c585b9b1825e260618666d790d3976646b3eaed0b62adcf8ca1eaedaafa642b99b0c668fb2ca646cf83ac831284183eaf859b2dde29a5bc4ed0fe1ed9f3b3e4b66b5b1b1b8e2ccaceff284570e94b8e30962aa3f7834b8ba1ea36a8ae66af7c05c9f26ece5af36d3e62503790341dd82ae3f277043cdf576765127e8b1ef261938dad94d9253166b12e3012a098cd13cac7440a796ab7cdd143141d75646524728a119a9b8b7a6bad74992b229f1da3b792912490932d69dcda2f002679624dea63b05b8a626d29cf0a21e281008deaebe2011441e2251c4163f566316b754bd68de1e29d872314f14c98acf06c65072574039e59a4be896da9457287d943daa8124c8112cfd53d8416b5dbe2389f9b0e142bf22bb249b8a65aea8678c3f8e337d8d01cb053da0865c48b95c2a98cf96bf95776f89fe16e6e735b6ff6d77d65b19c713ad94b2d833e274b28a1d83ecb08d14c57a21c6fc084500a03f20d2f2f4e113c6234631c4a4c862c8452d8619e2fb00d51f4660d7eebe5d0b485331281e6e4fecab05ee5b39fd5a576007a02effe3276eb44bc256394bb45df037d31b8a03d4dbff274b7d4dff96796329900a5f0ddf1afc22b52b45204173e66c015f00c263df12c81244e6aa531df60424de20721c938a170a8ecae4ca005937a20beb47b21d5114dc6acf93ea1612242dc85ca47576a18571f7ac8619b4ed0fab62fbc14c988ea251c175ecbaba5a2120eaef75b4a23de5516c4409c15984f80e7a2754be08f8d8a586921d36da642bde79fe59910f9c9dd77ea3043601e017b911b2bf632d7638bfa2a0df8dc4a4158571fa1f23328c3780dbed7d136816beccfc88d346a328a9b5bfbeef4bc0ce04edc95d456661d0eb8b84b5f49bd166423dfe4e44d292b5c221b1a9249bcb09094fc663b9b1a33ac12f371616bc82907844262a4257f3b0f30494ec53318e4208e1927d77cae51515142b0379df332b1a69430dc6b1faac64d7d5c4ea9b87a71af3ad9c2c137e8f0720aa216af2f0869467dbaab2593db8e98a43a77e2c688e0f4ee2b6e37d294f473cd9933f3ddf4a6ed9b6c32bbc46c95db64abdc2c665b60f30f0494c32e794f78d06cc07204763c577e6ea2807cd9129ef13c0c63d564026df11741e1c38e336332e811beaf01a8336ce345ac7558d23ced7c63d4f7a6109116d2f26b10687f2fec3bdc80ab96f9d6cd940dbba2096f69f4cc07cf9b05007073bfce2438fdc73e5d2187e676f286fbee1c9ce169d1ca1bcc3a71d5b515a2cea999f3f4b8b2000e1944945a0ec5719f2ff71908c8903f2ab1ebf811139bc1ace82e5ed82e865146a52e18acc699d0583a4b0b8469387b04045acffcc9b8a1faaac1d47dbf656c92156fa8b864b34d75e6ef4e7dc75b031b2a6f48e9eaa2d2fb3c68e3adbb2caaf732d6f6ea726b8904a855196a864e5a2f835935b51efd00bcf1ff872cb1b4135fcdbd5d1e96a7a58df82a1a2ecfcbf69f5c0a9c093333417d3dd49754668e48b033d2dec98fa0a2adcffa47985e039acc5e49d12377a9f0271e8ebd87fb374d9f854def3b254c1495cd5722b58cb04b6da4484293adc012b3ba3498c119faaebc4d3d3e7b54bc4ed8b68415797a813ae76c4fc43a7818008ad9f53cb63132d925fc1f285b75966339371c9447b2c45f9610fab11b15598273da77731e94ebda44ee2fb236383a0a0deeaaa0ed802dad3b9cbf991474c9f012afcdb34fa6eddc42fb1d2599c2b38fc70c4baabf6d787bdea3ff8bc2cf9631517c0ddbdb7ee2e008622cbeddf715fdceff1bd1aa94a5a280b1308b9751304250c62c27c3989eac079c11f437c3414111356ea1d7987befc81438ae97b6b632e61faec19757d01bb5c31c78b0c90d26a3b71709ea3626198c5562241b226cb1157ee972eb53a12fb593b473df72aa843e1450832cfc721fd2fd7f037c1b6d4263a464d40a4302aa2495b9d9be79915f656fc201bfb43f1e6c11fe7acbaccf803259bcebde2dcc3056bcc63c53d6b292095447edfc39d783edaad8a5e798f1728c64ab0b1c0489089ea5b8ebc7b53209ca084d722795ba667a77ce7f6b45aaa17c68ebda1440c7545e684bbf9e648ce2fb4c2429968a2204695e3e28b1b6ae90b2837fddfb5e70cf62e75c6a0b446125f793cbfd4bdf28d9f6b99da1e276ec12f63b8210c9faaeaabff24bff05d89539e3d6753a5d63ac9c8d6a05482bfb13e0fc8f6a95809478289e225f918f6baf43748868b25d45f846e604fef59e5d00b109fbc8e63307141368905dc9d3d0d0cb3028d7f778215822a3fe943c1f746711fbd74bfe4b4189f88173b2223c3c0266b82b6ecdaba2542723592c530aaf2301a76a882bd71dff78c2d22603790c9650b2e1e1170d05125af5d0a319d745b2e149f60779eca2908fab92f744af749856fe553d3c6a29651aa82d2f1dc8743a8171861bca3e373e295d7ad740a458d2e648c1d0172b1fc6466fc2e6a67abb97712a837b4085cd6a5c5447ba344c977d514eec63dae387e57bbea863222aeae2f17c9f83f0915c8437b28107dd00705f2dcccbc6b5b86c6cf65e7b67229bf72ae1ab5db1316dd37ddc470c48ee9c01f73f4eb0a5a661939aababee0eb10cceb7f259142020f2f2c2cfdcf7e1a73a9788ed61dfc804d1be7e5d2a6c4697a5b1d8a0c647fe72135aebf86f18b0db90bb6bd0ccc896829725c28651d7e1307fcfcee2f4cf4809ab83585d0bdfcc0b7f11245df7eb373b7639e41cd6947e49dc05d1d24e93ae6b006bede35d521db286ea335822967251ca8b1e75fe98c6d323a52810912269918429ae971037503f97fc1930fbba65055167a1142c4029bbd13815d298a459d0d17f83607b8e553b645b928e12a5ba47c3a29411d4660bfd27b522d2238834c52fd7d29853a9e34abfb12528f33fb3d27618e6da73288e1a0ae3b9c011810f73a0e7f5e4a53700d0486e2c7b89210ee348db7ef440502b39a6cf72e127e0a7f12d0b42ebd927e5f3c91f306c2755a4d4870e0fd4145c4a868afae772138c4188bcc47eabb5c045ad1a6d677212baae9ef7ead5989fa664cf1afd35e2a0f79fecdbe7b8023c60ae6f6daea7891ca68e8e995afca7c1ef6a39f24711e02416e6b298dc891eb5a6f85afdd0a44d8a071b576fa14236debe858125378cf160831e632c434b386866c9f6ee7c589a9b181956360d998d1e2ee3cf4d79e832ea36e916003c90f97ff0487542b33d0332cf34ae74a654da9e4e5a40e8e9bdf1651b3d3197f8097eee61ed1d6425eb1975712095712a5c7038285ee4fd16be228d77c66915e9524b9b0cdcfaf9ecd26b4b3f10a4e425f44480cebd3003b70290bbc5398f1229c4a19810868a35504068ac01326812b8a0e9f665d9195d64bd42397b246030c014d748e4be99065f8ea3c72c983aab168cbb76a70e6a8760bda15d4d22844d77f4323526f30c54d604c493f223f4a341675b2696e4ed812bbd81516245b2e5c3879275d6e7a6cdbc6b978064be19dbbb1f656d4c803aab83786302a6b5a5a43a22f99887ea0a812fa8b51aa8637e5df1d7ed5cd318fc5d00766082bcc1def74470c7a872302bed39e8e051ebe2ff94c45217cf79b2a4615a41c126eae2b56037c4399d124d085ebb06d53917a7bd73c1413756a8a78125a64c4227444263469b7b5edb028c7b98d313831c93cbff689080d1bdb6f166644284b25e9704af7c3ad31b34253207d2064f36eb67cefe487b6fae26969b8289ca5290953c82bcd3454e8ba7bde204b4f5be3e8b5afeb15bd8e20986fcccb93d08e8825e988859679b51fa0f938c7476f55dc3929998d1761c7aa25e390caf801f8ff0fe2d77cd8755a04a4671dfb8d0ae1d2e917a66802e786425e13cd695a631705284bd012acd166ef99c75099b6f603dfde93e2623cf6e47753c76e2f3d8ce507298f3e71c7340938679cbfe5e5bc22a969f08c3372c9c084c2636a1cd76fb2e906095782c9c1a9643c968d0b146233a57ad730d77332c10c8167cb180dd3512c24a02e872ca9f98fbba84d23141cf5d66207f879a928bfcd22e5692396ddc80c2b9b1b8b50b8de8cece0a17d3c8ca30c36e9cdf045e4924494d6c99b29e929bc2d117ff452edfd85f7c4adcd9cbbc8a3ff76011351aecd157070ff978a6048dc08412b512073bb2152f681f316f1f0625fba865a9acdb19f3992e9fdca4189d520b9f5aa6e222057b464a80a4d04b2fc7b9f92a5a8667eab1faa27945e0081d61fdd29f1a7d5444f74f09a2f30044d16ef1bf6531a0ed6d1151cd35a1b6283c222185f0aff47c7e7a37a6fa0846c983103871dd1870824b8d18f2163da9bf2a70038b0facf58a67165abd01d21cf2429ec7153fac53e2b6e335142fd2cb3aaa02423e67047c73fc811b4ad3c8b452fe327d594d9e7e1d51417edef03990949db1f7e274080f76644ec70b2b6c05267ddb2d6c806e0966303c77105a1ff0aeba72558dac392c66ef60efd29a6357cc644348b8b9ce3c39243e41d3a107355ca050109fab6c07380c8ca191e908c144271b2b55a8490d28296b0bdaa34911268801aba316c2967dac2ada95da9e41c72427c498ea387de3d234e5d728959fcddec1d48b05c86337c38dc83ee23caa8079d5f809ab2d1f30dbfeaed4ea7e4b87fec0424d66e7ef425245355ba9994876e17000b875b53053eaf8f38e6937aa4f0ea2e8d25d8a5e2087be8f9392bd56e9d95520efbfecbe8d312e374bd8fb10a6dba08de8a096af917c4affc0b27e093ae6d1ed63b70b0b88dae467bcac39f7fc88c1a08ba9b1d4db0dc16e2df05e265019349f8c250b2966754bd3aee8abfc280bf03c7dcb8d5c003eb7afa191842ddffbbb7e624da7f397fe89f90b12d349826d807a2e3f357a0912d5af5b2273b32ec9974f43f163f2aff433cd805f30e26edf12f3a6d67ead33ad272e4908cf00568cfbc7ca9b12e9b15631814e547d6569d910866261e817e204b0410ba0fa7511d7878dbddd4e456b5aed444d8f730b5ced605209c97a9c9b775e9679c3664e2dd37ef7618fdac726bb36ac97ec093ce3a85241b49b290fee4fd53ecc38866dda42ad9e89d81512cd5482f6feba6b84d099f1e0d9d2544c2462149b6304394161e678132031158b1bd24066fd2e943adcb202d4136b5fce7facbab01cbdc9352aa2e773c8a40fa8fb735facfd70c685cb4941818959346ef51c68ebff31f6886fff418c58b64d22b17c70ede38ee5048c06e1c47d7159575e4b31acdf5e1132543dc1a394dde58683bf6839e222d0da5303e1eaf022ed8ff621c383856539f24839aa597a53329b6153c1c663d94558289991e0efd67c8971dfeeb6f36e712e835ca6d6b12cb8deb7a39e5686d0b7105d0f00aff977aaf69f9d045f19a01d2aeaa20d181dcf04f46f5557e34205686f4ef090aa0dc2f18d59f049b313b135c52f2a6276928cc0f11ab4948bb463b12ea9e3e2aacb661846247a5c3e3d349e822594b61dc48cdd93e68f559cf6d834acc90e728dd3288e94b99740ce069be51320defa30e03fb5799a33d7440673bb536d34817b1ded0cd3003019ab911bdf5d0384d48152312612aad122f8975d4b358bd2900dfb7e65ca31b2f7be187ef465777c278f670ddbd71deca7d5598a7b734913a13762531d2b2add16d5e37c92e7a1544011be58bca9f05750b4d86c9fd2abac413244404d2e8247dfab02c91ce8f4e6e0c9731cc82cded1c6527a844df0d6da324a192aeebcdd9f6bbe1db18a50813421271ed0678a8595c0bff9393ff84db4702f02eca84f25ca461eb06c310e1ecb75863860e47be4117884f075626c716af125b03ca92208379f81dcc34e4f41a414ab8b5edde232f8fc280ab049fd082fb2a8973bbc3e8fa46937704993202d184e17f80c74d3d66fdf28510fb1b1916ed1bc7414792af8f0bb1c5029dc468e3931fdcba416def99099cb00e85e695b28903636b366320015aeda121084dfb493171d0f84cc3708bb15a827b9f4f8af6782cf047a876096716594c6042e2c62770c37c86a6992e26561b4937be8deddf762235bd98c8a4abe96acd8f44943988932da6622c996564e8e4bd6d86044becb1005c7014222588fced532f040d85f21b694a4e940b7292545c9d7cc033b6ad4c1508dc7da02701d8d5c819deef613ac4d2f6170cab35ebbde63859a3f1a4397e24c51253418723f2a37e50d1cec94e0a1ea1e3f4b9ab19bcbb1fe320081e89f122d5592111cd83b86ca5d74db8aa45644280938af94f30c246de5a9e42a4e7c806aa4f6bbc0b40b66650fae09f068980329ee6ded77e255033c84f9fbe734bcd2bc175d335b3549a3567f0a5a242cee45c1d37f0dc7c0e091404b766ca4e37d40a3520a2538997773fad1285b4da877cff9e302bf838ba0dcef08c346bba42cf17e1addce3b129357a52ca15e1847649deb1725b35a6f92cb599de7ae5bfe1312cbc1e5327770be0eff878e8f1bde2a21467e5fbecab7290a1ede10b9df07eaf0b04d69ffbdaa12b51d1fa9522f982c4d89239d47f4b56ffbb8fd630b3e6636d257e22d3f31fd1f59eae4428b42fc9ccfac6cec11aff3ea7d88d37f45b013c340faf832ca6f3044dc026011db9172ebd8a50ab81f86db195239097ad5226b5fb07ae137250b94a651e40711a345ac56fdd076f56f9d2edad70356c1647853a562df655a338313805345bdc388451870364269856156ba27dbf9f013a86580a58275c3a0c96db3c6bd69e69c6627e8b37c77000cae86f388c855d88138a1d540510b7590554caf3b3ee1c4de0004826ded89c3c2d886255eb6c352df92ef402d404b008751a6219cea7831bbe590fb7484973247e7eed62a41fda7fe1b4c517852f9c46a3caa152a6ba19ed81d68060ab7de2ce648f2e959149627345df0af88013a778e50256572cd0f0db53e6bfbd0b265226056157d842adf904d66f68f5e82ffaf7d267bc206cf126453fbf97aadc413e8bfd0980f6d2e51fd12c6b8c450d22a7632ff78cda0c94ec01807bba33e809a36bf6d5c3e15a65d0380bfb5738f20fe99bcc5c24df1f7dfaaed12790f48d695d10fc94448aaa6483cfc44c668d2823977f80ca02bb04aa050e297c39a336ba8ab7392f3f0ea13924ba2e4cfe4c5320f0a6ad82e7eccc5de9b85d68ae340c4d1340b64fc691e2f6d976db379468c80f1a2f8ca7bd84540963fadc8241efac5f7808f44d7f7b65c84a9e597b4a8f820a8643ddc0b3bdc9b3ad0bb1c3af39bd93187e37b6adfc8acb7985898f3f7f08076f5a84e1f44007572f1cab6721c2d2e5ba74f0237b384b3d2f801cb2adacd71e00f0c0d1e7c25ef230bb81a52cfa718ab44ecaf68ae3cb224ccb24b78ab3f60e445b67fc38fb2b395346370197aaaac7517d2b2aeef97769479d46358d8b5f0737c3304ef4cb623a9edf6f53b433d4ba88f2a71de5a9560c0494de2cdb2be50b0b228b1051a2708fdc673fa6df41fbea855fac8594d675b7782b86d3fbe2d010a001a81c82e8de37b026d989c382b2a463ae5855553d2a2fd4fc239307dc2006cffd98ea7ea19c1ab6f29976568c0180742ceb1389f2b787525d75964aaacc03b7945f1be91dbe8b9671553c5390fc4e6b504216f535c8898e54e8343676c61faa9650f3b1ac01af6629a87cf78d157ebf2576dfd4035a5c94876d5c46051919c6574b57939fd6ae2fd2128fbcccaa43675804486b48088d076b167a6932c10094d9cd0a0d704ce50bf44c160e3a4dd947e18398f8951353bd2f7d10901fcc1e467e5ed14b5ff29adf1db4fa4c1ff120a9b6e96b2d96267b24de93e5b58a730355b647a71f8c66bcd9f005eae5f2621d4e95a0e8f0040dea08c5dabb08af7e06e3e7e082a4cd093c840486db4b508ee370979ec8e7556050b81517a42b7f5428e3e929a0b36862db159a17b53ed64e3b19824f29a4690b403e1a06aeccbfe523887a99b8bb389be92479bf4a88bad4e9fa0765e38cabe9b4cb0f8359ac291513e1ab0cbe99a58ba6fb01277bb092f76bf72ff69b056c808302a73c303dc03422672236fc9f0e0e3584834fb3e666af49172fccf5e62e37a5d8ef3c30eb7598053a03524e50e3629e114de48ff812d3ac27f69fab79374e24008af2c22ab922189f58e73e3e2d433cb8691dc28d394416c53adad6433b24c756158e5183a4c72b6217027bb06d3abac3724ff8f65085c9c274f4361f4ffa696c196a5ce5c06d015a4869aa4894f7f23c2c9b723dc88b32d23c7f7b17fe0d960e75d43247e3122149af32b83259e273124e2b7fbba33da026be409cd308e87b99fbd4dc4e3b1e2f82b41ef4d94c4833b737775282fd5879f57b19f814322fe572a1e83eff8e7c211aedfc9ad3826d4fd63e00ad3f6f5d7846c028f58bd97fcf048a65858a6f8d29d245380da910de6a206c761b8f6d9adff7ab770385fb81143e96c8b1b1b50d3038cb42e6627becb2b3f0e88797ec28531752945b90c789487c5d82b46de770143ddef2bd48fd0e0b784ce88b32b93672ff466514e73d0058366d015eec42d82ac2416739bc1d07425ff2cc7b40ca139ac01509eba5b9202e7e721a4e4d372e1e98d84308869f428f96548f633864a57b7eba50b38e021a6226e28072096f713051f0b0f6ccf473d4b76cd400ec3d2fde6d77af2fdbd7e813730995deb9066629002d655f6405da3e09e52f70fde13e5a8002f9984148df1c0ff041ce4a51150e7a76c3cd5eade0672438a5ea1d1dd22bf7a77b23ef9faf91d032eb18c6ccc507582531d1d7879ab921faf19cb135501352150dcaefcd82dc1ffef26d41ef2228297b04cc49e099ea7290257eb1683b9bdcd3bd34921f0ddc415d4e79498d580f340704eeb78eb63816c3bbcf6482e4c2ffeeb356cf808367622288839785f02da91875ebd91f8271b60ced8088c8c10e1591c64dc26baea11805b46580dd9f10a9102266062bee1e3e475b80079c900faf306e1eaf8f1aaf4484f0000ea75d17a0b8d9ac1d396615d1aca3af0b0a9f6a3d86f798679c129e6022522ac7785f06b97e54dda22274b7f6b28c57df7695ccba1d1edb1ae386e8167bd352b49b54168f0b01c77ef1e91baa5223e002ad97d1a77aa9c249dddda1aa025b72ed49a10ecd92d4b1ec8011ae096e6eef733c7e305304d9a68d74a7d8abbfbd3d41ab9d05d1fdf5080883cafe6fbbcc97a843626a9541efce71c8bb4a6b50323193a2002562b7a415d4de5baa9d5c72068d1442d7498990f218fc03b5ca506e154ef325120dab908552da646fc5d6c2d2978fb3cd67bbccc28980114d084481383b60ac18d9cf5316730c0a9d02e46596426e88c854b9898b7cf798420776e779e9c51a084aa19f2c753f3de4ac67e558a6427a04705884c183295ec6c48b9b6ffa67a4258ba74b690d12381bd1a4a887e0b231ee84077fe2797b23ea41290dedfbe00a2446b17ad57771abe27f3e448bb01b17f69e74a063a253c91ffd93726a7644b12442d70b8753689a11eb6de126041730be57e8f71dfb56179d1507ae113d480827bbebcc7ace9d7ad5a46ef018734d393e98333e8b9fd0f77317ea5bb2d594722e3e43c556d5088a6b27ff4adfc0c1384a87676bb2aa30217d642bd6dd2add260d88f99572949c86c1fa4a1332bcd3728986c45ab37c9ff6db79b662323341b9013fd43f11c15eca886b4d13c8500dc1d8df937dfb49156262a412654347dcf80afc2b5ad6847a049569a52d91a93b047a0cd0836e6c165a3337adcee9620a1f19a5d392987cbf44ed846c39e36581056a5bbce8d26af5f81f9f2cb1bd58b17501e80853d15b8f735eae9ab20741f04b36654b4eb0e485b28bf7786d4ca494872c8abeae9a358850bc62b4e248201f315885a1b3007d4ab32ce52b3f4fec9968137edcec321b6f4a62112e4787b2bfbd7602cc6005b7eb482de4aac41f4f3403042c688454034386ee1aab7ef75896beaef9e6d178f650dc211a4ec50aac20e43008a659f19ff1b3b52ba2a53e0d258633e091137c025085850a13db466755fd1a387fb0b270186e001651fb51e422f31710dfce6f3a56e94cde2e9290d0cd3d1aae40949d1b7cd01599182d3a7dcdb3ae8cc005e2a14e1b39df73084f84db292aff9b4cd5373cb5a58def79c64f8f9b124ded447ca83e959ddc955e02f5786c1257a84c5697dda550ad7c7fa446840f9c52aa3673788a425a8f39898b64223b03433f14358f511051ebef163691391a110b6b9f7700ea415e2fdfaae627af710e8fed12c0e416b4c0b58b67b6de9c7aa4f5f22177786fedf9f06ce3a94d21f5221bd8961a7e292e9cf231f57117b134f0a0760a6748d626834b1e96296635c430371dbdd772bc5fd6a3a8cc16a23a23ad590243e746fee1506a882c081eeb2d1806ec3878562fd5539690873f380628c189aabae6ecef7a59a33f069aaed9dd117596a9f33de6768546b01bf20b4caf6713d148cbad539fee2b5d69c7299e5c172c53a7974407ed9212b8abdc2f9137fb7c459806fabccb825f75c3c08c0dae23d223d74d5b5890fb1e84340b3916a7cdd466379302100aa313e76ad493093d1ea729f88743430d4b9de0c070ac5e69875be9fb9302edc0b8d623750b727137108494ca5bbe9dc5605496df7869a75af39b8003e759e2c02f8463f46e93ca04", + "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f70a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510fd2e0c74ac08efb87cf1059f1e30dcc9468113293de905e1b6098606e2dbcc3" }, "decryption_aggregator": { - "proof_hex": "0x0000000000000000000000000000000000000000000000056cad7c4d4ab29b08000000000000000000000000000000000000000000000001c619e9b18c75b568000000000000000000000000000000000000000000000005d70fe88223230f090000000000000000000000000000000000000000000000000000f4d3fe76e6b400000000000000000000000000000000000000000000000f3b1e196b01bccf7500000000000000000000000000000000000000000000000b6a2a87540a20bf3600000000000000000000000000000000000000000000000daa621f0595b95f1a00000000000000000000000000000000000000000000000000008d5a8ba7f638000000000000000000000000000000000000000000000001accc4779895fcbaf000000000000000000000000000000000000000000000000668ea7d6e9d31a1f0000000000000000000000000000000000000000000000044b0fb30c4478834500000000000000000000000000000000000000000000000000006bfc6495aec80000000000000000000000000000000000000000000000004f4f3c14746f379b0000000000000000000000000000000000000000000000088dbe00e529eda58c00000000000000000000000000000000000000000000000f2605405f1946fd4000000000000000000000000000000000000000000000000000025b1f866541452ef1d421942cbeb1c5cfb5397da431759d5d9a9c317d36a930660d1bc170b4702ef125b0f2c11c7a4326be8bccade5618401aefc5255a1c696e6e85324f1050f268c15d9ee4f26e41b34cf4f0d5cfb130caf915adfd5ba31f1bcc79825f919471d415c3651ca431b5f3cd654858e981efe0855a21b2e38d123135b44710f1cab2c035e4105d4bdd3529bb5fe9188da07432c5a89e76b8f89a6fa18f3529cc0bd0cd2927992356821b6e43d1bc83f471bd00bc8f49254474a4f608093bfed179125ae77567866514f161a7684c7e6f6655e7b13e3372a7134f9af19d9f684fceb06f4c1e272c65fdd85029c7fb523f641d823a62439843c26aa5cacb8fcf0dfa10446d9cf70618a9814cb612660cb51726a62b6e43e543cfdddd4d001513e0d9529b98f6dfe08ba29b43c0328d7f11c2aaa68a41680f6c09512906652df9b07b81922552a60c62d7866bfc580eee4c7a39fd466127d0467fd96a77f978a90deff11f53d729bdcfdf44340633294c43751c8ed5297483960c58ab9f5e4313a5e58037cc3e1e0d78015e20d0d922b7dc641a5d1ea3ccdd01925140b4035dc0576c415198c1b75ba202af61715a9e087da1e48acf524606b9345ba54bc72b3447cbb24b16a9c8665ed01f422f4fc43ce9b9b4f3fd06dd1e170974b8f58d297c6998219adee798f050eb69bc48e574c8cc88e5f54a599078596ab2010dee8ad7fd671166a365ee47c4303fb7f3814118d649b5ca3d5f81e8532255ed0a010c6f264b0270b360e011a625807a323e92b639d9c82d3ab7fddb9c617a42b341b7da8cc8f2f3a68ea0915dcc62b8ac703522c1ebbe5530bc3f347537fef899406586e07d21d6e94d5208ecdf0a86971102ce7d61860e0bd1b5125ce717315f91e4d3bd4100f7b505fad6af8e3abbdd4f0759813aae3a05e90c23b4ba78c93b25b1711b9082145f3fd8aea81849b9eb991eae4d7047d7d03ddd13acca9a9777f25674154e60e060bb5c5c7be3c78c5b31e43a5c897e4caffa9f7a1784a3421260ea5aee2d02e6433c0b5662245c4120deabd578c95be23824fddcf69241423fff241f95fba244ad1484c09e631e1b800a5d1ddbc91300085db9bacef86ed1c4d3cb780781e1c9e02ad787c161b5797f8f0659efa8344be77edca236a9fd2bf7bf2de0aa7be073b7654a7dab5618a0ce0309e58b827ba0946e73ef577921924d315838740ff2f02dd4e38468fe93cf477bd8895f1dcc5cf8ad4183ca384bdfbe3d46e4bfdfc13fddd978b48eb5ae0468a16c16e3a40d52eb88c6698a26fe59aa829d3548cea01f8791499143a368cc10df96dd9383f216939090abd0f703ffb62811e52d2361b848b466597ff32c1b723f6160f5e2a142b2eb8e636375a1dd708b9593913d80d2443dbfdb9aa76ec2b2a38a38b13f6511248a7c672e7b2361228788754d4c622966be5bbb77049e05d240123925a9c1cfdb7abab0f41c94d1874090481f9110dcb0a7e51c334aa75119c70b570e358ebbe6a273ae63baf45a461b2508e220422a32a363f8a7c9a1b2b2d5d5477762295c405aaab172eeccf35f892a410c5d9098bd985c36b0c0e5027c47d43d38200babc0cc31af1b49741a4af672038927004aeba9f5a687164f44ce33aee7a5c026f2213eaaa2e1a637d9c946bae55bb171e53d2d5e5c60820d878b6e6a3eeda0199fa2608e90a08b0fbdcd80e5f445c6e0667b98efc1f4fd2b08b320aa8a56807767a8d607c28db5ea61a5ecf9976ce281908a1c40c1000f3038f9196f47dc0ffd1d74305a28ba020cd726f6896f7fe390225cd292aeac8305388b6b765ca96d911283e733663900abcdc06ef4fa7570b15b7c47708512ad8abeb9173b1e6871fbf4315c843b2ea3a91afe5b23b82139d12c032c998348c3f44ed226fe1afc990192fe8bbcaa51e4547def8bb76c8a866192b0dfb27ba2db74f99b66881b6b9259e30e7795eb7524f2b82a997ec646e53031ec3c5b8b34022c16181257ec59b0884c7b4fd20d4b9425e8bd1f375deeba525971ea65b4a5f4256dd47880339f6ee908843d7d2cef8dad1fbdb75c2ca6ada1415f83c7b02138f0602169c0f75725ccf52dfeac97bbe61f439738325607a9e255e82ea48ed8af7f60d3a6b9f4f7c15250688bce43dc311e4e382a8ab0c3dba06c7b8c5ede63770e92feeeb31591d9e35f0db391bbdd3602b73bf8a0f0e91892a7acdc0a53834569dc6b661f12588133c0782d14b3516d4a9b5fe5e9c9df5df0c89c531e0bae4e6050957ba7ef3bfb44bf0bfc1a8d9b5b3d72de063dba8772e0f21894b3966a410b2cc849d184369cbfc20a8d2e76494c73f6294745e969f521f0fd22cf1b3dead3888791fe3a073b7be51f92c285ebe305ebb9cc691bb38b02a7360b39a0cd4db80dce561d9e798ae3bef95013b7e9dd5e43c630b824ece8b023679d5122e7dc07c95c35f9e2ef131138a07bf9020d1b62c389fe33b90552304be90309b9169733745f5900911312d4684235470faca34ed59582d1e2d380f22090616478eaddb735390bf840de0e5751ad629e8413921c82423fe4626c0812b612cc2cd48365f7ad6bb8e932a405567f4cafa3e3fd446e2713f9c626c6ff925a4b25d6a356314bd347906144b57400a22f588169bf9d4f30e77b9c6126a7c26970872791915f48f15f1a6378a83f588850df74ad183e97a9c4ce006b3ac640d2a650b8f228902eed1d0c2786300bdafed28dc54498c78ea482dc2e893a60a017389725f4f281f267191e72df183a69e0902c10081a40fc3da3aed353f03222db1ac7af26d0bec38702928d402544f59e76e0bec359e880fa2843665a0beec29bca4e0d866154021b0e26dcd7fd75b17625bfd982e699790f08ac3a44f584a2923094ff82c4b714ff0dc3a3cd156e174bb08f35a56b7cb2c261a886dea21321c20cc2635ffa25ec21be53e93e63a8267a43e3bac1a43172cda46e031b297a72abd0445f4d8bb99f2554e6f539a71cf629a62cbc7d0c64a3b9dbe0d19f4b4620d83e8ad85e85da1a6a18a22d261a036180ac1c3378c125e4a0c03aab46378780672aa764d1267a28d7048f775faace9735fc5ee7afdc9e17fa5a9721e976f842f007d8690aa54a60c95bd9a013a80b59b6a22324bf2c90740967c080bcb48140eeb8246e3d623b8d388a455c9cf7f1c26b5e98226b396810015c7caa384cdaf07b549ad42aab158f69f3da72c1ea1a5c7cf00b7781f5e5b62ab04838c2f6586209c0cdf477aaa4ba459141775b67218e064b09af3be3f2a03854839a097e3a214f03e13ec21145ebb5ff5c81e1c84a8dfe3bcf4892c79d741144d2a996bd8422321999bc8e0395ff453438bbe7395e0695e49bba09ef3d8764948e1ea9cbccf2fe535c918810038418b8fd8f048d0db49bf6c1bfd553b0c394c8f043240a1a01d143cc3c50f981f3e7d6f6826ce7c2af850858753ae5454281ca9f929134e6805f200d4d7e2d7fea1b738f97037402dc6a3494b951274051f848c485d860c2812c2e371e5630f2ab4e56da8b2818468f4927c63699d3fb07611c88e0f2983b6294f3d21bd180cc64a5a2896d472e5b3383194141ee6003b2827513c89e48b0c235cfe5a962ffe156f1875f202fb14d1ef70eca3a0ea8877981010027167b2be0aed6b04ca467b3d9a477a1cf3f9759f2878e237c85a88ce01ee2f97fd97aa750f2c78111ff70bc2d8a535235222a617573f21dce2cf3dd25b70854b9ffd85350129a858ee033ad5f7fc66562f89d87afae6c544a8686499572a035e5995916e183df4a63d8feb24590f28621073a966a61699cd2377125be6043365010e08c61ed3b9c3d001d9c6cafdd4ea120e46860fbca37108a9a5b9a9f2cfaa8446a25b204c4f28ad5e52ab1695fe49da8663e90c2f797425ae367a7b4a42dcd5bd3fe926070c3ebcdba9804cd4a74722f73b0e5fef3e34743e1182ab54cd798228db6315c57f09394125bb7cba5c9d572ad6d255b4b632732cd4ec7063d63eedb4218e1f4f7caf1d3dd25167dd22623aaab18ca729628705911872313ffaf322ce01cc11c936d0dbb5b63c16ee60ad0a85b8964093eb18a940250ebda39766907bce66207f7dc441572f9677aef7a72d3e5fcec0c942e33315dc4ebbbab927bd09a2cd215d120ba8493452622c212d0aab531d9a7733ac743f52608390995cc2f752570304dad42f576fa8c181604c68f2cf87555228663a7c714e26eeb2c6e5035dc80ccb8b814f89a2383e642b8f829691753053f8140819204bd2180ef8c80e93c8230f81025fc3a42a1aa003c9b8eca00e0e3b850fd88c7e61e94d38b4eebb1c47059fd472bc0b8a3b70517698c7b74bb5e00def97185cd883247b4ddba10739fe06a3379164463d5854dd9a241327e5b419a2993704a75b513977b69b96b8fe8b0c7dd4726e5551284268a6c2e2667e0dbb3b28219223bb18f9e5af9d6709cff22b6a031590edb6b989b09732ed7a0a228a67856f391442545e2e1f737606bedc08f6e378d3ad8b0ba6db8d32942fef5e5378046832541b2d12a81ab902352efb246b2c10091c47689a425ec24e5b7f7bc59198f6f27189a2d7f42fa42b6205ac2e6aedf6cb543d0f606d543198e92acf412b5d884cf750f3b73f8897f702656901a19db1c90575af7dedd38bfb74229699003b67fbf938473413c61fb5e6c78b0878fb7a5db4a5b662313d0612e4c04a4464a176e06b478b5cf83921b18342452f324d99695dcf4ce33ff8efc3fd088f49d0747ff112006b954de65c9c8817af0ee60d9137093a9d4197437d2c57fe12ba577ea475d60906732c5746849cbc50162474e22b1c3c16e4d35f0e6a19c5ba983c4a1112f9281cb1f7bfc916a4caa92485487447bb3393167202c3696aaa302c00a8330093f3a1f3ff72baf44420392e5d2dadcad2bbf8303c926c7039c3c79c2041922c6b26504cc48eb5d12c2abd0a7515c373df38a8b44f793ee83bedffd35934f865ea07f10c96fe43e8857907000a4208a2703d320f159a24f346e3bf840260d052179f50919568d032a820df2b38066eba1ea7cffc02ce4c988b4787d58bdf85849317f0f8bd4f715314438f2237e14e38785e43212317697684d4a412ab17cfa0b6a64c8129424b6c7acb8d1cba0efa1a00b3e405602e7d00df2956376dccbae81d3faef40fca3ac6dcbf4f180f72866e5852fc2f0a5890da5d880214ebd2e79b04deda1742a1859f6f089b292e1c10696a966de1ee893258d934f9e851cdc77e848105dedf1f8337b074861e9774475e00815c94a84286c14d1e346f7da8d89ecc16a0c57e32813be3df9f2ac706f1fc284f222caf7608782ca6c7b7fd86c694a5ee6bfccf9eacdb748d332fb4ba7fb8df774b85b2d1f3adb3534985a4437db9ecfdcbbf9e0314a37b7c72205e241cccd78355ac99944501cfaf2c4ee0d0326ffcfe04e80b51d98b4f520e2e9e0f49718ba976711a22332e887c80194195721841e7490949f926bca49c0e2c5ac948fa21bb642670664aad40c4ce3f3ea70cf7902fff4b3debf9857dfc9c096ac7c71452d53f6a34686ff32984305fdcfed1fe0f995a35894efc50182965109605b2c39700a0ad4041c6541186a45e8d8218f4f4b3fe80b45ad08fdc4adf19f15e6beaaef77a30d12b3ca4303b4f55a4db68894cb4916a602f937439cb652f9b0798be3ed4da72c3fa8c0e1652baa9f88e53d45b7f1d762a91733b7b91a913790a477fe63688116c2b9f014462bf1b667c1e4f402a456bd1274c0f34236d06ed70c9b73a587e902443ce4853bad73c7ae5a937a1e5abb4a9bbf069b2ddb4214bb100536bbb39181927d13f2807691da20dfefa9459e9b0dd21bc3e8c33590686c366bcc30074314e6f086c6384de4ad088a49b786d4fe564b3e460fb97e00fd0cb2dcf6a4019d49fb759201a1509e305a20b0f87e49b3eae7218fca5f0b423824dc2d2ae4cab3aa343abe18d31c9e8a7ec65b6e8ef1e7365d2799b931a4c0b2afd800a183d8e0150007ffe345b3693f3acbb7ed7deaed961da6606e00b6f1b7a15f59ea2046f9375819019b86a5c67d16d94ed5b0d64295a6e9e9be90c853062c4bf2127f94e4398de65e83eec4f2e925f51ac77acd291fe3c4408f006040a91726760ea896b5c3dbb049108f42de5f968db4ca92e3341ecbfbbc8bd7968251f3fa3b07e2549cfe3232195b62b1b328895a777653358631d9ccdfa2f4b05199da8bd676437df062fdba92c8d9363bbbfd2cfa9b522c295983cceaf011e002198f97129a3e9981798ea7fd7049cd1514fb8163b0cb39dc8bdc58221cc19062ca8191c9b30ca4b8a7dcfa8066d6491e7e320a0b07c9b907d489911b05be0a726273667acb63e98cb324ca9064fe9a3e625634edd6683e695b5daf6c04ce97c198d7a2448ce0a0cb26b7ecff1ccbaa524dd91b62dbe5517a89643df21a01f1105aad045e0e4151c8ce7f781b40b424b1a071c214c86e28ea60d2489e594830d2a4bd978bf37e94f0f6824811131f99f95e4d63e6a0b13318639f9b78caa1cff2efa88000f5f654df97206a86ff10504529a5371babf812f2f9507b156639609268cc19ce52b7d8582cd9b3c2c12c2a152a085df6366ecab2be22b8620e077c30d95f6757d5f87a031d47d6497a2e59fa8bf4ac2cbbd7a58bb2f2aec7d8af2be0cb08139cc64f33d98e0c462602b4577ea1f0dc893671a4bee327c9b74b7db2d13ce138d323d1f035f1e3e4e0fd6eb69ecab1fe9ec5d2d3984318a0bb7e65c091c416fdf7cc647b1d3db7d46a8fb1e013a33a8f23ac33987832dd47178a51b2e0eec25fdade8e4794a3ee602f3a41f157191b3859a0b5f91f9dbf921cba24eef05f02af93c999a3d7e457d4a94a393daa7ee8dcdb9ee235cd52bbfb650aa70240cee561b03784a493a7109a40e337d51e55ae3de94bea91662a9dc7f3bf8e4d32f3d70587403d8280e55dc12f0afe0e6dafe9c19f2c0abebb0381546a5debccf264e53483931fb53449130f47d1407cd0c372637c0a644bdb8b25561bb28fa030f303a7d9bbbc6f0d2d80986a300cacba5276340a6f95f5a58dcb62d64218ba208aae2a01c8f4dfb42a5f93d44e870b78edd5bcf239888d6692eed1a118b799705f7b93c34b05ce3ae60f439c1742e22d456d35909b541df1efadd8e19eed68f1295e0e404fce2abb84fdb20c7fb59a1796b7db57ede655778fa81bdf6bddc000f06181a177c30403b7a3a75b0dd16518d63cd9e9168c7b891692816985882e40f1d0bce30a24709a075b64799d5b3e42f16d794f34eba8158f842a4b04e46cc1464e3d7f0282d9a85913fa90267ee8565d27fd10e28a2a1495b6ac494faeb9b0ba366816bdf54e694c63b753d9b66ede27540e3082b8a7172755882f56769130f0af577b8c3ede6e8eecc9425911787b62c5468a9ffea09e7257883b554d17704a23942749653ad9a87c8728fbfa56864e69bb8ae9607228bffd91643a828b31357a199ce3f2e4dc3fd57cb963d783242f9369e886376f57b9497504ebb04311eeec6e6c20c50d981fa9719fc9ed87480ddf9799ad62e7b1996293e2d57b0d92d05db41076cd3d90c81f793e57eda1191e5bdd40fc9d4831fccb2d33e8a569e009580985e29d40823ea35fbccb800afebdb2083a963ad2e72bfb0907cbb026e1224c0ce5f59107ac18b03307bf581f6ebcf3ce7800eb87b02a4d25c3c0780690a714e8aef53ad3e7ee56dc8760a1c6ac40b67dc97386716d8b7c8411f8e0fc10885b65982e9844784a2de0689a608bd2b3acb490d4a1a2a8902ffa562e20fea0b3ec2e1baf84eaa8955f757f304d164da3c8c1583567ee07a64bfa1e740f09427fa58b4185e625c869f6220eabe5b2f89ed573e76807d6834a6d93cf392b87e2911224dbd6ba3729d896600bf314e476e43c599de5b638ada7d19530fe557dd1401d2b9f08ce9d2c5fa7935c57f42fc83467dae1943d6c27882686e3f02cdaf1c23df9d61bd4f2b709fa7d2f488f999653318d8cfda4b40f774190c6ae7c68d04892a4456ad9ce39c61f7ccd63bae1f8735f269382ddab8f29590a03db7cc081f900b5fcfbc91245d4cf6e5d757439efc2b1606fbd5d2f98ee420a6b195a7322557b58063144c3b79efa8ca875cb186d97494f99c68ab9216d3a2e281d7d40f158b4dcce0f341a6ec3b566b77c8475f582af06b323c9dcc48fb8f6e4c24d8bd2b6ded7c6bafe9cb0d8dcca57887b1f03e43d8d38b7907ff65a37b78e7cf0648123971a67c2d9dd6a0138b2002ace0cc4839566f50d6095a9aa06a96083951752e8f860211deb7f9eab0bb30f442879145f272c019d2abc5206aae3924a75010275119d2ab7cef59e1636fad4e8bcad6589ba476e38ba5fc71e968541b1820b12ad654f7ebd9a2522d51d47dc5563ea7766799dd694bdba53b7bc2d2ee15f66e0e3fc5a203198545ca949fdff3dae7e730716d079ad70b35a4a3f49c32526592177f84da459ef90637dd637adbeac1f397ac1a8fa7da7d92e2057284b7afa34a03ec549f7e4965203ef4c0f6af45483907c7953bcf8c7c889f8540b93c48a746229d7a407e0b5589707b9bd26b0d13a7dbad9932aeeb8b7e532566cd92a882042b82821e5a9f5116c612818f9b586b639eba41e67d6c42528bca99a7189bbf2428231bf5a4a55bb5412bce1e75a98aae332ed95fcc476a9e18c5b2a90eac937a016a2a3d1ddc5fe9386871595a4c43ae2a5eea44746228ffb79ac2d9e4bb1d9e19cdf2ad6516c16897028def75fe6a78ff95e7062bfed70f2398582e004f7bcc030954895873d6342cbd903dbbe4b6f2f96b7d64579c9a8fca8996188fa3d9861501fe6f36e13a3c12589da13ee190064cdb3abc7143800a2098120cd0636aba23f08f43ddd021e098bfc75ed28215ba4459610ce3e6ee8194d76d83dc50cff7212d421e7d53f7a8dd7c2e1e37ffe54918f94f9aeba116460e76ac28e44f1c3b266386ba3d0083f22cf5e82672ff1bae279291e5eca52f58b928c5e2543af0e20fd256fbfe682dac42b71e11f695165cb77b9c7dab72d4021899aff8c9359ddc2d3310c8c8bcc83fd122e51bd5dea954f2970c5678b2b7e162a9d491a33e1a1b18a7c052d67d102b81301b710279d85f6ae7fb27eca6387bf45bfa08405fb9bb0449911ac0eb0b98c492b3675f3c8b17d8d4071115048d93ea92df10dd66c26523424c8b0d693ff682420404b198302eee8075c3ea7718467b0ea47e54768edc1e5bd11b2690c72032d1762d2bd386a76e7755b63a2d91f3c20a915289a334d82bed12ce87366262c75696163c36ff5b6533912e2416c90b6e307fa71935a5352a78296eb10928a01c2c4a651a4eb3d84093e27e6350fad6ead63ca737eff9ba04a9b5d17b1c78e1bed6711d5479d8d7590f3f050b7bdb7b15df86cba06af51c2a3341060130da96b435ca1e503c509f8e6efb90fd78840546f24a21472c757d0683c8408285b2c5268c325330e3e318ad6f968d606f1f6ba481531195bf905823fdec89b3dec12f3055bfb8f4e93c5756c65f5ba4fbb00e089e1780abcdd4260ad3487daa873a8913b4c45e3b7f68ceb9212a3672bf84f085d7efa6f261d7e42399de655fa523d772ab1c1977833438eff839b68adeb8fe5aa8e59d12c1d70c2ab4d524888f9758141a552238aa961345d98586a78b2ac3038c8db17f6df1d82d04959c242a3e53a402fd87da822dd33050d9629f63bc27f00a9d46cbadee3508dc65c0df4d1bc81f673be17aac5ae7f3f69fcf7a6b1cbbd3258a666c9886f229bc5e356436ac2d1f53b33a5edd19e1a77a12b2149b6a5adfc40ce4f4963a8f1a06ca726e4ac8dcb3631b1423719308baef7996d574b9bb675f8ffe769dba96276d992c218ea1f31ba038b6452bed51cdb97a78433976a53e90ae82249499dc21c8b280bd34f8521011e2f3bd49c88c90af6ec95104bf11178901157fdbc2f205c3f2f523575b57798ecb059e9c04d14156d2cb37bc8e01ad4d01ac1d8a3b2c1a85415be0a1c245d9caa40076146e69123ea7d79e8f66266677141acbb866f813be14adfd28d46f6c387185fe1ca5e7682b6e6349157ec34ac1d1c98c423c220dc47665532a35946c67453844da63cf704e5292f04b810d0e7fa57c3150759b17598d227e1b98cb744472c8235c725f62484f50516e8e3cabaf70e078e0e3a7116e076bb902491083e6e377440b879c0bcae990baaa3a8e9b75459ab5ce62d60fbe4f0a324270050f7aa5f71e5ba518faf8e7bece0338f44047bac43a5a464d1a5168f794f1a130f23dee9035b4aba6d81761a010944d8bc96679a812867312129fc418698487ba09bfe680bb002453bbef00fb05cb50134e0db7918dca367100aeea96655720ebaba10a03ab329a23cf9227874f3f68f4ff6aba63a1e31bf1048679a2ee2d3456d9682bd89129046a3bccda5e9b7e043c4b6e83a6dcf72fe40457fe3fef8d0acee37066ff15eeb9ca6f72fa59dcedd28085f02783709c00b619ac5cd22b0d57011c94a0878f8bb99e32889ee72cae1c797d2d4a885b32d1ce09b4c591d73bbbb7d4eaf5f2de94eaaa39d8ae46abd25c998d826cd3c2b24be42ae4a7c5ca9328b5da8d991067b46dd82b083afe37b7224d60d9c36c74db94ac15662c27062eb5ba2cb387020d7cd53d674b22fc4c48f1577cb2449b81886ba12eab4237ebdce8ccd34826707beddc50db68501788cedb56a75808aa6c7d4aa406a8374eb417615dc633ffc336066aa7437b69436610335e33beefabb58b09e3235ebfbc7043637c7e9c473e3297abfb2ab388fc82c067d9291e973fa7b641530370b330aa26dfecf195301ece3360465b33ad7c72e2906eae61a109da3b01a12b370cadd8bc59bca75c47f9dfb74bc9e505f82a5a421bc28a3878487f40eb18237cb2c22e928498f304584a9aaa187372271de84eeff56f4941103ca0aaaef40b3b0a7a5967383152a13470687b76ed9bf10b3c7bf3070588acc254d0c076b61d7c5d09d43f049275e66ed27775e66a695dabc5ec9a81efa1cfca62413e7c2715246a49e59a1975a1e8c5f581c16953b3238e7100df6d281fbdd12471022d211e9aa0a04c8c5e70bd1f826f3e21f03aec6849a2bd4278dd034fcab56000f1522b39c1bb9086f00b8c3ca230210495fa2eec66b9e4f1605d6dc58ca2464454e404b80261081908b90d9356638dd7b9240375955d9408ad152408cb84c9b3a4f803d4112f330f636ba8078fe23dbdf44f578540434812e91782f9c476a732cc501d8e7f8a273d121de7c3aa317a277c651fd752cf71d02e2fca19761aa849e2ee2d0aac369adbafb47aa9c60d463225df053213140ae24ab4616518ba9cbabcbe2826a8c47881114d6fc61bd001c4f9eae70bbbabcd40b7f46bf03e9247316e981e48219d24777d9e0dd124bf616f6934f8f03ec89abc05987b272f245882d0eb2da402dac09a7b9efa1ce83b590025507e87eb8a4530c77b478ce8b57332df3621a3363ff40d176d60230a289da7fc40d10b6f39be7dab90796d50bf1cd522021b7c8dad848ad2d32698805a7aaa0b7da3a07ce883c27a90f052b3f5c923c0b21051870d5512241f7bf97c74b83b88c648b7a93c2e18c0553ab6054b7d6652060af7808738a79ce157b6cf189d872c3985c4c25402b164ac64cfcec5e751adb3272894740a4a28c7f5c50e676720a3bb3330c596d1b51b40973744fab0f4066a2ef475f092e495adc50e181438b163624430e3289fa7e53bd79e8aedfd1a52141a59a4c51992a031afad71f74321b61e02102daf44c12787fb487e28f020045c2554b70eafaef11bd3b4473da7fa1171d61a148611b91e857db371a6021e02e5082465d45da6c5799563395c7cccc8dc061dc80d09f2a3834dc88ef7e61b45452aa2073ef7f495b56e50e1e7313a17ed454432a9ce4cae176b67b553badf02372fccd7a69af10c16f409533a7e7a7538d1e0604e93e978dbfbebecdfa78d812e11b390a2a02210f434d15b4a58cf4ef045d66d8c411af62d8578f68208aa70b827f8a69a1b792983f900cc2533a01089fd28ea6b83679cbff1fa567930b411b129c86a45349ea27d2850596c0bd0b9153caa96182ae15c2ec6985782b68cc0f12f2d147d2245c42323ec127108569230a4a6a796cc78f730d86bae5ba49997f111467f3da1fc7da088cf349a40e0d69d5d65df21492d82259acd9ca6f97079f7094cf842aa652186162248fc9f05e452c75f78f79f34b0ceda9d1b5bffbae06b08ace101deb3f05e5fbe700a98c259e1527e01be26cbb7aa3f2e7302489f67210225b03b9a82a5ff486478d3e248d9b0ef0c12e8c2a4a94df156b02e7175dcba0fdd5a9c960a8e915edb6bdd2596529c88f4a10ec7be746be2c056b7d9030aa31050256ea76a82ab8c18d53ba8848d8dbdf070cbab935ae371fc200aa8f858762f072ea8b58db1ee4ba00bf879153fdc81ab8fc745472a1ce17139221ab8ba3f24fae60f84f8815319eaeee9edc8dd43285aeaaca0dfa81d95923810e891d50e1f05570e981b9dbe1758bce636d067ed5d29c5c56c133e83e1545014bea6c55612c41bc021267dcc97203ebbae4be62e5f4f05c579ac4e0b550520668fb26a3e21bca88d9323106c35aabedffb98e83679d39c15bc618ca10e2b7c593b2b6e940bb54d775929f73d8e1d674564291b82a8292adef3495560185db0fb6ce8d479203547fe0a5d369e6253126731a156f003a388674cf6f1f1ffd04416edd62df101bf6fd3ac11e48a7bdee8c49d2775abcd563f4259e2bf92002ee822b6436a2e2c95cfbeb3a90669e505da14754dcff65e62d41f84657e33f15e8c3bf939faec2170671f1e6291e9c234edca69495daea06624af464327803b6369a6c536dd9e1faa338562348d3b8183999edfef72f3cc469dc65912ec86b31587856cddd7a60703129f723525803622560a1ca5491c1cab508b55b80caa329d932834aed32324943bd0827b144b4480c7403b30850fae68fd05be4bcfb4b2ce08d74afd147b2b5eb2b56bcd1fa9ad1657d3a6f3f5d0ad5a2a88d9ea287fde5b14f393355c7c218d23792a7020955fca0672dfd551994178df882d67d9b8833cc2763f390c572b2c2bcbcf6f73a56e126464cf60fe45c6b9b04474f05aee1b9e1573e12bad042deb273bacc444a207e11e8e4c047699014d99cc8c45be5db22815e9982bfe391d1968cfc83a1156a5f9211ba8e93d584d0e4a1de08fa3680546163b245bc8d20fb9ac25bcee5fc0f1b48589051ecb1856fd73f9979b1fbabf4dfb4858952d8d11114326a0fdf9729f2b4a305f5c5da2fd96789a25334ce9b29267314198d95e1569ece283d7b30452e9548c23b31c04019fbd1a7ec52097248c683ddaa69f800145cc51b9a45465d0d480a6914e57fc276596e67fa7a986507ffa4275e6c4d50970302cd091a4a8be2125afdb79384433025caefacfa08235f3f8863cd727d920d0aabc78030e70badd682205e4460eb96e24a8773c81fccd810548c7e2ea99292c5096aee3e1c3c96f0105b5e953e61fd2a139c311e53958af1e82411de02b18196bbb223f4f1f3c526ed3bda944ce929e99b8bddb999bd4d4a055a647b35a124bfe368aff68530d057103fc14b6343c9f6574971ebe03ba3a60c6cbc115c41095420da866b399218277a6a497dffd4f565ae24a2e961dada56b3fa30e4de600d30b82e9bce89cf1b8a67b9f9df4e19e98a203ad8ee0603c9b4d04ef96fea02ec5a3e0869195ac1fecf1aa7456f12a00fe30de4ca88255a5798292f8fd1ed12bd16d8770a1e938acd64621d25b319a09778ea95d5d62fa1087366893b689bc0a48b705c9c8e3c656a8cbad9b13ee4c32906f11e2e985127f5e6ee9298f8a5e1559fa1080bb2251b3433df3b369ff51198d29becad63a2662348404cae1dcf325e207fdeada5171927e9fb74abbb31fbf6f71b6ef4db87176bcf88895653a8528dbde3a3b7081f6e02199d067917d6d80c5cdfece94d3f8c8b39aaaa23e6c371173c2843e76b27011348dc6d9b1387a5ed4ddd05234fd7634c4d29c7a1aaf0c0892efbb8d90bdcb2a75ddd1610c1fb997136b361a72fa06e7dd10e0ff9deea60cf890ef3654011ec6bc245ea07272f1c76cf7da601bd9468ae7221b4c880ad5292921ae1e99b829ea974691ecab3aefc1320aebd275709b159a724c601749c52e1ccf6cfda239095cad645145801c9b4f9c2f9bf3dc5098602ba08f4c17add030395a4d37d68664d28214cb83addb4a361a0979108a8c12cf4f1024985554fb2dc77d514c86fdbdcfc0e136d2a050cd8ae5b7cb34e25f64080b100c7e75fa3c052900b6cf63b8be429867a37d8e13db462bd9a96a713bec5e8ad3c35722375b0db5b4daf2f9fb4f63cd4e8684b42582dc4df2b398e3ec51fc454c7647e4cdfe0061699e4d745a79b019b3b890652b297394d4783f44993c466ab44102f450450758052669d8a9b1b0e6e8185906a9168a75babaa95e15deaebf931c5361f21c180370c3effb062108883082b200a9eea74b5208949535ea97f57ed7fd69ab26167ab4df02686727474d80602348bfe16485e5d4999feb423380a52af2f101ea01e756031c45652577ab522390a7e364d6bf0868b58d4b5ab8b4507daa22b7c0068b7ca0af27f9610f9be95b1e8cfaf17225d5cdf6f7d4c5eead3942e9bf83ee", - "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c000000000000000000000000000000005fe27b65c562e50b0f036ea754579e4b000000000000000000000000000000004d71b2b07473783912b25cf8dd9b9c9f0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000210ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c99000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "proof_hex": "0x0000000000000000000000000000000000000000000000032f917b0fd3ba7a530000000000000000000000000000000000000000000000035e7eee9919cfc781000000000000000000000000000000000000000000000004d01f8760c8703bfd00000000000000000000000000000000000000000000000000004d94ca153b600000000000000000000000000000000000000000000000061836908fc3b8f2a500000000000000000000000000000000000000000000000f58c698fe27f1c7ab00000000000000000000000000000000000000000000000c83238a843749bc86000000000000000000000000000000000000000000000000000212d3d108ebd200000000000000000000000000000000000000000000000ef8085780c77757ba00000000000000000000000000000000000000000000000c3c61f9d2347a2f550000000000000000000000000000000000000000000000019c6e6ab16a366da50000000000000000000000000000000000000000000000000000d7fc69b4d7cb000000000000000000000000000000000000000000000007eab1b3dcf475109c00000000000000000000000000000000000000000000000f3b81a7652ce16d66000000000000000000000000000000000000000000000000b7fbd961c0c8033300000000000000000000000000000000000000000000000000005047797e138f27e2b49d2890a1a1d7d9e9f9d5f8de1c723e2432ee10ddddd854082841a60a190d1e262fcb062cd02b7fd2f59f3a9a5270c713891c8e81a49fe088806914debc146279040a63dd82eb4ce9221aebb89787e802ddaa082e654c975d695db28095217de830d6428843cc068ed10d043596da999068b91711995406145a857879f61aac072ef64f542798bdbbbec186c9ddea949792d717af3f861c541f6d3329c8139a72a4c39e91ed9cc57640eda4f794c250d137a8490b015a87034b26243a7e2ec7f12931d3c8474fc12656898b4e3bf422912bdd4db5374ee12c8f096d74f824c025e27442c76ed1b51d39e2cf7034a4479893de172eb8b7294dc4e8d271a3231e7500f202e19d8877a126052f950431368cef6f95f062ced311b8ff6ea4a4149a4952e3d78ce456f6fe14a68b1e90adddacbbf08765d209dc70609ca6400a22b52ded226eb2c9968f70cc9e8d3ae84650a167b9c9f15c26049d55e1f4c1fa028ebcd480f734412ce5f3a2d710a6e77762d349254e59ea37ecb81347b5626e298a12385b87048dc8debad8f5b2908e0723855959723a666f21eca85d3bc8b00cd22a77a7e4e84a2b36db98f02f0eb833246fd103ab30983c6efd381068b8d71f3fbf5f01e7009b84cf9eb866f583ad0c6e4c1f1b9f457acbec88e87f5ad7642c0a219b76dbcfcdc79d797d9e36eb98bc85294d4e80f324c41aeb5d5c7e7a0024cb722fa8c2f51ebde20d08f7808d710737ca258f5d5a92b3502d21cf54b5a00f101276cd0fa6746fd15fb69b4c0e9c468793c3d9de7683305d1ac0139b3ab0101732e6eb2a8c4a782d8a4de7eec90b02a5c2d018de75c066c2494e6f51c6df134d8f766efbcf3ed54ecb62a51e4ceec128d2059759359397b487769861435d07dd738c9bfd93cdafc20a2bbfbff80b293523f1504d9eb4772de3a8799748ef0bcacec57d8ae3fc978ab8ffd64c15a20b4773db561a5a6bd51fb91ad9226911231fc9128b34c554eaf02080253b584e58ebd1cc6e6c976bd0ef8f993282680c187b610790b86b8eb17f5f46cc044b3bd1ff9adb80ca51ede5b36f46a9f62f1b1a89849470515f82eae676e8f251c869872d45d6aed4f38f7d2d0858bf1a4d93058186322e7ee8b79de71f366c9855390b46d2e6c5a6e3cf63fde1e851e03fb10b5b2399701861f4fd31c8bfd664c4c928f3413f55049a1d90c671e9a1614ee127e412345224047f85d7049836cfc6c9a331c14c1c0857dd0199a233c2d6392e1bc381eb283dd577441c23d64f5878e6d627ce803cca051052a1c74c8b66aa69162662c26b7c6664b363e0727e1e9844ce3d2662ab8fb678d1b192fef266bb0b1dfcc5caee4ca0fd5c615ed966245a26131a576c846c2475ba08597e43b5902e103e051dec1ac8f79d07c157ce88a7b2411788658e0df6dd5c23266a513e8b7a0db93f7d5689d0ca3b5c090b9258bd3a8cd939ceac84c1c2f61915d50904a9de29d376f9dd4674ed7e648efe0ce4c0e5634d8d90b6d1e569955fd105ff2751070c70d8bfc9e75ff4894afd01cc06dabca071edf803c9e8e1ce9637e0825ff5fb0305b5ca6feb8d9c1b0fe37be80ac5be9cdeef33956bdeee9d489a5e18f31b83265c9780c4ac8f0c6460997b3e829684c20823762e4850c2156c80ad47db73440f3887deb40f6d3eb415e4cf5a468ad78053028f2d41fa55af530a305d496a1902183d1853eaaa7e4d7470a5520f2142865d8575bb4d1116da36cad00fce14e000315b8a500a1a46059103ee9b2aa0d9a3a9deaaf941369b4b9d8b08ea36cd12179d921c8ffa4d2f47b68b438df65c265dcc076c2777f8611d75cbd6b1aca59119d3221631736761f87dc3fad1d9f71a4ea8ecfb742b1376c06cec1d524858892e1429670e288a4b876c12b4079cebe718f43fc9acf25e76662faba622d990ff214913406b10cd7b24a94127550adeded67a6d29e5600363f247650fa3bbf1650d9dc9af7da683071fd81e8950edec9bebdabe1f7cfe0195e098339f5bdf2a021d02d26abe670315342dd239fb6bf77024da51b7fe27526e111afa16b312bc0f009f4f13105af83dd8e15a51a81d2ead3d76f67962073d80ad460517b6444342298f836107bd20a98b029f5cdaadcd3918c2d9f1d2596d121dde8456565ec01b1db9eb5e4e16f246568c72c64a8ff78927b7ba1d22a89dc0415f084bf1a5c5e307d2fefe8c7c73dc9ca90b4fd975943518f3f9c1dfe083278ba5064e5ffb805d2bf413130a56e5a4a3eab4bad0dc4a5fdd4611ece922af711f0b99815012b2862d53fba4d59d04810bfda4945dd3c93229b1a143e5db3749c6fa8eb30ca3c6a313d74b0604a7f3fd97373f21d8235ce46c550cfa3c02f082ea381467461261022f035b91ad4e1fa0a244b68d9f81e6c2883473f7317cbc990ab7bb71f52630930b4f7231da195bd1bd644b5b2fe16173e5738fc7b368ba6f1014c055cafeefa21e4f186454ff08d1b64548b75dc5c7febb1c27ec3fc5bb59f5efdc25633386cd2fbd6acc0ce26ea7c11e8f2ff5c03cc27e6dde633edb6703664d9b25ede6297308b872b62066969fe13dffad85fb79b12a7f2ee224c2fd4e4cce55b45e4170c7125ed83804f3316f5c17470b160dde071c81d0e9d5e50f766fdf519bf945bd5921b8d4a8af0f1ee513b5d173b3b1ead3c348bd0038ed7b159be86de0109eb8082ad018b9f99c8d7eff3c28494bed4179c43636eb858bbb17987308b52bece0c10589dd01c8d6c6bce012ec221617cb673e673b8052e7e2254e9e08d84190c6c6258ee080fc0fbf163d24a91a2fc4208add9b98bef160bce94b7f6ea671407c150a42dad24823acbe16ab2537442d072a3f6c339581fd33a1749608fcba9193cd0339b24b250972378b10b92cc76c073072924728ee1f9c112abb15ad1e00396d060b30b0d3b8f3b09d8be157157e00d9bb6de1e8c4e899b78212151aaab332b504383516b0755074c07c61d550b5a354fd1204decf0b6d123acb7442f4925d18041a45eb9aec1f8a6edd6969bb0eaf06b2857963547d0ffd277173ee6a2ea831182263aa5773b19ea5cf9b871bc36a39ae544d732858f70057aa6ad36967f4613041fd1eca6bc20777d0a2e58598b67dc69eebb72d472c989d7604004de653ed0cd21ea34fd34c069dd87215a779a6a01d40d7b7333b8be940d34e3889bf96dc07149af5cbeb8494c5a7cceecdfa9ab4b9a7dc5101745b0876706a9f0fb1d05f16ebca6656b0a546606866f3493164c7c7d2617947d68e2c21c89df9e02b5e821c16f98ffb550e9eb98a1a926a7955b91366fa057df7a701e6b22becba0d5ee20388cdaeeeb6ce41b68cfe8b3d1c0d18948490c8f65bd028e3f8ac92f43f99001a8585ea21888777e6f4b0c393b95f64228971149dcd8ed62ac2245ec2453ec809a4c281ede4c0f8fead07d9c33e8fad95f36e6d71aadc7c2fcd88fcedf2c2780816bccb4df8d7a8a6b0a323a72954c8f469031663d7d150619ef3fe21ceb5de2793216c0e79a32438808983c1cceec67fc5b86965315828795a44245f82de0a1cccb11d340ed2183ead2c424b3fd032fdbdaf9e93b314d7de104100b508ef8b07f682297ad47f5a43693b375e85d181090fa4cbba644ab99bdb3aeee7cbe0a123b1680007468d2376fa4b087198a880b7d943122c64e2739285cb197ad6d87c0f8410a1295bff339df55e97c9e2869a3ad39ebee71f0442026725e13c7894701294e42521fbff09cc72bca14c6ee12055e93eb6a36c3dead6bae7ff69e214e5157a8f7b3ee1cc9a630892352325cdfe7f4673bf9b250f74b0d53a9ec62275ed08fa47c06229ee7065a4200e5d2de129180e4a3e2d896d322166a0dd71bc8ab00cae7d08c8e4ce746faa6ef6b7cedb1987db5a46bb1a78d01235dccf1967f4ce133d4a0e336c78fde09b78763813bfe420d501fa1bb77fd59dfb7e9a5df034a30286ebeffc596cc19e89ccedfa81795a7aebbcc9aba21dffc3e0245246f1099d1aaaa6598a814cd0d504a677008cb789c2eaf178e159f5c20aafb301b4f0e8df2479de0f3717d4e4ef7dc83d738610d2f9bcd50d73dbb619b8074f392837dae12bb62b06a460bc9beae70d089fc01a43d5b6c01d6ca2e3037adaf61eb04dc2ae27c47045ac7caf828a562ae12da800e7732b3bc8c550cf584f515f680fbb2b2f28fe7a9e126ac1e7262fc0c4c15a8524ffec6e26abdb450e445cb62a54df6120269fefb17a52977bc955fed6ffa537a1b1d8194c864fcf06ec5d6b129a2e319227a8fadd3a40dfa0d6819498951b4867672fc74428d26c7d490f3a2718ff46a029357e4d83809324bad732e822805a0136e3765feba528bceb2317fa20879da32961662f7a785dce16e500991e0b9c32f5e1a9b80300876499c96b3d3369232e22522f6faa2ef3d05f5fd66d54f0ff085ffff1777b5eedc80bd244a8247be09d299994111e6aa8d0b60c75a68fa4aec522abeaa11c977b175e7c7ccf154c0bcc19ac59eb945f924d1936e318d57d6418989e411ca5870b79984a5a54e32c1d18128c3ae13bf6ae39462c274431cfafdf4b5901872c1e7277a5f9e9833618290e0e06311671aa5e3416015247a0e2bac183c27dc687571b0b581dd3f6adb8962415c7097dc3d0f19f6ee891547d6a619bb3e3f1cf9bbaf99060d8556daef9b16b05416869515e72d011820ff51de020a7c702c7a7942be41bd5efd5e3e96dc3181c682616910eb09cedaee661f46ceb5918d74d23a760d7555a14bd4d012e90d713fb7320d715910b14bbe9439e621e34a1496e8b60e628c9dd5b7bc1115588c107eebb6e62f46011149032423e6ba742d8f8c8a0cf39605e7539f0f809646a3b25db17eaf635e9d1217fd85dfede27881235abe9479fb8ff0bd5be4af87059ae0b42476793bd6e018178fe9a74b84718d5bbbca46087842120e036b0bd3c578f1e76504ad8ef04a719ed739a9583fc3a4b9563d1904c92849a4be6c57f7d596729fd36cbe2dc3855351d29dc4a90ed15ff56fd6fea033728b792ab1183f256f4304280a6041459cf3e6f67b86373d6e4bec24c6484c623721f39814f7ab9b41b0ce2a10a6bdbc16d0f6603a4b0c15b492dd147edbbb3cd16b9d461c2556cd4302dff6cd7ba49ab4c5f3e468b5569adbe825f835d9290467ca676e8e2ea39f1dc294d245771466cdc3546c0624a2d325be31fd9b5d6cdfee83414c334812883b50b6e68e3c8623d0fe6aa870ef8cc6015754b26cf8e215aca15de566a1cf0e9ac0f017fc5385f6873161c7cdaa3b77538dbb5ae5b74f28dfc76d6e0076523c91312b14d00e6c72ab2a16d0c46f6b5739a3b177cea1aac83de18861d4b1bafe05a11f1cd72972a8db708107cfeb0af3487cdf6528735cd20472c1d59d4d8f1ff4209165bd6a83a3819b94428cfbbfb80252a5891c75da8dd740dd53b8badf933662994154da3d0032bdcebaef3cfa3733ffa311dd21b7f7f2e207797deb1a884a1205c698d5ae5b8290c9471ceed6e6c079e0b4f85e98da71f0456a72fca9bd9d628d04e9af4a48f36345b40e585e0aa98d56c46e59612d8e54c397a06850c45c3051be842965eb9f23840f18ee68e27147a5efedbb04efe0937418da83cc0567a079b805d9b638d171a7c59843997ff23b71ea76ea6d6800eaff14d3f79b4165a22c6451ad1775fd4d26d722bf23f89fee41e312ea67679b1fb12ce5369b497262a1f271bcda2d8b84b17c57de10e2721dc36bac0cbd65b5f9376644d05d110561a00dc9f73a118f8b7bc5ae3c6536bae7ae50f220221c018eb59ac638ea67d7313fe05a2c460ec78ec1fca5b0daf64d4c4bb9a72cbf6be833a3b0b2668bb512c23aa5a8cb69c355e5e0e8d5d0f56bb3868029a33963f3bd54a22cddfecb7953d149acfcdf891b6b5515802e2b341d5b058e0e24d56549defc46bf686bc6fe41e1293f7dea651f9c7024bdebfd07b25b7fe9d1433c0c93188c4d56635d75a808a0e8896aab641b65ecad603341135b0b2f3a3b442e05e7a63befedb318467b2ca253f5bd3a72ac1fe96d7a8399e8e5f5baaaa2daf8798e7652e9e11f8f0f524a8161953d5721896c1806a2e245581dd941fd36674ac0beb499d3531155ff4fe0d20f461de9d964337cf3d6dfa698cbd8d731c91741b16f0a7b018a8f3f85a2d842d1caa900206db1de437e9925ee8ea5a0b63cd2d7fb16f358decba50a96160b52b37ef68a5ef127e7f7226d854dd9a6834d2346ce42b3214bf811823183f3bce29a0742bc573a50a950f17d924fa0152192d75027aea786510faa92fa84aa6d722a2230b297f3225a520b30a9c719a1ed90f1c41e0b857c79671d1c8e86d639517505a2d38d3d6ccfdb9cf0be4243edcf0bd9d9919ff3c1e1423587b86902b6b1b76e4c6801996135d3a5b12325a996971feb683407d29c778a0503df7ddca671ea0fb59d11d0cc0307fa4de218be33e88dec7f09231ad19bbef47a9968884db2b9269ac913dcedd940b1c3c556243184680339d304710414288abdc275f5d331dc0edf3ab16f486919ed31e9edb034ea7548d0093cbc255136f2bda7da0439f1392cc549dfe75586cdb78594cef6290c938aa07916c0312b51733f6f03b1c7d1068ba9fb6d003144f42d11f81618c601f6dbd903082b3aa57ad3ae70e32095f171b7135ac8b3add2620cf85c589fb513c4f0d0778ac8b895180ab9088eb270a2ddb28186c6a7715a004da3c73bba9b0301d0627a70229eb9322cd1bc705f54a1f7a778414f4b7510dddfa983a039e1f35e44611da8d5e362f94a8c5b1eb74360ae4f7a7fa0af058f75ee1fdf6844c43e374bdae0a0326d2996c735914cb999504b98ae3afeeca586dc66712fb5cacdedfc84b5fc2cd440e0e98a9b43807a67128bd8c4f473fcbc4b3515924e638d31db8368b06a1ac274ff1d88cd782337c8d13c3e4a706650ee60fda16e68ad2f012a56639ff3bee948229a4ed8d9c386e222223e4f32c02efd03009b0fbf87f63d798094ddb110f9471180732ed2a461cdc2647fd700c40446c1c60e2ad89da7a5df1917822b47b358092a2bb74628d0b251d52d41534aa1ad6e94ebb146fd01ccb98bf7185bfd8b03cdebc5a337cf813450cae2b75fe2cf53bea9b36071ff4b9fa31e1f24038fc7608ea85c6c3b82a84472fc0fcf682228465a07c7d32e8472ec21e0753539adf4885e88b1bdc3350138118c811a01ad8b224bf573095db46b4647dd23ac9030691f2930b097d8ec5dd100760d78d282354c618343787d24bdec98d94bcaf21ccd2983f1bcd16552c2a50253f8802ddc74ea576d7394758ac7217b42c46c076d68bfd316bef99b75e06a416efaa9597b1f085ac6f74cc6334f4708200c4cf3591d47f0f2349d4fea8e2e406987be467dcbe38ddc69127225d20957a15c981020fd96407f2768b2f03688b1c913d9f79fbd9f2886304da7654a180fed16df5011cf9667271813f73a4688b027f9e524698c2cbaa6a88f6e3e76a6c148bc06930fbcccb6782a2a4791242600950c371942d8bd2dc889606dd9515fdd31e146aa7c8ca5eb676717c58ef26112c127d36931d54ecbf4bef7a2f12aea92d47f98cc0dc4d281ede2170413a7898293f5eae5485ee18bac0fa0adf41e3dbafdefb9d9baea98cb05ecc6b633fbcf9282bb4dffe6f83c61655df8b489fb4c01db5f7e2690b255adf3c6e885599084b07c2514a723274817c1f43a9eea8d89e5770c75dba6e113b6eb2938e772ae5011007ac68d590074f3dcd0dcd7d66607dc6105f65dc98c974e07e388029e132231ba3ca3c3929ef1200454504e844c1967fd6c5fea75f01ef3bc5d64b2b8c1f2217bf3df18b7f0e5c4b29ff22f236f48e9bc20443cc75495e3011b66033d753970e28c4adae4607318ab0569c6ddfcbfbea5ee2322832b980bfef0a1db53fb02a2b0eb14c6176a62015852a72640d1bf6f6c542f7ee40ecdefa5d3acb97cddb170f1db88477068182e6be7206269247888df636da9b456f70590c09149bcbf46a19a9d3bc40996abe93b1d5f3dcb11b526ea1d2e959d5bd5437fa4cf91969adae1b0a097d4b17e7b98449f2a90cf905e3eeaa21426ef43224e1adfa70397b968b086613a03251962c98a0ee883329f02c7e859472dde1b90b17c0ff876213a2b02a8cc443ffea3b98cbdf501f3e3e065a2c5d024e7deac62f86af4be112e0c2e41977a2a34885d25ab9a930ceac1a8be6976d64d16d8f7ba2b18440fd9e3049320e24155f1964f8562c19ffd4e30137d0df78c914369c6cfa7fb3a34500ce9169074953563f9312b4c3fe4415159d65210cd379a5bfc6fd2af934b41367886cb30988aceb17be1331db76c60f96c2844989fb22047a619fca5d9434d25d70a1670d197f70c2c89684a98d3381a81123cfa247f4a35bd976852cd73d43a4d02e5a18af2db1a2374dee122147b825440736b4ba20e8d3d680dc8650ee5a9a8a9a301c2b17a1147e43fb585c32e2cda06ce3d54af93d022a4635cf25a4fb78249f0b25bc8ba2e8fb929885b9a19cb9fbd12a676313fd3edf4066b01a779190f4e648118ad0da745bd19017cc131305257f322f323b1f92aa8155829695dc9afe423a0c988765a8719d6f25df1571bd2543f6ba16b19311483a74c784b90b27ddb3b22d6064e4447182baf8dc307320f3029b20cbb8c8896c54226e0e85d4fd70067b0d854dfd5d25f82aeee8aef6e967b52e77caf4e2d93623c85cf63996d182bf5404d4a6ad89410e41775d0876a535c834f85ade195d0b00b462293316a9df7ee12dfc932fa7fc97f276ee49631067d06ccb97b2a260417a009b500958558bbbca05fb66776dc7d15293db5eb8d19df4f3373a6a17a6c3106652fe96751eaf492509f36c9658c35b2ccdad5886ee631cd2e58412a5e503fccdf4bb71771c0947f70db6388d35cb0038e98fe8b78edf81b51a6bacfcb40b93f8636cf07adc589f0f147a7446ff1d2022274ce3b89baf6df657de69aa0cd1c957d8c9f9de2f15ec2e0f7ff502368270a30276308c2f09d0f35de5d0c784c8c45c9482a1f789d021e325c3c8a18dae526ca06a6e6558c6c41fc8af0bdb17fc360cf744c4cd891805a92fe989e097d5ad743ddf07094129c0d1e503511d4f81190723f7956335c2d9110d24f22584b4c727560b83aabdcf961b690ba845788039718a4506dcd048e8dc2490ff6a88b9671d9398eebc8319797bda55d642bcba47f139a231d650101aad27b12f3c069358e6b82333bcac1dded6c23d8900930f2c5fc7be3edf64874de1141fcd391a2b917da0165ab0fef51d6730ae7cd9b9b1f3d0b55fcc72eb3e17b62debe56fe2e10127f3b046cfe373456b3360509b8328fc04d54606829576c5250462738984185b20a0b7f88023f3e7777c7ea62d1a41d364c533bfb2d12fa1cd0db92d5464ba8a38133367f515e4de7d424c586306d9ce22987b7247386b01022757f4648500f17e96149cf652c6c6a28fe9f85e045be8d9d66f92ff74229299049344cc223c6f1bd7d67761c9b93ea2d8c912d34ce9af9be5aae395f497c90a0af3b013a82b622b4942d4c5e76acb383740009874450f496f32cd7517be45ca289cf4b127c67cf0155168cdbad6fdad969ed7f1c8162ba8f5f89e3886b812f91e21f02ca64205417c15bdd1379eeb814083a3c32dc715c0747dbcef6dbdd7531d4deccac77bf29d1628280a89c4848c94eaddc3b36312fe2505b37a6d75fe81045025949fbc93a3326af3fd369d39fa6c009ca3471f1113847a3919b116bdb9077a09781a3a637599df7fcc98839e11c07e695d311bc51e6b8d64b55d2f170400e634e4979be229ad38ea5e2f128d1572a85cce10f271c414c04a306c6b92002a00e00825eb99906a26d1945eda3910b84502cd3482d0d84f5847932dcc4faf0bfb0c9f3bbbefce5991057908c42d2d5920d1757da51a12d9bd5d99790f76652c4307b7d0f927786d9e6cb6c57ebb44fc5d2b04c3359d3f4e3735a45861a3ca2859d4f4306d1843f79a332294a638cb1f76622e57d50558c1f22abd370503c903caa3f08dd93e5f82833de8e6d46a3341e7a8913f2a7e22e6643bc7c6538c8e0cbbf6fbf36164fe1b6f1145dcee45960273b2891250ed461e1ae1f23b19863c0ffe0810499d5b5be47ab8bc81ed7a2e004439eb823da19d539f8e7ac1659a92096441c33583ac9c5603ccb0d44c51fed6308f069da81382b1a1d74262f89cf328243fb2580e1a1abbbe2bed12ac80e361ca6a4123461a6d8efc5eb8672dddd22320ac7c5a087b21dd48e32e8ebdb4da050b93dd294e91d28a238b59d41d6265221ceddff0fc2a28de353b6c14fc5163ef26aaf67bc153eade50130c49c682e91851b297fb64d9d792b9c9c44a8a8bd2311db7cfad7090e8d1badfa6ac6a58a207f955c456cea50f9ebc0d7f95b4bd3347b211234a55c5c4bf20a183ac9b683719f208fc6b8cc67ecc372b325a4901678b2fb9288b4ff6601097abdc14df17010ca0147edd325f460457fb6ecccae55494c61cc30f5c29cf57a424147feb0b26195c0e3e739d3b3669af537c778a151926b774187ef6000f4d7349c6d5a248352efaab21ace4fcb78b5226827b068bcdda804f14b7fd86bdafd02c95fb60def714b6962ebdb37972973f9cac5db0d6bb9793fa68f19129a098bf9919df1f9f382df39520119d0fa7c8b262361a51fef9e5c0418b4af5c082b50dd95af82039f6049c751ab056b6ca7b13a1c1fbe61d36341c4df78ef722bc37a0635e42af44201d7951639b2fc9037432aff590c41fecc465cf82a10c7385f05e4ec18243106408c4fa61fa0ee08ccae97a0f104cc9c331fd87b786a8aaf813c05d187b3e30dc240b88f66c0b8d5c82efb9952183e37131290dac7ccd34bdf015214f933e275e03583c09916c1c6ca5a79acd3042fc82c1880dafdd9c00e1ff3ad410d8547c400d58dd99c637a8087117e36ea91e6812c6742e2d7250bf9ffedc435e6f79c9ee00de2aae6f0d19c82b5c99cdeac09f23d4e9e1dc20c1aa7c40a19b175c04ed182bf3b47f5dcdea54be39082d106621c59df843109a6883e4ca3949acc4e9754f103077d98bc264134bbbaf7e90d8d842a33578a7ad26a061c9ca6b77b3587dc826b783db0e3f346007f66f31f8612359a1aa251a23fb875f7d529bcf9223978716c7f5b8879fff558c3799d234346f05d7e80789d437b4cdd55c2be81353abec17abd7d2ecd9e1450ce944d03c9e6e517075a82ce5e4193844eac41f54abbef00f86aa9bd96eebbc4a7b67067fb9de593364457f94ffbdc8776b908b68b73c9c0850cc0dbd973ba25d515ee139f15fbfc0f125e1682f8f4d42b47f7c3281c2251f2eef4b2d676d4791b21a53a281ed28902f731d256e5edca72933b79053311513bb354296f2cc4c225fed68e505bf1430b1e5350b29049107ed15530da30d8a26863fadc7374c10adba56cfce0212cf3ef17d9021f63ffcd3de6b55b89f72a22c2b59e3d3a06970bb738b602390f6695fa876d376d9c0b845fe711a85e77afc2ba278b527ee921508d815f640ec09bc8d963a6aa450b1bda744f420a23e669d2df4d35f90eb8bba6771984c28fb5575cc5628cd6437a9172bf671d6197b224726dd1157e09bafb93f5e8daad3e37eac638fe47897bb1b8f476268e2f4783096133455ec390141a1bed6103851ed452c5969ef4765c5a24f4d17d1b3676e80dd2315c58cc3c2018a9e4dfa28d965895a1eb055c7fe41eabf03d3036be840abb61301d966663a812629391084a6b445fede42b562e60e0b74bd7b7f424474f87d02f3686c606b1a96da46917a8cb070f6867b4672311e248492072364ee5e70842f52ad47f0cbc0b018fb41ef8694d08f6f604f4ca40f578a7d0c561021ee8dd62b4605620eeef24fae8d03b5ab8ff013f7181b8db77f1fb03565bd5c9d896f66285ac0f3bf9b155ce499a793df6bb993d5aa821773b92854d96b59e91f212fee2c60be3b197bcf457faa4932500e94ed760070c26e49789a33186f5ffc99447f1676d9956e30b06c28f150456073c06cd17380311cdd6e542cfe862e3a00d27017b5827b442d3af40df6449ed4c04be82015ddc6ad04112ef5f062edda022e8909cedae081e8db20856c23c6baaeb42c2c5e7b0fe8abe6ec3980efb76912aa4309f135514e65c16895796e9b278a31a747ed20eb572ab82e1a49fd8ca60a98f823cf3344f17db432a8c2f9baa00be40038c98f7c11a1b2c414e67686b77720d8137f3272f6de98b68ca04b28d2396f5a2b6d894113b7f7af32aa77200688a6952583043ef8ff22e4c1e417c68648a3380691e1d9bf55db4533703448b331fc4b1e6dc67cd32bb0f26b5cc312fbc5a8eaefb7b10ae7cd03402aa9ac3825b597d62e10e39cd2a8fd4bf1517d37255560dc77db0ea2db7edfe9cc564d0fa22ced9d2d80ee077547db7160f90ee4e7fe9f1c3235acb8323abf43e2fcfc741d5f9a9819cca25bf68ec3235595d7f0d759d661253e9ef535ef4d8e4b0096e814e013921f749227303bc67bf6cefdf344692198576b1bc4356c73ccdfaabeedbf69abde2c462f80f1980015305e52b10707bad1889f5c39f736800aa51f1501d405b3732af595b49c48b4333f160b58b87ca84c910977c93aeea98a2362e4daef3ef63f08bc094cb1019eec6c1e9f2feb2bef068c5fc563a013950433c25e7e218b66051d5a44837375c1b83c9489efe3099f427c67bf0fefb25dfd8b626c48d00c7a4b1070504657a3b7ccf42af9dfa40e93afc0e3a5e2aa92e250f2145ea915abdb6a0b78fd055839c44b13e2fd7782d67e7a0ff4e1181b4bb64124543f5438702ee42d8d8dec996a95e84c8c9f1419c5bc66b34aef3700a67786714b6aad4147643c172c4a70c0e363781f8956e374b01f88f397750c374cd7d163919d877889bd5629aa9a70dac88464aeac5a0cd4906d60979ffc1e4626b0af9aa0a22e9d3966ac2609ada8891286e5fe76227c8b5b50a267171e1d256d6468ae45360978054ab41625cffa58eae964ada1e6369b9c8b2491d372aac40aff7443366aaf6679274f26d13c1d1fd13e2ebc731975b57be4c9eee4b6dc88445d8ffb0d6de2e69b8463129087d86aea27ccefc304326063c7972ba3e80553fac7c5c488ac4545f8ead0169bf87f01acf9353d0ed6fa6a55db96bd9e41ef8fb4f1c2628e86504987acd21b9af044c092f91ead0db66966546169c32b670bfeeba5746860f83ee005d0da01bda136cef67dd3e66a111bc90cd88056b1619d90c701fcb20a7a4ac33342950f6188bb0e7d4a788e1a24808954084e37d8377cef483a9a84490b46c95d10a82c27ec6acd7128da9cd8250a45fa24b5678e94a0eead4f51b62881505463237502442e915e71adedfb9f97115ac5d150170b2d572e067a92010f51c48168fa8005fd3192e9b838c58f31b3ecfbbb078e8639ee2f3a5dbeb8dfc5ffe1175b448c00e213d2ddcead739b4563a90f47b5fdfd45eefaf5dcec0768df8490020e69282377fb10343b5a8a221bb1fea3bf8fe84a790c1adeab68779614f29c283810200156b08e06521c126199dbb9ea2f2a6af5f5b7552e40ae1555c760930577969e22c7b04ea4e95901c650a73c988c618bead593d17d5007146ea9c47dc77d14ce0e03ee7b11ce3448fdbc534f42ef81bac3bb78c15b1b3a83d56b3f36d21b62d92510252201ab1927d4ba5dbaef0f3e1c095e8c52a019da94e3560e11a83205e4276ec3235751505050679851506af768f0cabdbd6571d0995bcad6e3f6c10f6a1e09368c3547f9ad262f12a9adf34939cea2d1154acf2aec479352ded626aaef25982e7552e667fc7e4e9e6fe330dfaa6ec83fca6b2604281666f3f99c32262905e6a7d5c87d6ccbf80260ab790e02fe7f51dc8071a5fe80eebdfa76a7c258961c401120d9f12b68c977423df5af18e93b2193e9b74fe53bbcda7468f342863e08310cbff5ea6c0ff558bb83aa2bc23e8df39b3383c6ae5f86c22845edb39b2a2953297894e3c2ad4e253dca273b043ab725f81833d327159207177c0b0ec96a2a9d9dd5834c42b493856edf49a3cbe2be99b4711f6bc83e57cd41137641847a04d4127ee7420f4b77460152b4d7aefd72c105f3b834dededbdecb89a1c4d2d22831a4928e242757e1f30360cb8c0501aa4642cf791ad9246a4a49bc712086c50cf0c0067bfc80c788d426bcfa946f8830771998880594658acedbd416087f731c2d9a1f721e273a548daa7078371b7f6196244479f11b24ebaa395631e9ef1f0ae2ef0548e857f2df929518a18b8a95717f00257f6c5f133ee95ca28b76febc122ab204fe89476d434759f23f70fb44b03b5ef93011c0c147acc417dbff7800172bee75bd52030baa9d42c0be98620037f763ea2b51bbf861b8f03a03eb2d030793cc0c782cd860d2e212b7de317c1687b3a7c3338926cce04b4a79562d77ad232eca3a2901fa6cd0fff130d3e55735b134c8022dcb25f8dd068d5d1874e3572012f7a4df16d20451fc0d48ffb0b844c34d578893abe54f5da62af0c4b597b51f8f652fb2d9440c9641bf27dda51477b9d902fe04f5be88f852c3558cb1a5fb03ae2d0635da9de9c58fed8a406dd3b2d99445a575fa3864f1d4c4351617617e1ed2bb4f656f1113aca5094ec20d755d1287fededfbec38fda5c26660a292656", + "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a00000000000000000000000000000000ae6a85768f71c83f114b20d8a933586300000000000000000000000000000000ebd03ad97202d4bf5bf80bfeb5239fba1f8e48fdae937d71edfb5a4d694a7bb5a16a0c2ed1ab32e08dd664615f32513e0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } } diff --git a/circuits/benchmarks/results_insecure_minimum/report.md b/circuits/benchmarks/results_insecure_minimum/report.md index 4e2ae6fdfd..d44ad5a4d3 100644 --- a/circuits/benchmarks/results_insecure_minimum/report.md +++ b/circuits/benchmarks/results_insecure_minimum/report.md @@ -1,9 +1,9 @@ # Interfold ZK Circuit Benchmarks -**Generated:** 2026-07-18 21:04:24 UTC +**Generated:** 2026-07-18 22:30:49 UTC -**Git Branch:** `circuits-audits` -**Git Commit:** `135c1344a6c160a49d0086c9cf9574e66e6df8aa` +**Git Branch:** `fix/1731` +**Git Commit:** `37ae995a82dbeaafa24cbd1d97157a088fcc3960` **Committee Size:** `H=2`, `N=3`, `T=1` @@ -13,205 +13,194 @@ Settings for this benchmark run (integration test + Nargo circuit benches on the ### Integration test (`test_trbfv_actor`) -| Setting | Value | -| ----------------------------------------------------- | -------------------------------------------- | -| Benchmark mode | `insecure` | -| BFV preset (artifacts) | `insecure-512` | -| BFV preset (enum) | `InsecureThreshold512` | -| λ (smudging / error) | 2 | -| Nodes spawned (builder) | 7 | -| Network model | `in_process_bus` | -| Testmode harness | true | -| `proof_aggregation_enabled` | true | -| `BENCHMARK_MULTITHREAD_JOBS` (max concurrent ZK jobs) | 13 | -| Rayon worker threads | 13 | -| CPU cores (host) | 14 | -| `dkg_fold_attestation_verifier` (EIP-712) | `0x7969c5eD335650692Bc04293B07F5BF2e7A673C0` | -| Verbose logging (`run_benchmarks.sh --verbose`) | false | +| Setting | Value | +|---------|-------| +| Benchmark mode | `insecure` | +| BFV preset (artifacts) | `insecure-512` | +| BFV preset (enum) | `InsecureThreshold512` | +| λ (smudging / error) | 2 | +| Nodes spawned (builder) | 7 | +| Network model | `in_process_bus` | +| Testmode harness | true | +| `proof_aggregation_enabled` | true | +| `BENCHMARK_MULTITHREAD_JOBS` (max concurrent ZK jobs) | 13 | +| Rayon worker threads | 13 | +| CPU cores (host) | 14 | +| `dkg_fold_attestation_verifier` (EIP-712) | `0x7969c5eD335650692Bc04293B07F5BF2e7A673C0` | +| Verbose logging (`run_benchmarks.sh --verbose`) | false | ### Hardware & software (Nargo / Barretenberg host) -| | | -| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **CPU** | Apple M4 Pro | -| **CPU cores** | 14 | -| **RAM** | 48.00 GB | -| **OS** | Darwin | -| **Architecture** | arm64 | -| **Nargo** | nargo version = 1.0.0-beta.16 noirc version = 1.0.0-beta.16+2d46fca7203545cbbfb31a0d0328de6c10a8db95 (git version hash: 2d46fca7203545cbbfb31a0d0328de6c10a8db95, is dirty: false) | -| **Barretenberg** | 3.0.0-nightly.20260102 | +| | | +|--|--| +| **CPU** | Apple M4 Pro | +| **CPU cores** | 14 | +| **RAM** | 48.00 GB | +| **OS** | Darwin | +| **Architecture** | arm64 | +| **Nargo** | nargo version = 1.0.0-beta.16 noirc version = 1.0.0-beta.16+2d46fca7203545cbbfb31a0d0328de6c10a8db95 (git version hash: 2d46fca7203545cbbfb31a0d0328de6c10a8db95, is dirty: false) | +| **Barretenberg** | 3.0.0-nightly.20260102 | --- ## Audit status -> **Incomplete on-chain verify gas:** 1 of 3 artifact verify-gas values are **N/A**. Re-run -> `./run_benchmarks.sh` and ensure `extract_crisp_verify_gas.sh` completes (CRISP test + -> `test_trbfv_actor` + EVM replay). Calldata gas alone is not sufficient for audit sign-off. +> **Incomplete on-chain verify gas:** 1 of 3 artifact verify-gas values are **N/A**. Re-run `./run_benchmarks.sh` and ensure `extract_crisp_verify_gas.sh` completes (CRISP test + `test_trbfv_actor` + EVM replay). Calldata gas alone is not sufficient for audit sign-off. --- ## Measurement methodology -| Metric kind | Source | Meaning | Do **not** use for | -| -------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | -| **wall_clock** | `test_trbfv_actor` phase timers / HLC event span | End-to-end wait in the in-process test harness | Production WAN latency; per-node deployment cost | -| **isolated_nargo** | `benchmark_circuit.sh` per circuit | Single `bb prove` on oracle witness, one circuit at a time | Full protocol pipeline (different witness path) | -| **tracked_job_wall** | `MultithreadReport` per `ComputeRequest` | Wall time of each job on the shared Rayon pool (≤ `BENCHMARK_MULTITHREAD_JOBS` concurrent) | End-to-end time — **sums exceed wall clock** when jobs overlap | +| Metric kind | Source | Meaning | Do **not** use for | +|-------------|--------|---------|-------------------| +| **wall_clock** | `test_trbfv_actor` phase timers / HLC event span | End-to-end wait in the in-process test harness | Production WAN latency; per-node deployment cost | +| **isolated_nargo** | `benchmark_circuit.sh` per circuit | Single `bb prove` on oracle witness, one circuit at a time | Full protocol pipeline (different witness path) | +| **tracked_job_wall** | `MultithreadReport` per `ComputeRequest` | Wall time of each job on the shared Rayon pool (≤ `BENCHMARK_MULTITHREAD_JOBS` concurrent) | End-to-end time — **sums exceed wall clock** when jobs overlap | -**Harness limits (integration):** all ciphernodes share one process and bus -(`network_model: in_process_bus`); sortition registers extra nodes; `testmode_*` enabled; proof -aggregation always enabled. Compare runs only with the same `benchmark_mode`, committee, -`BENCHMARK_MULTITHREAD_JOBS`, commit, and hardware. +**Harness limits (integration):** all ciphernodes share one process and bus (`network_model: in_process_bus`); sortition registers extra nodes; `testmode_*` enabled; proof aggregation always enabled. Compare runs only with the same `benchmark_mode`, committee, `BENCHMARK_MULTITHREAD_JOBS`, commit, and hardware. --- - ## Protocol Summary ### Circuit Benchmarks (isolated Nargo + Barretenberg) Single-circuit `bb prove` on the benchmark oracle witness (not the integration actor pipeline). -| Circuit | Constraints | Prove (s) | Verify (ms) | Proof (KB) | -| -------------------- | ----------- | --------- | ----------- | ---------- | -| C0 | 6847 | 0.12 | 24.33 | 15.88 | -| C1 | 53485 | 0.32 | 24.60 | 15.88 | -| C2a | 41244 | 0.30 | 24.55 | 15.88 | -| C2b | 79591 | 0.51 | 25.52 | 15.88 | -| C3a | 120114 | 0.57 | 25.36 | 15.88 | -| C3b | 120114 | 0.57 | 25.36 | 15.88 | -| C4a | 62750 | 0.34 | 24.95 | 15.88 | -| C4b | 62750 | 0.34 | 24.95 | 15.88 | -| C5 | 21501 | 0.21 | 24.75 | 15.88 | -| user_data_encryption | 53732 | 0.33 | 25.75 | 15.88 | -| C6 | 86929 | 0.52 | 24.61 | 15.88 | -| C7 | 90889 | 0.47 | 25.52 | 15.88 | +| Circuit | Constraints | Prove (s) | Verify (ms) | Proof (KB) | +|---------|-------------|-----------|-------------|------------| +| C0 | 6847 | 0.12 | 24.93 | 15.88 | +| C1 | 53485 | 0.33 | 25.36 | 15.88 | +| C2a | 41244 | 0.31 | 26.14 | 15.88 | +| C2b | 79591 | 0.49 | 24.71 | 15.88 | +| C3a | 120114 | 0.56 | 25.48 | 15.88 | +| C3b | 120114 | 0.56 | 25.48 | 15.88 | +| C4a | 62750 | 0.34 | 25.38 | 15.88 | +| C4b | 62750 | 0.34 | 25.38 | 15.88 | +| C5 | 21501 | 0.21 | 25.77 | 15.88 | +| user_data_encryption | 53732 | 0.33 | 24.50 | 15.88 | +| C6 | 86929 | 0.51 | 25.71 | 15.88 | +| C7 | 90889 | 0.48 | 25.61 | 15.88 | ### Artifacts | Artifact | Proof size | Public input size | Verify gas | Calldata gas | Total gas | -| -------- | ---------- | ----------------- | ---------- | ------------ | --------- | -| Π_DKG | 10.69 KB | 0.38 KB | 3119505 | 175020 | 3294525 | -| Π_user | 15.88 KB | 0.12 KB | N/A | 170260 | N/A | -| Π_dec | 10.69 KB | 3.53 KB | 3672202 | 187900 | 3860102 | +|----------|------------|-------------------|------------|--------------|-----------| +| Π_DKG | 10.69 KB | 0.38 KB | 3119663 | 175176 | 3294839 | +| Π_user | 15.88 KB | 0.12 KB | N/A | 170236 | N/A | +| Π_dec | 10.69 KB | 3.56 KB | 3674782 | 188436 | 3863218 | ### Role / Phase / Activity -| Role | Phase | Activity | Metric | Duration | Proof size | Bandwidth | -| --------------- | ----- | ----------------------------------------- | -------------- | -------- | ---------- | --------- | -| Each ciphernode | P1 | one-time DKG participation (test harness) | wall_clock | 137.63 s | 127.00 KB | 128.06 KB | -| Aggregator | P2 | C5 + Π_DKG fold (aggregator span) | wall_clock | 125.47 s | 10.69 KB | 11.06 KB | -| User | P3 | per user input | isolated_nargo | 0.65 s | 15.88 KB | 16.00 KB | -| Each ciphernode | P4 | per computation output (C6) | isolated_nargo | 0.52 s | 15.88 KB | 16.06 KB | -| Aggregator | P4 | C7 + Π_dec fold (full publish→aggregate) | wall_clock | 55.07 s | 10.69 KB | 14.22 KB | -| Aggregator | P4 | C7 + fold only (pending→plaintext span) | wall_clock | 51.29 s | 10.69 KB | 14.22 KB | +| Role | Phase | Activity | Metric | Duration | Proof size | Bandwidth | +|------|-------|----------|--------|----------|------------|-----------| +| Each ciphernode | P1 | one-time DKG participation (test harness) | wall_clock | 135.11 s | 127.00 KB | 128.06 KB | +| Aggregator | P2 | C5 + Π_DKG fold (aggregator span) | wall_clock | 122.81 s | 10.69 KB | 11.06 KB | +| User | P3 | per user input | isolated_nargo | 0.66 s | 15.88 KB | 16.00 KB | +| Each ciphernode | P4 | per computation output (C6) | isolated_nargo | 0.51 s | 15.88 KB | 16.06 KB | +| Aggregator | P4 | C7 + Π_dec fold (full publish→aggregate) | wall_clock | 53.77 s | 10.69 KB | 14.25 KB | +| Aggregator | P4 | C7 + fold only (pending→plaintext span) | wall_clock | 50.06 s | 10.69 KB | 14.25 KB | -_P2 **tracked_job_wall** sum (ZkDkgAggregation + ZkPkAggregation, parallelizable): **6.03 s** — not -comparable to P2 wall_clock row above._ +_P2 **tracked_job_wall** sum (ZkDkgAggregation + ZkPkAggregation, parallelizable): **5.96 s** — not comparable to P2 wall_clock row above._ ## Integration test (`test_trbfv_actor`) ### End-to-end phase timings (integration test) -| Phase | Metric | Duration (s) | -| ------------------------------------------------------------------ | ------------ | ------------ | -| Starting trbfv actor test | `wall_clock` | 0.00 | -| Setup completed | `wall_clock` | 1.02 | -| Committee Setup Completed | `wall_clock` | 7.02 | -| Committee Finalization Complete | `wall_clock` | 0.00 | -| Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall) | `wall_clock` | 125.47 | -| ThresholdShares -> PublicKeyAggregated | `wall_clock` | 137.63 | -| E3Request -> PublicKeyAggregated | `wall_clock` | 138.13 | -| Application CT Gen | `wall_clock` | 0.01 | -| Running FHE Application | `wall_clock` | 0.00 | -| Aggregator P4: Aggregation pending -> PlaintextAggregated (wall) | `wall_clock` | 51.29 | -| Ciphertext published -> PlaintextAggregated | `wall_clock` | 55.07 | -| Entire Test | `wall_clock` | 201.25 | +| Phase | Metric | Duration (s) | +|-------|--------|---------------| +| Starting trbfv actor test | `wall_clock` | 0.00 | +| Setup completed | `wall_clock` | 0.97 | +| Committee Setup Completed | `wall_clock` | 7.03 | +| Committee Finalization Complete | `wall_clock` | 0.01 | +| Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall) | `wall_clock` | 122.81 | +| ThresholdShares -> PublicKeyAggregated | `wall_clock` | 135.11 | +| E3Request -> PublicKeyAggregated | `wall_clock` | 135.61 | +| Application CT Gen | `wall_clock` | 0.01 | +| Running FHE Application | `wall_clock` | 0.00 | +| Aggregator P4: Aggregation pending -> PlaintextAggregated (wall) | `wall_clock` | 50.06 | +| Ciphertext published -> PlaintextAggregated | `wall_clock` | 53.77 | +| Entire Test | `wall_clock` | 197.39 | ### Multithread job timings (`tracked_job_wall`) -| Name | Avg (s) | Runs | Total (s) | -| ----------------------------- | ------- | ---- | --------- | -| CalculateDecryptionKey | 0.00 | 3 | 0.01 | -| CalculateDecryptionShare | 0.02 | 3 | 0.07 | -| CalculateThresholdDecryption | 0.02 | 1 | 0.02 | -| GenEsiSss | 0.01 | 3 | 0.02 | -| GenPkShareAndSkSss | 0.01 | 3 | 0.03 | -| NodeDkgFold/c2ab_fold | 18.82 | 3 | 56.46 | -| NodeDkgFold/c3a_fold | 73.49 | 3 | 220.47 | -| NodeDkgFold/c3ab_fold | 7.85 | 3 | 23.56 | -| NodeDkgFold/c3b_fold | 73.17 | 3 | 219.52 | -| NodeDkgFold/c4ab_fold | 8.28 | 3 | 24.84 | -| NodeDkgFold/node_fold | 18.94 | 3 | 56.82 | -| ZkDecryptedSharesAggregation | 1.59 | 1 | 1.59 | -| ZkDecryptionAggregation | 49.68 | 1 | 49.68 | -| ZkDkgAggregation | 5.74 | 1 | 5.74 | -| ZkDkgShareDecryption | 0.95 | 6 | 5.69 | -| ZkNodeDkgFold | 108.81 | 3 | 326.44 | -| ZkNodesFoldStep | 5.31 | 2 | 10.63 | -| ZkPkAggregation | 0.30 | 1 | 0.30 | -| ZkPkBfv | 0.23 | 3 | 0.69 | -| ZkPkGeneration | 3.61 | 3 | 10.82 | -| ZkShareComputation | 2.62 | 6 | 15.70 | -| ZkShareEncryption | 3.67 | 24 | 88.14 | -| ZkThresholdShareDecryption | 3.49 | 3 | 10.48 | -| ZkVerifyShareDecryptionProofs | 0.08 | 3 | 0.25 | -| ZkVerifyShareProofs | 0.24 | 5 | 1.22 | - -Sum of tracked job wall time: **1129.20 s** — **not** end-to-end latency (jobs run in parallel up to -`BENCHMARK_MULTITHREAD_JOBS`). +| Name | Avg (s) | Runs | Total (s) | +|------|---------|------|-----------| +| CalculateDecryptionKey | 0.00 | 3 | 0.01 | +| CalculateDecryptionShare | 0.02 | 3 | 0.07 | +| CalculateThresholdDecryption | 0.02 | 1 | 0.02 | +| GenEsiSss | 0.01 | 3 | 0.02 | +| GenPkShareAndSkSss | 0.01 | 3 | 0.03 | +| NodeDkgFold/c2ab_fold | 19.28 | 3 | 57.85 | +| NodeDkgFold/c3a_fold | 72.09 | 3 | 216.27 | +| NodeDkgFold/c3ab_fold | 7.79 | 3 | 23.38 | +| NodeDkgFold/c3b_fold | 72.64 | 3 | 217.91 | +| NodeDkgFold/c4ab_fold | 8.06 | 3 | 24.19 | +| NodeDkgFold/node_fold | 18.46 | 3 | 55.38 | +| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | +| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | +| ZkDkgAggregation | 5.56 | 1 | 5.56 | +| ZkDkgShareDecryption | 0.77 | 6 | 4.60 | +| ZkNodeDkgFold | 107.17 | 3 | 321.51 | +| ZkNodesFoldStep | 5.21 | 2 | 10.43 | +| ZkPkAggregation | 0.40 | 1 | 0.40 | +| ZkPkBfv | 0.22 | 3 | 0.67 | +| ZkPkGeneration | 2.25 | 3 | 6.75 | +| ZkShareComputation | 2.50 | 6 | 15.02 | +| ZkShareEncryption | 3.92 | 24 | 94.12 | +| ZkThresholdShareDecryption | 3.43 | 3 | 10.28 | +| ZkVerifyShareDecryptionProofs | 0.15 | 3 | 0.46 | +| ZkVerifyShareProofs | 0.25 | 5 | 1.27 | + +Sum of tracked job wall time: **1116.25 s** — **not** end-to-end latency (jobs run in parallel up to `BENCHMARK_MULTITHREAD_JOBS`). ### NodeDkgFold sub-steps (`tracked_job_wall`, per fold prove) -| Step | Avg (s) | Runs | Total (s) | -| --------- | ------- | ---- | --------- | -| c2ab_fold | 18.82 | 3 | 56.46 | -| c3a_fold | 73.49 | 3 | 220.47 | -| c3ab_fold | 7.85 | 3 | 23.56 | -| c3b_fold | 73.17 | 3 | 219.52 | -| c4ab_fold | 8.28 | 3 | 24.84 | -| node_fold | 18.94 | 3 | 56.82 | +| Step | Avg (s) | Runs | Total (s) | +|------|---------|------|-----------| +| c2ab_fold | 19.28 | 3 | 57.85 | +| c3a_fold | 72.09 | 3 | 216.27 | +| c3ab_fold | 7.79 | 3 | 23.38 | +| c3b_fold | 72.64 | 3 | 217.91 | +| c4ab_fold | 8.06 | 3 | 24.19 | +| node_fold | 18.46 | 3 | 55.38 | ### Aggregation jobs (`tracked_job_wall`) -| Operation | Avg (s) | Runs | Total (s) | -| ---------------------------- | ------- | ---- | --------- | -| ZkDecryptedSharesAggregation | 1.59 | 1 | 1.59 | -| ZkDecryptionAggregation | 49.68 | 1 | 49.68 | -| ZkDkgAggregation | 5.74 | 1 | 5.74 | -| ZkNodeDkgFold | 108.81 | 3 | 326.44 | -| ZkPkAggregation | 0.30 | 1 | 0.30 | +| Operation | Avg (s) | Runs | Total (s) | +|-----------|---------|------|-----------| +| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | +| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | +| ZkDkgAggregation | 5.56 | 1 | 5.56 | +| ZkNodeDkgFold | 107.17 | 3 | 321.51 | +| ZkPkAggregation | 0.40 | 1 | 0.40 | -Sum of aggregation job tracked time: **383.75 s** (parallel CPU work; not P1/P2 wall clock). +Sum of aggregation job tracked time: **377.52 s** (parallel CPU work; not P1/P2 wall clock). ### Folded on-chain artifacts (exported for Π_DKG / Π_dec gas) -| Artifact | Proof (bytes) | Public inputs (bytes) | -| --------------------- | ------------- | --------------------- | -| dkg_aggregator | 10944 | 384 | -| decryption_aggregator | 10944 | 3616 | +| Artifact | Proof (bytes) | Public inputs (bytes) | +|----------|---------------|------------------------| +| dkg_aggregator | 10944 | 384 | +| decryption_aggregator | 10944 | 3648 | ## Raw circuit benchmark JSON (Nargo) -Source files for the **Circuit Benchmarks** table. Persist this directory with -`crisp_verify_gas.json` (and optional `integration_summary.json`) to regenerate the report without -re-running the integration test. - -| File | -| ----------------------------------------------------- | -| `dkg_e_sm_share_computation_default.json` | -| `dkg_pk_default.json` | -| `dkg_share_decryption_default.json` | -| `dkg_share_encryption_default.json` | -| `dkg_sk_share_computation_default.json` | +Source files for the **Circuit Benchmarks** table. Persist this directory with `crisp_verify_gas.json` (and optional `integration_summary.json`) to regenerate the report without re-running the integration test. + +| File | +|------| +| `dkg_e_sm_share_computation_default.json` | +| `dkg_pk_default.json` | +| `dkg_share_decryption_default.json` | +| `dkg_share_encryption_default.json` | +| `dkg_sk_share_computation_default.json` | | `threshold_decrypted_shares_aggregation_default.json` | -| `threshold_pk_aggregation_default.json` | -| `threshold_pk_generation_default.json` | -| `threshold_share_decryption_default.json` | -| `threshold_user_data_encryption_ct0_default.json` | -| `threshold_user_data_encryption_ct1_default.json` | +| `threshold_pk_aggregation_default.json` | +| `threshold_pk_generation_default.json` | +| `threshold_share_decryption_default.json` | +| `threshold_user_data_encryption_ct0_default.json` | +| `threshold_user_data_encryption_ct1_default.json` | ## Notes -- All nodes are executed on the same machine in this benchmark run, so inter-node network latency is - effectively 0. +- All nodes are executed on the same machine in this benchmark run, so inter-node network latency is effectively 0. diff --git a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr index 0bdede3231..acc7034277 100644 --- a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr +++ b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr @@ -78,6 +78,7 @@ fn main( committee_hash_lo: pub Field, domain_hi: pub Field, domain_lo: pub Field, + ciphertext_commitment: 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); @@ -91,6 +92,15 @@ fn main( assert(c6_fold_public[4] == domain_hi); assert(c6_fold_public[5] == domain_lo); + // Every C6 leaf commits to the same decoded BFV ciphertext. Expose that + // canonical commitment as a final public input for the EVM wrapper. + for i in 0..(T + 1) { + assert( + c6_fold_public[C6_FOLD_PREFIX_LEN + C6_FOLD_CT_COL_OFFSET + i] + == ciphertext_commitment, + ); + } + // Cross-circuit C6 to C7: each folded `d_commitment` column entry must match `c7_public[i]` // (leading `T + 1` words of `c7_public`). for i in 0..(T + 1) { diff --git a/crates/compute-provider/src/ciphertext_output.rs b/crates/compute-provider/src/ciphertext_output.rs index cfb020a644..330b973ed5 100644 --- a/crates/compute-provider/src/ciphertext_output.rs +++ b/crates/compute-provider/src/ciphertext_output.rs @@ -15,6 +15,7 @@ pub trait ComputeProvider { #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct ComputeResult { pub ciphertext_hash: Vec, + pub ciphertext_commitment: Vec, pub params_hash: Vec, pub merkle_root: Vec, } diff --git a/crates/compute-provider/src/compute_input.rs b/crates/compute-provider/src/compute_input.rs index fd8e749fc4..6498abde95 100644 --- a/crates/compute-provider/src/compute_input.rs +++ b/crates/compute-provider/src/compute_input.rs @@ -6,6 +6,8 @@ use crate::ciphertext_output::ComputeResult; use crate::merkle_tree_builder::MerkleTreeBuilder; +use e3_bfv_client::client::compute_ct_commitment; +use e3_fhe_params::decode_bfv_params; use sha3::{Digest, Keccak256}; pub type FHEProcessor = fn(&FHEInputs) -> Vec; @@ -27,6 +29,16 @@ impl ComputeInput { pub fn process(&self, fhe_processor: FHEProcessor) -> ComputeResult { let processed_ciphertext = (fhe_processor)(&self.fhe_inputs); let processed_hash = Keccak256::digest(&processed_ciphertext).to_vec(); + let params = + decode_bfv_params(&self.fhe_inputs.params).expect("Failed to decode BFV params"); + let ciphertext_commitment = compute_ct_commitment( + processed_ciphertext.clone(), + params.degree(), + params.plaintext(), + params.moduli().to_vec(), + ) + .expect("Failed to compute ciphertext commitment") + .to_vec(); let params_hash = Keccak256::digest(&self.fhe_inputs.params).to_vec(); assert_eq!( @@ -42,6 +54,7 @@ impl ComputeInput { ComputeResult { ciphertext_hash: processed_hash, + ciphertext_commitment, params_hash, merkle_root: hex::decode(merkle_root).unwrap(), } diff --git a/crates/data/src/commit_log_event_log.rs b/crates/data/src/commit_log_event_log.rs index 013d0e903d..f3acb0e5b7 100644 --- a/crates/data/src/commit_log_event_log.rs +++ b/crates/data/src/commit_log_event_log.rs @@ -679,6 +679,7 @@ mod tests { CiphertextOutputPublished { e3_id: e3_id.clone(), ciphertext_output: vec![empty.clone()], + ciphertext_commitment: [0u8; 32], } .into(), ), diff --git a/crates/events/src/interfold_event/ciphertext_output_published.rs b/crates/events/src/interfold_event/ciphertext_output_published.rs index 6e7efebc88..bc047dd416 100644 --- a/crates/events/src/interfold_event/ciphertext_output_published.rs +++ b/crates/events/src/interfold_event/ciphertext_output_published.rs @@ -15,6 +15,7 @@ use std::fmt::{self, Display}; pub struct CiphertextOutputPublished { pub e3_id: E3id, pub ciphertext_output: Vec, + pub ciphertext_commitment: [u8; 32], } impl Display for CiphertextOutputPublished { diff --git a/crates/evm-helpers/src/contracts.rs b/crates/evm-helpers/src/contracts.rs index 4a24987bef..2d75321e40 100644 --- a/crates/evm-helpers/src/contracts.rs +++ b/crates/evm-helpers/src/contracts.rs @@ -7,7 +7,7 @@ use alloy::providers::fillers::BlobGasFiller; use alloy::{ network::{Ethereum, EthereumWallet}, - primitives::{Address, Bytes, U256}, + primitives::{Address, Bytes, B256, U256}, providers::fillers::{ ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, WalletFiller, }, @@ -62,6 +62,7 @@ sol! { bytes32 ciphertextOutput; bytes plaintextOutput; address requester; + bytes32 ciphertextCommitment; } #[derive(Debug)] @@ -123,7 +124,7 @@ sol! { mapping(address e3Program => bool allowed) public e3Programs; function request(E3RequestParams calldata requestParams) external returns (uint256 e3Id, E3 memory e3); function registerE3Program(address e3Program) public; - function publishCiphertextOutput(uint256 e3Id, bytes calldata ciphertextOutput, bytes calldata proof) external returns (bool success); + function publishCiphertextOutput(uint256 e3Id, bytes calldata ciphertextOutput, bytes32 ciphertextCommitment, bytes calldata proof) external returns (bool success); function publishPlaintextOutput(uint256 e3Id, bytes calldata data, bytes calldata proof) external returns (bool success); function getE3(uint256 e3Id) external view returns (E3 memory e3); function paramSetRegistry(uint8 paramSet) external view returns (bytes memory encodedParams); @@ -198,6 +199,7 @@ pub trait InterfoldWrite { &self, e3_id: U256, data: Bytes, + ciphertext_commitment: B256, proof: Bytes, ) -> Result; @@ -481,6 +483,7 @@ impl InterfoldWrite for InterfoldContract { &self, e3_id: U256, data: Bytes, + ciphertext_commitment: B256, proof: Bytes, ) -> Result { let _guard = NONCE_LOCK.lock().await; @@ -491,7 +494,7 @@ impl InterfoldWrite for InterfoldContract { let contract = Interfold::new(self.contract_address, &self.provider); let builder = contract - .publishCiphertextOutput(e3_id, data, proof) + .publishCiphertextOutput(e3_id, data, ciphertext_commitment, proof) .nonce(nonce); let receipt = builder.send().await?.get_receipt().await?; e3_utils::require_successful_receipt("publish ciphertext output", &receipt)?; diff --git a/crates/evm-helpers/src/events.rs b/crates/evm-helpers/src/events.rs index 21330e3fe3..2206bde29c 100644 --- a/crates/evm-helpers/src/events.rs +++ b/crates/evm-helpers/src/events.rs @@ -50,10 +50,11 @@ sol! { bytes32 ciphertextOutput; bytes plaintextOutput; address requester; + bytes32 ciphertextCommitment; } #[derive(Debug)] - event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput); + event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput, bytes32 ciphertextCommitment); #[derive(Debug)] event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); diff --git a/crates/evm-helpers/tests/fixtures/fake_interfold.sol b/crates/evm-helpers/tests/fixtures/fake_interfold.sol index db3d81d650..d54d5391b2 100644 --- a/crates/evm-helpers/tests/fixtures/fake_interfold.sol +++ b/crates/evm-helpers/tests/fixtures/fake_interfold.sol @@ -8,7 +8,7 @@ pragma solidity >=0.4.24; contract FakeInterfold { event InputPublished(uint256 indexed e3Id, bytes data, uint256 inputHash, uint256 index); - event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput); + event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput, bytes32 ciphertextCommitment); event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); event CommitteePublished(uint256 indexed e3Id, address[] nodes, bytes publicKey, bytes32 pkCommitment, bytes proof); @@ -20,8 +20,8 @@ contract FakeInterfold { } // Emit CiphertextOutputPublished event with passed test data - function emitCiphertextOutputPublished(uint256 e3Id, bytes memory ciphertextOutput) public { - emit CiphertextOutputPublished(e3Id, ciphertextOutput); + function emitCiphertextOutputPublished(uint256 e3Id, bytes memory ciphertextOutput, bytes32 ciphertextCommitment) public { + emit CiphertextOutputPublished(e3Id, ciphertextOutput, ciphertextCommitment); } // Emit PlaintextOutputPublished event with passed test data @@ -48,7 +48,8 @@ contract FakeInterfold { customParams: abi.encode("custom_params"), committeePublicKey: bytes32(keccak256("committee_public_key")), ciphertextOutput: bytes32(keccak256("encrypted_data")), - plaintextOutput: abi.encode("decrypted_result") + plaintextOutput: abi.encode("decrypted_result"), + ciphertextCommitment: bytes32(keccak256("ciphertext_commitment")) }); } } @@ -66,4 +67,5 @@ struct E3 { bytes32 committeePublicKey; bytes32 ciphertextOutput; bytes plaintextOutput; + bytes32 ciphertextCommitment; } diff --git a/crates/evm/src/contracts.rs b/crates/evm/src/contracts.rs index f9b8395da5..204a44a9ce 100644 --- a/crates/evm/src/contracts.rs +++ b/crates/evm/src/contracts.rs @@ -36,6 +36,7 @@ sol! { bytes32 ciphertextOutput; bytes plaintextOutput; address requester; + bytes32 ciphertextCommitment; } // ── Write functions ───────────────────────────────────────────────── @@ -53,7 +54,7 @@ sol! { // ── Events ────────────────────────────────────────────────────────── event E3Requested(uint256 e3Id, E3 e3, address indexed e3Program); event InputPublished(uint256 indexed e3Id, bytes data, uint256 inputHash, uint256 index); - event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput); + event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput, bytes32 ciphertextCommitment); event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); event RewardsDistributed(uint256 indexed e3Id, address[] nodes, uint256[] amounts); event RewardCredited(uint256 indexed e3Id, address indexed account, address indexed token, uint256 amount); diff --git a/crates/evm/src/interfold/events.rs b/crates/evm/src/interfold/events.rs index 4f90e1ce83..6f995b2584 100644 --- a/crates/evm/src/interfold/events.rs +++ b/crates/evm/src/interfold/events.rs @@ -106,6 +106,7 @@ impl From for e3_events::CiphertextOutputP // XXX: Ciphertext is an array of bytes this needs to be coordinated with interfold // contract ciphertext_output: vec![ArcBytes::from_bytes(value.0.ciphertextOutput.as_ref())], + ciphertext_commitment: value.0.ciphertextCommitment.into(), } } } diff --git a/crates/indexer/src/indexer.rs b/crates/indexer/src/indexer.rs index e560889019..0123c64835 100644 --- a/crates/indexer/src/indexer.rs +++ b/crates/indexer/src/indexer.rs @@ -379,6 +379,7 @@ impl InterfoldIndexer { chain_id: ctx.chain_id(), ciphertext_inputs: vec![], ciphertext_output: vec![], + ciphertext_commitment: vec![], committee_public_key: e.publicKey.to_vec(), custom_params: e3.customParams.to_vec(), e3_params: e3_params.to_vec(), @@ -417,6 +418,8 @@ impl InterfoldIndexer { let mut repo = E3Repository::new(store, e3_id); repo.set_ciphertext_output(e.ciphertextOutput.to_vec()) .await?; + repo.set_ciphertext_commitment(e.ciphertextCommitment.to_vec()) + .await?; Ok(()) }) diff --git a/crates/indexer/src/models.rs b/crates/indexer/src/models.rs index 5003eab05e..9f5cc5066e 100644 --- a/crates/indexer/src/models.rs +++ b/crates/indexer/src/models.rs @@ -14,6 +14,8 @@ pub struct E3 { pub chain_id: u64, pub ciphertext_inputs: Vec<(Vec, u64)>, pub ciphertext_output: Vec, + #[serde(default)] + pub ciphertext_commitment: Vec, pub committee_public_key: Vec, pub e3_params: Vec, pub custom_params: Vec, diff --git a/crates/indexer/src/repo.rs b/crates/indexer/src/repo.rs index 61c58042ed..bc592423b9 100644 --- a/crates/indexer/src/repo.rs +++ b/crates/indexer/src/repo.rs @@ -78,6 +78,20 @@ impl E3Repository { Ok(()) } + pub async fn set_ciphertext_commitment(&mut self, data: Vec) -> Result<()> { + let key = self.e3_key(); + self.store + .modify(&key, |e3_obj: Option| { + e3_obj.map(|mut e| { + e.ciphertext_commitment = data.clone(); + e + }) + }) + .await + .map_err(|_| eyre::eyre!("Could not set ciphertext_commitment for '{key}'"))?; + Ok(()) + } + fn e3_key(&self) -> String { let e3_id = self.e3_id; format!("_e3:{e3_id}") diff --git a/crates/indexer/tests/fixtures/fake_interfold.sol b/crates/indexer/tests/fixtures/fake_interfold.sol index 548b4eb46f..2bb5ef8428 100644 --- a/crates/indexer/tests/fixtures/fake_interfold.sol +++ b/crates/indexer/tests/fixtures/fake_interfold.sol @@ -8,7 +8,7 @@ pragma solidity >=0.4.24; contract FakeInterfold { event InputPublished(uint256 indexed e3Id, bytes data, uint256 inputHash, uint256 index); - event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput); + event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput, bytes32 ciphertextCommitment); event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput, bytes proof); event CommitteePublished(uint256 indexed e3Id, address[] nodes, bytes publicKey, bytes32 pkCommitment, bytes proof); @@ -20,8 +20,8 @@ contract FakeInterfold { } // Emit CiphertextOutputPublished event with passed test data - function emitCiphertextOutputPublished(uint256 e3Id, bytes memory ciphertextOutput) public { - emit CiphertextOutputPublished(e3Id, ciphertextOutput); + function emitCiphertextOutputPublished(uint256 e3Id, bytes memory ciphertextOutput, bytes32 ciphertextCommitment) public { + emit CiphertextOutputPublished(e3Id, ciphertextOutput, ciphertextCommitment); } // Emit PlaintextOutputPublished event with passed test data @@ -50,7 +50,8 @@ contract FakeInterfold { committeePublicKey: bytes32(keccak256("committee_public_key")), ciphertextOutput: bytes32(keccak256("encrypted_data")), plaintextOutput: abi.encode("decrypted_result"), - requester: 0xdead000000000000000000000000000000000001 + requester: 0xdead000000000000000000000000000000000001, + ciphertextCommitment: bytes32(keccak256("ciphertext_commitment")) }); } } @@ -76,4 +77,5 @@ struct E3 { bytes32 ciphertextOutput; bytes plaintextOutput; address requester; + bytes32 ciphertextCommitment; } diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index ddde7b2f5e..2062d65474 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -6,7 +6,7 @@ mod helpers; use alloy::{ - primitives::{Bytes, Uint}, + primitives::{Bytes, Uint, B256}, sol, }; use e3_bfv_client::compute_pk_commitment; @@ -188,6 +188,7 @@ async fn test_indexer() -> Result<()> { .emitCiphertextOutputPublished( Uint::from(E3_ID), Bytes::from(ciphertext_output_data.clone()), + B256::ZERO, ) .send() .await? @@ -202,6 +203,7 @@ async fn test_indexer() -> Result<()> { e3_state_after_output.ciphertext_output, ciphertext_output_data ); + assert_eq!(e3_state_after_output.ciphertext_commitment, vec![0u8; 32]); let store = indexer.get_store(); let total_inputs_processed = store.get::("input_count").await?.unwrap(); diff --git a/crates/support/README.md b/crates/support/README.md index 96b0eaa366..15bede1830 100644 --- a/crates/support/README.md +++ b/crates/support/README.md @@ -195,7 +195,7 @@ The program server: The callback server (e.g., CRISP) receives the webhook and calls: ```solidity -interfold.publishCiphertextOutput(e3Id, ciphertextOutput, proof); +interfold.publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof); ``` This transitions the E3 stage to `CiphertextReady`. diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index 6b6610280f..4aad3c6468 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -1835,6 +1835,7 @@ async fn test_trbfv_actor() -> Result<()> { let ciphertext_published_event = CiphertextOutputPublished { ciphertext_output: ciphertexts, e3_id: e3_id.clone(), + ciphertext_commitment: [0u8; 32], }; bus.publish_without_context(ciphertext_published_event.clone())?; @@ -2616,6 +2617,7 @@ async fn test_stopped_keyshares_retain_state() -> Result<()> { .map(|ct| ArcBytes::from_bytes(&ct.to_bytes())) .collect(), e3_id: e3_id.clone(), + ciphertext_commitment: [0u8; 32], })?; let history = history_collector 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 0198e4a075..5e08848f62 100644 --- a/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs +++ b/crates/zk-prover/src/circuits/aggregation/node_dkg_fold.rs @@ -555,6 +555,7 @@ struct DecryptionAggregatorWitness { committee_hash_lo: String, domain_hi: String, domain_lo: String, + ciphertext_commitment: String, } /// Prove [`CircuitName::DecryptionAggregator`] for each job (C6 fold + C7), with @@ -617,6 +618,14 @@ pub fn prove_decryption_aggregation_jobs( let domain_lo = c6_fold_public.get(5).cloned().ok_or_else(|| { ZkError::InvalidInput("C6 fold proof is missing domain_lo at public input 5".into()) })?; + let ciphertext_commitment = c6_fold_public + .get(6 + (2 * c6_total_slots)) + .cloned() + .ok_or_else(|| { + ZkError::InvalidInput( + "C6 fold proof is missing the ciphertext commitment column".into(), + ) + })?; let witness = DecryptionAggregatorWitness { c6_fold_vk: c6_fold_vk.verification_key.clone(), @@ -632,6 +641,7 @@ pub fn prove_decryption_aggregation_jobs( committee_hash_lo: committee_hash_lo.clone(), domain_hi, domain_lo, + ciphertext_commitment, }; let json = serde_json::to_value(&witness) diff --git a/docs/pages/cryptography.mdx b/docs/pages/cryptography.mdx index 9d29e63546..d0b53fa1ef 100644 --- a/docs/pages/cryptography.mdx +++ b/docs/pages/cryptography.mdx @@ -479,8 +479,10 @@ decodes modulo **t**; it runs once at the aggregator after enough valid **C6** p **C6** proves a partial decryption share **d** built from the output ciphertext, the node’s Shamir shares of the threshold secret and smudging noise (from **C4**), and reduction quotients. Each C6 proof also carries the common E3 decryption-domain limbs that are preserved through folding and -checked by the on-chain wrapper—schematically per CRT limb (see -`verify_decryption_share_computation` in `share_decryption.nr`): +checked by the on-chain wrapper. C6 also recomputes the circuit-compatible SAFE commitment from the +decoded `ct0`/`ct1` CRT polynomials; the final decryption proof exposes that commitment for +comparison with the off-chain commitment stored at ciphertext publication—schematically per CRT limb +(see `verify_decryption_share_computation` in `share_decryption.nr`): ```math d^{[\ell]}(\gamma) = \mathrm{ct}_0^{[\ell]}(\gamma) + \mathrm{ct}_1^{[\ell]}(\gamma)\,\mathrm{sk}^{[\ell]}(\gamma) + e_{\mathrm{sm}}^{[\ell]}(\gamma) + r_2^{[\ell]}(\gamma)(\gamma^N+1) + r_1^{[\ell]}(\gamma)\,q_\ell diff --git a/docs/pages/internals/dkg.mdx b/docs/pages/internals/dkg.mdx index 3045fc740d..28b3a0b278 100644 --- a/docs/pages/internals/dkg.mdx +++ b/docs/pages/internals/dkg.mdx @@ -520,11 +520,12 @@ for the full contract. The decryption recursive proof (`BfvDecryptionVerifier`) follows the same shape: a recursive Honk proof aggregates **C6** from at least **T+1** parties plus **C7**, carries a domain over the chain, deployment, E3, committee, ciphertext, and committee-key context, and surfaces the party IDs plus -`expected_sk_commits[]` and `expected_esm_commits[]` per party. The wrapper receives `e3Id` -separately so it can compare those surfaced commitments against the anchors stored at -`publishCommittee`; if any anchor differs, or if the E3 domain differs, the proof is rejected. The -plaintext is decoded from the proof's last 100 public inputs (one `uint64` coefficient each, packed -into bytes). +`ciphertextCommitment`, `expected_sk_commits[]`, and `expected_esm_commits[]` per party. The wrapper +receives `e3Id` separately so it can compare those surfaced commitments against the anchors stored +at `publishCommittee`; it also compares `ciphertextCommitment` with the SAFE commitment stored at +ciphertext publication. If any anchor differs, the commitment differs, or the E3 domain differs, the +proof is rejected. The plaintext is decoded from the proof's last 100 public inputs (one `uint64` +coefficient each, packed into bytes). ### Slashing-evidence binding diff --git a/docs/pages/sdk.mdx b/docs/pages/sdk.mdx index fa126eff67..c5485130bb 100644 --- a/docs/pages/sdk.mdx +++ b/docs/pages/sdk.mdx @@ -366,8 +366,8 @@ that wraps or complements the core Interfold SDK. - **Historical events**: `sdk.getHistoricalEvents(type, fromBlock, toBlock)` fetches logs without a WebSocket provider; useful for CRON jobs or health checks. - **Publish ciphertext output**: - `sdk.publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit?)` submits the computed - ciphertext output for an E3. + `sdk.publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof, gasLimit?)` + submits the computed ciphertext output for an E3. - **Gas controls**: pass `gasLimit` to `requestE3`, `publishCiphertextOutput`, or other write methods if you want fixed limits when interacting with Interfold on L2s. - **Gas estimation**: `sdk.estimateGas(functionName, args, contractAddress, abi)` returns the diff --git a/examples/CRISP/server/src/server/models.rs b/examples/CRISP/server/src/server/models.rs index 7ae99cffee..8804c4c74f 100644 --- a/examples/CRISP/server/src/server/models.rs +++ b/examples/CRISP/server/src/server/models.rs @@ -20,6 +20,9 @@ pub enum WebhookPayload { ciphertext: Vec, #[serde(deserialize_with = "deserialize_hex_string")] #[derivative(Debug = "ignore")] + ciphertext_commitment: Vec, + #[serde(deserialize_with = "deserialize_hex_string")] + #[derivative(Debug = "ignore")] proof: Vec, }, Failed { diff --git a/examples/CRISP/server/src/server/routes/state.rs b/examples/CRISP/server/src/server/routes/state.rs index 6209d272eb..7fc2710cd8 100644 --- a/examples/CRISP/server/src/server/routes/state.rs +++ b/examples/CRISP/server/src/server/routes/state.rs @@ -15,7 +15,7 @@ use crate::server::{ CONFIG, }; use actix_web::{web, HttpResponse, Responder}; -use alloy::primitives::{Address, Bytes, U256}; +use alloy::primitives::{Address, B256, Bytes, U256}; use e3_sdk::evm_helpers::contracts::{ InterfoldContract, InterfoldContractFactory, InterfoldWrite, ReadWrite, }; @@ -129,6 +129,7 @@ async fn handle_program_server_result(data: web::Json) -> impl R WebhookPayload::Completed { e3_id, ciphertext, + ciphertext_commitment, proof, } => { info!( @@ -148,6 +149,11 @@ async fn handle_program_server_result(data: web::Json) -> impl R .json(format!("Computation completed for E3 ID: {}", e3_id)); } + if ciphertext_commitment.len() != 32 { + return HttpResponse::BadRequest() + .body("ciphertext_commitment must be exactly 32 bytes"); + } + // Create the contract let contract: InterfoldContract = match InterfoldContractFactory::create_write( @@ -170,6 +176,7 @@ async fn handle_program_server_result(data: web::Json) -> impl R .publish_ciphertext_output( U256::from(e3_id), Bytes::from(ciphertext.clone()), + B256::from_slice(&ciphertext_commitment), Bytes::from(proof.clone()), ) .await; diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index 4f6ffaf51f..b5878d89eb 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -1338,5 +1338,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-2d3d2b6b440530e2d0cda7f925e842c7cd652fec" + "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index e0fac11e91..e89f2c9031 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -1345,5 +1345,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-2d3d2b6b440530e2d0cda7f925e842c7cd652fec" + "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json b/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json index cb19928ddd..92fb501ec6 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json @@ -491,6 +491,12 @@ "internalType": "bytes", "name": "ciphertextOutput", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "ciphertextCommitment", + "type": "bytes32" } ], "name": "CiphertextOutputPublished", @@ -697,6 +703,11 @@ "internalType": "address", "name": "requester", "type": "address" + }, + { + "internalType": "bytes32", + "name": "ciphertextCommitment", + "type": "bytes32" } ], "indexed": false, @@ -1484,6 +1495,11 @@ "internalType": "address", "name": "requester", "type": "address" + }, + { + "internalType": "bytes32", + "name": "ciphertextCommitment", + "type": "bytes32" } ], "internalType": "struct E3", @@ -1901,6 +1917,11 @@ "name": "ciphertextOutput", "type": "bytes" }, + { + "internalType": "bytes32", + "name": "ciphertextCommitment", + "type": "bytes32" + }, { "internalType": "bytes", "name": "proof", @@ -2078,6 +2099,11 @@ "internalType": "address", "name": "requester", "type": "address" + }, + { + "internalType": "bytes32", + "name": "ciphertextCommitment", + "type": "bytes32" } ], "internalType": "struct E3", @@ -2376,5 +2402,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IInterfold.sol", - "buildInfoId": "solc-0_8_28-2d3d2b6b440530e2d0cda7f925e842c7cd652fec" + "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index 9ec078df51..f44acf9268 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -1432,5 +1432,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-2d3d2b6b440530e2d0cda7f925e842c7cd652fec" + "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" } \ No newline at end of file diff --git a/packages/interfold-contracts/contracts/Interfold.sol b/packages/interfold-contracts/contracts/Interfold.sol index d714936c6d..260d6fa5a8 100644 --- a/packages/interfold-contracts/contracts/Interfold.sol +++ b/packages/interfold-contracts/contracts/Interfold.sol @@ -359,6 +359,7 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { function publishCiphertextOutput( uint256 e3Id, bytes calldata ciphertextOutput, + bytes32 ciphertextCommitment, bytes calldata proof ) external returns (bool success) { E3 memory e3 = getE3(e3Id); @@ -380,6 +381,7 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { bytes32 ciphertextOutputHash = keccak256(ciphertextOutput); e3s[e3Id].ciphertextOutput = ciphertextOutputHash; + e3s[e3Id].ciphertextCommitment = ciphertextCommitment; _e3Stages[e3Id] = E3Stage.CiphertextReady; _e3Deadlines[e3Id].decryptionDeadline = block.timestamp + @@ -388,7 +390,11 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { (success) = e3.e3Program.verify(e3Id, ciphertextOutputHash, proof); require(success, InvalidOutput(ciphertextOutput)); - emit CiphertextOutputPublished(e3Id, ciphertextOutput); + emit CiphertextOutputPublished( + e3Id, + ciphertextOutput, + ciphertextCommitment + ); emit E3StageChanged( e3Id, E3Stage.KeyPublished, @@ -450,6 +456,7 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { e3.ciphertextOutput, e3.committeePublicKey, plaintextHash, + e3.ciphertextCommitment, proof ); } diff --git a/packages/interfold-contracts/contracts/interfaces/IDecryptionVerifier.sol b/packages/interfold-contracts/contracts/interfaces/IDecryptionVerifier.sol index b7550f1e1a..8637500fb9 100644 --- a/packages/interfold-contracts/contracts/interfaces/IDecryptionVerifier.sol +++ b/packages/interfold-contracts/contracts/interfaces/IDecryptionVerifier.sol @@ -16,6 +16,7 @@ pragma solidity 0.8.28; * - a domain-binding slot supplied by Interfold and derived from * (chainId, Interfold address, e3Id, committeeHash, * ciphertextOutputHash, committeePublicKey) + * - the final proof's SAFE ciphertext commitment matches the commitment stored for the E3 * and reverts on any mismatch. */ interface IDecryptionVerifier { @@ -23,8 +24,8 @@ interface IDecryptionVerifier { /// verifier rejected it. Used in place of a `bool false` return. error InvalidProof(); /// @notice `publicInputs` is shorter than the layout the wrapper expects - /// (must hold the two VK-hash slots, the domain-binding slot and the - /// 100 message-coefficient slots). + /// (must hold the two VK-hash slots, domain and ciphertext-binding + /// slots, and the 100 message-coefficient slots). error InvalidPublicInputsLength(); /// @notice One of the recursive-aggregation sub-circuit VK hashes embedded /// in the proof does not match the immutable value committed at @@ -36,6 +37,8 @@ interface IDecryptionVerifier { /// @notice The domain-binding public-input slot does not equal the value /// recomputed on-chain from the call context. error DomainBindingMismatch(); + /// @notice The proof's SAFE ciphertext commitment does not match the E3 commitment. + error CiphertextCommitmentMismatch(); /// @notice A `party_id` returned by the proof is not present in the /// registry's stored DKG anchors for this E3. error DkgAnchorNotFound(); @@ -51,6 +54,7 @@ interface IDecryptionVerifier { /// committeeHash, ciphertextOutputHash, committeePublicKey))`. /// @param plaintextOutputHash `keccak256(plaintextOutput)` expected by the Interfold. /// @param committeeHash `keccak256(abi.encodePacked(topNodes))` for the on-chain committee. + /// @param ciphertextCommitment Circuit-compatible SAFE commitment to the decoded BFV ciphertext. /// @param proof ABI-encoded `(bytes rawProof, bytes32[] publicInputs)`. /// @return success Always `true` on success; the wrapper reverts on any failure. function verify( @@ -58,6 +62,7 @@ interface IDecryptionVerifier { bytes32 decryptionDomain, bytes32 plaintextOutputHash, bytes32 committeeHash, + bytes32 ciphertextCommitment, bytes calldata proof ) external view returns (bool success); } diff --git a/packages/interfold-contracts/contracts/interfaces/IE3.sol b/packages/interfold-contracts/contracts/interfaces/IE3.sol index 1f53b57c85..b3e0471ef2 100644 --- a/packages/interfold-contracts/contracts/interfaces/IE3.sol +++ b/packages/interfold-contracts/contracts/interfaces/IE3.sol @@ -25,7 +25,8 @@ import { IInterfold } from "./IInterfold.sol"; * @param customParams Arbitrary ABI-encoded application-defined parameters. * @param decryptionVerifier Address of the output verifier contract for decryption verification * @param committeePublicKey Hash of the public key of the selected committee for this computation - * @param ciphertextOutput Hash of the encrypted output data produced by the computation + * @param ciphertextOutput Keccak hash of the serialized encrypted output data produced by the computation + * @param ciphertextCommitment SAFE commitment to the decoded BFV ciphertext used by the decryption proof * @param plaintextOutput Decrypted output data after committee decryption * @param requester Address of the entity that requested the E3 computation */ @@ -44,4 +45,5 @@ struct E3 { bytes32 ciphertextOutput; bytes plaintextOutput; address requester; + bytes32 ciphertextCommitment; } diff --git a/packages/interfold-contracts/contracts/interfaces/IInterfold.sol b/packages/interfold-contracts/contracts/interfaces/IInterfold.sol index acf74791fc..f0c31c0f23 100644 --- a/packages/interfold-contracts/contracts/interfaces/IInterfold.sol +++ b/packages/interfold-contracts/contracts/interfaces/IInterfold.sol @@ -137,9 +137,11 @@ interface IInterfold { /// is successfully published. /// @param e3Id ID of the E3. /// @param ciphertextOutput ABI encoded ciphertext output. + /// @param ciphertextCommitment Circuit-compatible SAFE commitment to the decoded BFV ciphertext. event CiphertextOutputPublished( uint256 indexed e3Id, - bytes ciphertextOutput + bytes ciphertextOutput, + bytes32 ciphertextCommitment ); /// @notice This event MUST be emitted any time the `maxDuration` is set. @@ -521,11 +523,13 @@ interface IInterfold { /// @dev This function MUST emit the CiphertextOutputPublished event. /// @param e3Id ID of the E3. /// @param ciphertextOutput ABI encoded output data to verify. + /// @param ciphertextCommitment Circuit-compatible SAFE commitment to the decoded BFV ciphertext. /// @param proof ABI encoded data to verify the ciphertextOutput. /// @return success True if the output was successfully published. function publishCiphertextOutput( uint256 e3Id, bytes calldata ciphertextOutput, + bytes32 ciphertextCommitment, bytes calldata proof ) external returns (bool success); diff --git a/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol b/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol index 699dcfdc9e..2f22c59c67 100644 --- a/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol +++ b/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol @@ -80,6 +80,7 @@ library InterfoldPricing { bytes32 ciphertextHash, bytes32 committeePublicKey, bytes32 plaintextHash, + bytes32 ciphertextCommitment, bytes calldata proof ) external view { bytes32 committeeHash = ICiphernodeRegistry(registryAddress) @@ -99,6 +100,7 @@ library InterfoldPricing { decryptionDomain, plaintextHash, committeeHash, + ciphertextCommitment, proof ); } diff --git a/packages/interfold-contracts/contracts/test/MockDecryptionVerifier.sol b/packages/interfold-contracts/contracts/test/MockDecryptionVerifier.sol index 87b088d32f..697e604223 100644 --- a/packages/interfold-contracts/contracts/test/MockDecryptionVerifier.sol +++ b/packages/interfold-contracts/contracts/test/MockDecryptionVerifier.sol @@ -18,6 +18,7 @@ contract MockDecryptionVerifier is IDecryptionVerifier { bytes32, bytes32, bytes32, + bytes32, bytes calldata proof ) external pure returns (bool success) { if (proof.length >= 4 && bytes4(proof[0:4]) == _FAIL_MAGIC) { diff --git a/packages/interfold-contracts/contracts/test/MockE3Program.sol b/packages/interfold-contracts/contracts/test/MockE3Program.sol index 776ff69d3f..2a01a412d7 100644 --- a/packages/interfold-contracts/contracts/test/MockE3Program.sol +++ b/packages/interfold-contracts/contracts/test/MockE3Program.sol @@ -56,7 +56,12 @@ contract MockE3Program is IE3Program { // proxy. Do not copy this pattern into a production E3 program. // Pass `data` as the proof too so `MockE3Program.verify` (which // requires `proof.length > 0`) returns true. - interfold.publishCiphertextOutput(e3Id, data, data); + interfold.publishCiphertextOutput( + e3Id, + data, + keccak256(data), + data + ); } } diff --git a/packages/interfold-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol b/packages/interfold-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol index 1a330fdbbf..0337fb41e2 100644 --- a/packages/interfold-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol +++ b/packages/interfold-contracts/contracts/verifiers/bfv/BfvDecryptionVerifier.sol @@ -26,10 +26,11 @@ import { CommitteeHashLib } from "../../lib/CommitteeHashLib.sol"; * [3] = committee_hash_lo * [4] = decryption_domain_hi * [5] = decryption_domain_lo - * [6] = aggregate recursive VK key hash - * [7 .. 7+3*(T+1)) = party_ids, expected_sk, expected_esm columns + * [6] = ciphertext_commitment + * [7] = aggregate recursive VK key hash + * [8 .. 8+3*(T+1)) = party_ids, expected_sk, expected_esm columns * [last 100] = plaintext message coefficients (100 u64 LE) - * Total: expectedPublicInputsLen = 6 + 1 + 3*(T+1) + 100. + * Total: expectedPublicInputsLen = 7 + 1 + 3*(T+1) + 100. * * The two VK-hash slots are checked against contract immutables set at * construction; this anchors the recursive aggregation trust and @@ -45,10 +46,10 @@ import { CommitteeHashLib } from "../../lib/CommitteeHashLib.sol"; * preserves them, and DecryptionAggregator exposes them here, so an * aggregator cannot re-label an existing proof for another E3. * - * The domain prevents cross-context replay, while the DKG anchors bind - * the proof's secret-bearing commitments to the authenticated DKG output. - * The circuit still does not expose a ciphertext commitment that can be - * compared with the on-chain ciphertext hash. + * The domain prevents cross-context replay, the SAFE ciphertext commitment + * binds the final proof to the stored circuit-compatible commitment, and + * the DKG anchors bind the proof's secret-bearing commitments to the + * authenticated DKG output. */ contract BfvDecryptionVerifier is IDecryptionVerifier { error InvalidCircuitVerifier(address verifier); @@ -61,8 +62,7 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { uint256 internal constant DEC_RETURN_PREFIX_LEN = 1; /// @dev `decryption_aggregator` return columns after the leading key hash - /// (party_ids, expected_sk, expected_esm). There is no ciphertext - /// column here because the circuit does not expose one in its return tuple. + /// (party_ids, expected_sk, expected_esm). uint256 internal constant DEC_RETURN_COLUMN_COUNT = 3; /// @dev `publicInputs` index for `committee_hash_hi` (after sub-circuit key hashes). @@ -74,11 +74,12 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { /// @dev Public input indices for the E3 decryption-domain limbs. uint256 internal constant DECRYPTION_DOMAIN_HI_IDX = 4; uint256 internal constant DECRYPTION_DOMAIN_LO_IDX = 5; + uint256 internal constant CIPHERTEXT_COMMITMENT_IDX = 6; /// @notice BFV threshold `T`; must match the compiled DecryptionAggregator circuit. uint256 public immutable threshold; - /// @dev `6 + DEC_RETURN_PREFIX_LEN + DEC_RETURN_COLUMN_COUNT*(T+1) + MESSAGE_COEFFS_COUNT`. + /// @dev `7 + DEC_RETURN_PREFIX_LEN + DEC_RETURN_COLUMN_COUNT*(T+1) + MESSAGE_COEFFS_COUNT`. uint256 internal immutable expectedPublicInputsLen; /// @dev `publicInputs` start index of the `party_ids[T+1]` column. @@ -128,12 +129,12 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { ) revert InvalidVerificationKeyHash(); threshold = _threshold; expectedPublicInputsLen = - 6 + + 7 + DEC_RETURN_PREFIX_LEN + (DEC_RETURN_COLUMN_COUNT * (_threshold + 1)) + MESSAGE_COEFFS_COUNT; - partyIdColOffset = 6 + DEC_RETURN_PREFIX_LEN; + partyIdColOffset = 7 + DEC_RETURN_PREFIX_LEN; skColOffset = partyIdColOffset + (_threshold + 1); esmColOffset = skColOffset + (_threshold + 1); @@ -149,6 +150,7 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { bytes32 decryptionDomain, bytes32 plaintextOutputHash, bytes32 committeeHash, + bytes32 ciphertextCommitment, bytes calldata proof ) external view override returns (bool) { (bytes memory rawProof, bytes32[] memory publicInputs) = abi.decode( @@ -194,6 +196,10 @@ contract BfvDecryptionVerifier is IDecryptionVerifier { revert DomainBindingMismatch(); } + if (publicInputs[CIPHERTEXT_COMMITMENT_IDX] != ciphertextCommitment) { + revert CiphertextCommitmentMismatch(); + } + // Plaintext hash check: 100-coefficient plaintext must hash to the claimed value. if (!_verifyPlaintextHash(publicInputs, plaintextOutputHash)) { revert PlaintextHashMismatch(); diff --git a/packages/interfold-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol b/packages/interfold-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol index ca26559b0e..7dd582166f 100644 --- a/packages/interfold-contracts/contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol +++ b/packages/interfold-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 = 129; -uint256 constant VK_HASH = 0x3007c7ee30e1eab6a52c0fec9560fc4096b081a8c86e1b47ec1512c5280fa98b; +uint256 constant NUMBER_OF_PUBLIC_INPUTS = 130; +uint256 constant VK_HASH = 0x020f83657164668f3b39c3b5a9c40f3facb3249a8875f5ea26a8d3a61bfb128f; library HonkVerificationKey { function loadVerificationKey() internal @@ -18,149 +18,149 @@ library HonkVerificationKey { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(2097152), logCircuitSize: uint256(21), - publicInputsSize: uint256(129), + publicInputsSize: uint256(130), ql: Honk.G1Point({ x: uint256( - 0x26c761c1db2e0a6312b45b9583d8d57321c54d4cdafaa353a30803de1ea257b9 + 0x26e40978f90e392493d3d1c7aface709c48207ad973e9422ec45265388cd7613 ), y: uint256( - 0x13d3ee606ac490c68044940773f562f362b7a6e9c98f53702e200950b430f225 + 0x16e21edee9dccc132c9eacdfefcc4280e4ea22b8d970145b61deb3b5a6e7b07c ) }), qr: Honk.G1Point({ x: uint256( - 0x1633bd1e83fb45390712d99c698528639af4dc97d74918c5e030a433cdaa3134 + 0x258467421a5f0ebaa54afa7525ee713ec17fe18c778b574c756743b2de6960e4 ), y: uint256( - 0x2a7e087f47cf6ff97021c1b3a8d7ec2fe7d95b4c1bd9e38ddf8249e4ee291ec4 + 0x184ec77c38e13939791cddb5171b4fe836dc0b51cd33de51d2fb56e9ba4666f0 ) }), qo: Honk.G1Point({ x: uint256( - 0x039a9ae4a599b9663982c1366d9e85c3d8ac639f8425d2daa4b0246559b7d5b6 + 0x1e94e3b623e2f689f0f5ab011776d724b0e383b746a2f6d9293c9ebd06522703 ), y: uint256( - 0x0abc441a852ed7c936752b0a62297690e4f2296aeba34b553c499dde634b2188 + 0x155c5e7e803f5d4ec6a61af0630d13e86a527b7f8d8d83b84a67fd5128569a6e ) }), q4: Honk.G1Point({ x: uint256( - 0x00ac508ffc59f81de2305f7b340433fd6f3037ae87e9f16971e5a803cc7d76b3 + 0x28fc24cc37f1c8c140ba7853caba095b8442406cf4294a7bbaa27dc4c87f23d9 ), y: uint256( - 0x2efb6903b5bf3c77403d2fac605c8034ee70e7185f3a225f11ec82f101975a03 + 0x111907d2876c800be15b6dd8ab709d1c7c4c62fe47091dc46c8429b2c8c86bb5 ) }), qm: Honk.G1Point({ x: uint256( - 0x215efd61a94f7aa1702ef4617c153052137606b70d77054e252322d5d5e64ac7 + 0x08d7c25713da6496046ca1a952df7c02159fab93f1c28f8821aa991d9cac342b ), y: uint256( - 0x0c2eb9cf44c602ab2e40cfa8a9b87fac584eecaf592b67b5f6651c5d19a4badb + 0x069992d4c1fc42ae38c2649da941205fee6d13fd07c3f6de9b3632061feac8e0 ) }), qc: Honk.G1Point({ x: uint256( - 0x0a1a529e0e1ef341c69d05dbfca65a5860ecaa5be6e14bd3a0fedb729fb22bc7 + 0x0d11ab383d24fc5d4fcfdbc13b20673a30da66891408520330c0fab172a24e94 ), y: uint256( - 0x2626c476fc9e32a4fd44e43d5dadb7ddd1250c63564044561452702c6c281a4e + 0x1835ab498ab7c79d31b2af85d05a7a02bb98d20f790d9d22591f98fc471053c4 ) }), qLookup: Honk.G1Point({ x: uint256( - 0x0e01e2471d2cc58c36a2af88d7c457a0c643082e0ea549b50e64780288cddb33 + 0x2d208816f798766860756415b7643e2a5d6a04c740ae11c430de694c0259714e ), y: uint256( - 0x1bdf27437b6f422c586cd3ccef4cb4d8bb8b1cf1db74d99a6f85215f93af99f3 + 0x015504bb4744dbb532ef1937764a2481f0a3cf1919f42d70e3f2b442e1b5d7c0 ) }), qArith: Honk.G1Point({ x: uint256( - 0x02f72baa01ed565d9e6b7dcf87e97314f15f40270dee972816d363051071e340 + 0x0832cfd25e9750bd90d5d0a6c35ef96f00aa1a3a8b488c2fe4958040b60a7c2c ), y: uint256( - 0x1492abb616878d8dce325ca76eef28973d8fc5bb636c51c5214cc8dfddb14bd7 + 0x13c0235574c9b1b2bb0635f71efe2ee808ed2540460a42e8f5b8e8d056558f10 ) }), qDeltaRange: Honk.G1Point({ x: uint256( - 0x2027e34e97f08e318e02c16e9d22a8c5c07afa7e7710d4ab5011ac929acaec37 + 0x020c5b5c8acf2edd08db039af48bb903d9b3a0428aab8ffe273f961a4b28e359 ), y: uint256( - 0x255eacab70d19db0a35919f197feba1cdc4b213f6768153ad38b9e6581cf39aa + 0x1fd324f1721454e0e7e91ddd38330c2f98ba13a0579c4133434de3afaf6354de ) }), qElliptic: Honk.G1Point({ x: uint256( - 0x10406869a07dda6bf2a575195b0032897355adea655f89baef21bd698f6be7ef + 0x2a983d8e7b183cca275651ab6d7303078a1c19b760de1768daf968e578d36df0 ), y: uint256( - 0x2150dea61781cbe337ac831a74f43af0f0986824fc7104761554e79cd2c32e9e + 0x14a763e848e9c8c3c753259777801f199b47a1412f7a2ca98bafc30471e529ac ) }), qMemory: Honk.G1Point({ x: uint256( - 0x217c623bb5ed45b66577bd5777ab2af3f3e070d4a98c664675342e96886007a5 + 0x18181635f8750d3b03b52e121bbe07fb4d3e08b4989b6ef5333def026b828cf3 ), y: uint256( - 0x04c5f52d35c5ed18a466b1efd8acc4fbf04c25f860080d06d170a7fbe473520e + 0x2c242dfb8c0229804eaae90648bc992c4f63d874ef151c4ecf54ac97a5bf08af ) }), qNnf: Honk.G1Point({ x: uint256( - 0x2fa39132d2953cc30adda59cfec619aa9d2b70752295df0ca628845d904f28f4 + 0x110215fd0e2726c3c3683b996ff51724d93199b7ef88fdadbd54aaa9fca022bd ), y: uint256( - 0x2651aa28d13ee5492a29bd64f4ad4832140dc788e4e1c00f324b1cccbc937494 + 0x0dc638d96bb795eea151703dd5c4fe20c48f665e1264edb39ae300aa9f4271fc ) }), qPoseidon2External: Honk.G1Point({ x: uint256( - 0x079dd8624c03b30721db34a8872655db057f57c0933f7caf0fc4544964989bc2 + 0x256acee310ff585285aed9d9c01bd289881ccb39db67b8b991848ead743b63ca ), y: uint256( - 0x0e875b3d698d43802d1fe32a30d34c7c43bc1d9eb0a6b9b9c2fa667b31ea04eb + 0x178e69002175c64bb8aaffaae114cc8bc57480961ab90ace8f64f5862dafb821 ) }), qPoseidon2Internal: Honk.G1Point({ x: uint256( - 0x219a73defcdde90b92d8965858524cac51b08d7a652e4f94b04ec1b57ced064b + 0x04a70b2eca87e9050e09a105dcc2a73bb1c4a4b930707c9db6629b2c4b4ea3e9 ), y: uint256( - 0x0b4bfaa8972071cf51c62a4b98ecce85a6103091dcecdef51b4f7fa48d0f5a10 + 0x0677452145e88b25104c0164ab4e2e1cee82f965d2fc7f7d20b6141028ff9e2f ) }), s1: Honk.G1Point({ x: uint256( - 0x26a59aded238e61be9880c77ac3a7940d7e9720b104397e76e67b225cba9b80b + 0x1f0eb99dbf51ad7e6b2354d5b3ae077d5e1afddde296bc4c258707c30f882688 ), y: uint256( - 0x12ddf734e74b37da608c991b0cc2dfc9e113e3af59b5ac0af35386f5b4ec3d9a + 0x1717ce3f820e34d18f634296a4bab9b66dab9248dd2a870c5b583678ab7f9e26 ) }), s2: Honk.G1Point({ x: uint256( - 0x1881314a3796e27e431515e33df350add1397051a4db244ce7a5cac11faed51b + 0x12aed25179629d76d5925eaeb9e8b2d80c448a96d36744f9a5ca08d991f64400 ), y: uint256( - 0x16761ef2ac648cf92f1568015ca7640a2fb58c3dbf0de0eeb702a20062ce271b + 0x23d3dbcb3fcf90b58de5581b7170656e9d6b604d9508fa339a38646ece91ced8 ) }), s3: Honk.G1Point({ x: uint256( - 0x3015cfab2f817be579c9ec2fb7de656b09e04c095d46fb9c572ac45470ffcc6f + 0x227acfcb40b92109ab9551588c73329c398b26fab17487bdc234a95725a79898 ), y: uint256( - 0x09c9e677811bb52a9b51699304524b04165ee39fb5c8571e2600c6e3a65b5fe4 + 0x226129284eced0d2aa3c8548bd5b5edc96451dcfbf495e50c0d0ed545d10fba5 ) }), s4: Honk.G1Point({ x: uint256( - 0x21c4ebc93b81a0d4b48fe6768aac01e0da0db363ad5ed2b12d8a834b7f1fdffe + 0x040fbcc56d29dab3d67432c22dcccc91b227b9576acd333c00fcf93518d0b071 ), y: uint256( - 0x1c78387f50e554c5d663e4162d9904cfe53037a126fba4d08ee8f643c9450ec2 + 0x0dab4e861225494a60733262c51a5ef446fd06f62fe07ec72394532b547c1385 ) }), t1: Honk.G1Point({ @@ -197,34 +197,34 @@ library HonkVerificationKey { }), id1: Honk.G1Point({ x: uint256( - 0x1b4e63e074dea29db92b812d9e6d2a4859a60635f458e1e5029ee0aed26c702e + 0x0202ad5cc5c52cbb55775ec641c2181ee24a853e3942ef1d6dda20c7fec140f5 ), y: uint256( - 0x2d5fa9ba6ddb54ee0c0d31b1bcd3f449f0805d9a66801c945f012aa29119a4df + 0x2a1344dfb9b554a8f0a7ef7765d1638f46cb56bef3edaf3503087251cfd0b4ed ) }), id2: Honk.G1Point({ x: uint256( - 0x194c7c12ecb7cd44a614bd0080e2808e7785992904d11117dbc05e46a8fb127b + 0x29bb9e589926bcc214d1a61bbbb0de5ef9575449c5dcf5ab642c0035a6907c9b ), y: uint256( - 0x12879b5e899f7fbea4177df2a56ab2c9af92e281d75e11dc463b07623bdf7db4 + 0x200c9affff4ce2cb7c1f9d28917db69435ebe4e8b2e1f22f0362c85c77ea16b3 ) }), id3: Honk.G1Point({ x: uint256( - 0x27c9e91567b2c65396669dd2bacf1bd390e2d45f86d00a7ac95914144da382bc + 0x05e52f5db3e65feb5411e607e74b233434b9ff8c3a89a915670b1057f4bcf1dd ), y: uint256( - 0x1f5a7bb257b7912f6da48167ec70be3cf6fd1ffb020c80e63c9a4e9ff82ff4bb + 0x13a0ebbdfd34579ad99e170f3ff1a52ea9f390c4b08a0702b9aab51cce75e804 ) }), id4: Honk.G1Point({ x: uint256( - 0x1a6a30cc88ff3654113a4bb42bb0793ee741c025d6444b1f91d8ee1fcbdc8247 + 0x22ebe24f645ff3a89590bb2a18b044dcfdcab82116cf009975b2830d9b3a4ea4 ), y: uint256( - 0x23025936d2e066c8a1b8007230566c730afb42dea751e960a8d48485ddbbed69 + 0x2efa39e6590d27d97a3370de478c409ed4a81c21b095ef66fbba5781731feee1 ) }), lagrangeFirst: Honk.G1Point({ @@ -237,10 +237,10 @@ library HonkVerificationKey { }), lagrangeLast: Honk.G1Point({ x: uint256( - 0x23448f8b72ce67791d3051dcc2e73fe2210514cc6a95582066f9796ab7ef2002 + 0x0023e61900b57f815ccbbee3b413f670ed953f78f97138d58e5e59db1129e2aa ), y: uint256( - 0x242ccb90a0c69b71476139b7087b4f7bb37248c17f31dc514c4944e1c879cce9 + 0x13968632dbb726e48bcd9d74f136844cb4e2f7d8fcae051ab1fa866eafc02592 ) }) }); diff --git a/packages/interfold-contracts/scripts/benchmarkGasFromRaw.ts b/packages/interfold-contracts/scripts/benchmarkGasFromRaw.ts index 47930fb977..15fa07c139 100644 --- a/packages/interfold-contracts/scripts/benchmarkGasFromRaw.ts +++ b/packages/interfold-contracts/scripts/benchmarkGasFromRaw.ts @@ -11,6 +11,7 @@ import path from "node:path"; import { BFV_DKG_H, BFV_THRESHOLD_T, + bfvDecCiphertextCommitmentIndex, bfvDecCommitteeHashIndices, bfvDecDomainIndices, bfvDecPartyColOffsets, @@ -445,11 +446,14 @@ async function main() { decPublicInputs[DEC_DOMAIN_IDX.hi], decPublicInputs[DEC_DOMAIN_IDX.lo], ); + const decCiphertextCommitment = + decPublicInputs[bfvDecCiphertextCommitmentIndex()]; const decOk = await bfvDec.verify.staticCall( benchmarkE3Id, decDomain, plaintextHash, decCommitteeHash, + decCiphertextCommitment, decEncodedProof, ); if (!decOk) { @@ -462,6 +466,7 @@ async function main() { decDomain, plaintextHash, decCommitteeHash, + decCiphertextCommitment, decEncodedProof, ); diff --git a/packages/interfold-contracts/scripts/utils.ts b/packages/interfold-contracts/scripts/utils.ts index d13dc21ab3..c1b5a76933 100644 --- a/packages/interfold-contracts/scripts/utils.ts +++ b/packages/interfold-contracts/scripts/utils.ts @@ -110,7 +110,7 @@ export function bfvDkgCommitteeHashIndices(h: number): { /** `decryption_aggregator` EVM public-input count for BFV threshold `t`. */ export function bfvDecExpectedPublicInputsLen(threshold: number): number { - return 110 + 3 * threshold; + return 111 + 3 * threshold; } /** `publicInputs` indices for decryption-aggregator committee hash limbs. */ @@ -128,7 +128,7 @@ export function bfvDecPartyColOffsets(threshold: number): { sk: number; esm: number; } { - const partyId = 7; // 6 domain/VK/committee inputs + DEC_RETURN_PREFIX_LEN + const partyId = 8; // 7 domain/VK/committee/commitment inputs + DEC_RETURN_PREFIX_LEN const sk = partyId + (threshold + 1); const esm = sk + (threshold + 1); return { partyId, sk, esm }; @@ -139,6 +139,11 @@ export function bfvDecDomainIndices(): { hi: number; lo: number } { return { hi: 4, lo: 5 }; } +/** `publicInputs` index for the final circuit-compatible ciphertext commitment. */ +export function bfvDecCiphertextCommitmentIndex(): number { + return 6; +} + /** Recursive VK hashes for `BfvPkVerifier` sub-circuits (from `pnpm compile:circuits`). */ export function getBfvPkSubCircuitVkHashPaths() { const root = getRepoRoot(); diff --git a/packages/interfold-contracts/tasks/interfold.ts b/packages/interfold-contracts/tasks/interfold.ts index a2f540c082..86c14e9e26 100644 --- a/packages/interfold-contracts/tasks/interfold.ts +++ b/packages/interfold-contracts/tasks/interfold.ts @@ -329,6 +329,12 @@ export const publishCommittee = task( defaultValue: "0x", type: ArgumentType.STRING, }) + .addOption({ + name: "ciphertextCommitment", + description: "circuit-compatible SAFE commitment to the decoded ciphertext", + defaultValue: "", + type: ArgumentType.STRING, + }) .addOption({ name: "dkgAttestationBundle", description: @@ -524,7 +530,10 @@ export const publishCiphertext = task( type: ArgumentType.STRING, }) .setAction(async () => ({ - default: async ({ e3Id, data, dataFile, proof, proofFile }, hre) => { + default: async ( + { e3Id, data, dataFile, proof, proofFile, ciphertextCommitment }, + hre, + ) => { const { deployAndSaveInterfold } = await import( "../scripts/deployAndSave/interfold" ); @@ -550,6 +559,7 @@ export const publishCiphertext = task( const tx = await interfold.publishCiphertextOutput( e3Id, dataToSend, + ciphertextCommitment, proofToSend, ); diff --git a/packages/interfold-contracts/test/BfvDecryptionVerifier.spec.ts b/packages/interfold-contracts/test/BfvDecryptionVerifier.spec.ts index b60fada616..9cee02894e 100644 --- a/packages/interfold-contracts/test/BfvDecryptionVerifier.spec.ts +++ b/packages/interfold-contracts/test/BfvDecryptionVerifier.spec.ts @@ -29,6 +29,7 @@ const MESSAGE_COEFFS_COUNT = 100; const EXPECTED_C6_FOLD_KEY_HASH = ethers.id("c6_fold"); const EXPECTED_C7_KEY_HASH = ethers.id("c7"); const DECRYPTION_DOMAIN = ethers.id("e3-decryption-domain"); +const CIPHERTEXT_COMMITMENT = ethers.id("ciphertext-commitment"); /** Must match `BfvDecryptionVerifier.threshold` / default circuit `T`. */ const THRESHOLD = BFV_THRESHOLD_T; @@ -102,6 +103,7 @@ function buildPublicInputsWithMessage( } arr[COMMITTEE_HASH_HI_IDX] = committeeHashHi(committeeHash); arr[COMMITTEE_HASH_LO_IDX] = committeeHashLo(committeeHash); + arr[6] = CIPHERTEXT_COMMITMENT; for (let i = 0; i < partyIds.length; i++) { arr[PARTY_ID_COL_OFFSET + i] = "0x" + partyIds[i].toString(16).padStart(64, "0"); @@ -261,6 +263,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, "0xdeadbeef", ), ).to.be.revert(ethers); @@ -287,6 +290,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -316,6 +320,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -346,6 +351,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError(bfvDecryptionVerifier, "VkHashMismatch"); @@ -373,6 +379,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError(bfvDecryptionVerifier, "VkHashMismatch"); @@ -405,6 +412,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, wrongCommitteeHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -430,6 +438,7 @@ describe("BfvDecryptionVerifier", function () { ethers.id("different-e3-domain"), plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -438,6 +447,33 @@ describe("BfvDecryptionVerifier", function () { ); }); + it("reverts when the stored SAFE ciphertext commitment differs from the proof", async function () { + const { bfvDecryptionVerifier, mockCircuit } = await loadFixture( + deployWithMockCircuit, + ); + await mockCircuit.setReturnValue(true); + const { decryptionDomain } = ctx(); + + const messageCoeffs = [1n, 2n, 3n]; + const publicInputs = buildPublicInputsWithMessage(messageCoeffs); + const plaintextHash = plaintextToHash(messageCoeffs); + const proof = encodeProof("0x01", publicInputs); + + await expect( + bfvDecryptionVerifier.verify.staticCall( + E3_ID, + decryptionDomain, + plaintextHash, + ethers.ZeroHash, + ethers.id("wrong-ciphertext-commitment"), + proof, + ), + ).to.be.revertedWithCustomError( + bfvDecryptionVerifier, + "CiphertextCommitmentMismatch", + ); + }); + it("reverts PlaintextHashMismatch when message coeffs don't hash to plaintextHash", async function () { const { bfvDecryptionVerifier, mockCircuit } = await loadFixture( deployWithMockCircuit, @@ -456,6 +492,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, wrongHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -482,6 +519,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError(bfvDecryptionVerifier, "InvalidProof"); @@ -518,6 +556,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError(bfvDecryptionVerifier, "VkHashMismatch"); @@ -550,6 +589,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -588,6 +628,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -628,6 +669,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -653,6 +695,7 @@ describe("BfvDecryptionVerifier", function () { DECRYPTION_DOMAIN, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revertedWithCustomError( @@ -691,6 +734,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ), ).to.be.revert(ethers); @@ -715,6 +759,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ); expect(result).to.equal(true); @@ -740,6 +785,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ); expect(result).to.equal(true); @@ -768,6 +814,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, committeeHash, + CIPHERTEXT_COMMITMENT, proof, ); expect(result).to.equal(true); @@ -790,6 +837,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ); expect(result).to.equal(true); @@ -815,6 +863,7 @@ describe("BfvDecryptionVerifier", function () { decryptionDomain, plaintextHash, ethers.ZeroHash, + CIPHERTEXT_COMMITMENT, proof, ); expect(result).to.equal(true); diff --git a/packages/interfold-contracts/test/BfvVkBindingIntegration.spec.ts b/packages/interfold-contracts/test/BfvVkBindingIntegration.spec.ts index b0884fd00b..46d30028d1 100644 --- a/packages/interfold-contracts/test/BfvVkBindingIntegration.spec.ts +++ b/packages/interfold-contracts/test/BfvVkBindingIntegration.spec.ts @@ -15,6 +15,7 @@ import { BFV_THRESHOLD_T, assertBfvDecryptionVerifierSubCircuitVkHashes, assertBfvPkVerifierSubCircuitVkHashes, + bfvDecCiphertextCommitmentIndex, bfvDecCommitteeHashIndices, bfvDecDomainIndices, bfvDecExpectedPublicInputsLen, @@ -338,6 +339,8 @@ describe("BfvVkBindingIntegration", function () { decPublicInputs[DEC_DOMAIN_IDX.hi], decPublicInputs[DEC_DOMAIN_IDX.lo], ); + const decCiphertextCommitment = + decPublicInputs[bfvDecCiphertextCommitmentIndex()]; if (isCoverageRun) { // Instrumented Honk verifiers can exceed any practical eth_call budget; @@ -406,6 +409,7 @@ describe("BfvVkBindingIntegration", function () { decDomain, plaintextHash, decCommitteeHash, + decCiphertextCommitment, decEncoded, verifyOverrides, ), @@ -417,6 +421,7 @@ describe("BfvVkBindingIntegration", function () { ethers.id("different-e3-domain"), plaintextHash, decCommitteeHash, + decCiphertextCommitment, decEncoded, verifyOverrides, ), diff --git a/packages/interfold-contracts/test/E3Lifecycle/E3Integration.spec.ts b/packages/interfold-contracts/test/E3Lifecycle/E3Integration.spec.ts index 395f3e623f..e7a7dbf02c 100644 --- a/packages/interfold-contracts/test/E3Lifecycle/E3Integration.spec.ts +++ b/packages/interfold-contracts/test/E3Lifecycle/E3Integration.spec.ts @@ -442,6 +442,7 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { await interfold.publishCiphertextOutput( 0, "0x" + "ab".repeat(100), + ethers.keccak256("0x" + "ab".repeat(100)), "0x1337", ); await interfold.publishPlaintextOutput( @@ -1835,7 +1836,12 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const ciphertextOutput = "0x" + "ab".repeat(100); const proof = "0x1337"; - await interfold.publishCiphertextOutput(0, ciphertextOutput, proof); + await interfold.publishCiphertextOutput( + 0, + ciphertextOutput, + ethers.keccak256(ciphertextOutput), + proof, + ); stage = await interfold.getE3Stage(0); expect(stage).to.equal(4); // CiphertextReady @@ -2118,7 +2124,12 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const ciphertextOutput = "0x" + "ab".repeat(100); const proofBytes = "0x1337"; - await interfold.publishCiphertextOutput(0, ciphertextOutput, proofBytes); + await interfold.publishCiphertextOutput( + 0, + ciphertextOutput, + ethers.keccak256(ciphertextOutput), + proofBytes, + ); expect(await interfold.getE3Stage(0)).to.equal(4); // CiphertextReady // Record the E3 payment (normal rewards) before completion zeroes it @@ -2254,7 +2265,12 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const ciphertextOutput = "0x" + "ab".repeat(100); const proof = "0x1337"; - await interfold.publishCiphertextOutput(0, ciphertextOutput, proof); + await interfold.publishCiphertextOutput( + 0, + ciphertextOutput, + ethers.keccak256(ciphertextOutput), + proof, + ); expect(await interfold.getE3Stage(0)).to.equal(4); // CiphertextReady // 4. Publish plaintext output @@ -2312,7 +2328,12 @@ describe("E3 Integration - Refund/Timeout Mechanism", function () { const ciphertextOutput = "0x" + "ab".repeat(100); const proof = "0x1337"; - await interfold.publishCiphertextOutput(0, ciphertextOutput, proof); + await interfold.publishCiphertextOutput( + 0, + ciphertextOutput, + ethers.keccak256(ciphertextOutput), + proof, + ); const plaintextOutput = "0x" + "cd".repeat(100); await interfold.publishPlaintextOutput(0, plaintextOutput, proof); diff --git a/packages/interfold-contracts/test/Interfold.spec.ts b/packages/interfold-contracts/test/Interfold.spec.ts index b2e1205ca4..82d13b490e 100644 --- a/packages/interfold-contracts/test/Interfold.spec.ts +++ b/packages/interfold-contracts/test/Interfold.spec.ts @@ -40,6 +40,7 @@ describe("Interfold", function () { const data = "0xda7a"; const proof = "0x1337"; + const ciphertextCommitment = ethers.keccak256(data); const inputWindowDuration = 300; @@ -501,7 +502,9 @@ describe("Interfold", function () { it("reverts if E3 does not exist", async function () { const { interfold } = await loadFixture(setup); - await expect(interfold.publishCiphertextOutput(0, "0x", "0x")) + await expect( + interfold.publishCiphertextOutput(0, "0x", ethers.ZeroHash, "0x"), + ) .to.be.revertedWithCustomError(interfold, "E3DoesNotExist") .withArgs(0); }); @@ -534,8 +537,20 @@ describe("Interfold", function () { ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); - await expect(interfold.publishCiphertextOutput(e3Id, data, proof)) + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); + await expect( + interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ), + ) .to.be.revertedWithCustomError(interfold, "InvalidStage") .withArgs(e3Id, 3, 4); }); @@ -565,7 +580,12 @@ describe("Interfold", function () { interval: inputWindowDuration + timeoutConfig.computeWindow, }); await expect( - interfold.publishCiphertextOutput(e3Id, data, proof), + interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ), ).to.be.revertedWithCustomError(interfold, "CommitteeDutiesCompleted"); }); it("reverts if output is not valid", async function () { @@ -596,7 +616,7 @@ describe("Interfold", function () { ]); await mine(2, { interval: inputWindowDuration }); await expect( - interfold.publishCiphertextOutput(e3Id, "0x", "0x"), + interfold.publishCiphertextOutput(e3Id, "0x", ethers.ZeroHash, "0x"), ).to.be.revertedWithCustomError(interfold, "InvalidOutput"); }); it("sets ciphertextOutput correctly", async function () { @@ -622,9 +642,17 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - expect(await interfold.publishCiphertextOutput(e3Id, data, proof)); + expect( + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ), + ); const e3 = await interfold.getE3(e3Id); expect(e3.ciphertextOutput).to.equal(ethers.keccak256(data)); + expect(e3.ciphertextCommitment).to.equal(ciphertextCommitment); }); it("returns true if output is published successfully", async function () { const { @@ -650,7 +678,12 @@ describe("Interfold", function () { ]); await mine(2, { interval: inputWindowDuration }); expect( - await interfold.publishCiphertextOutput.staticCall(e3Id, data, proof), + await interfold.publishCiphertextOutput.staticCall( + e3Id, + data, + ciphertextCommitment, + proof, + ), ).to.equal(true); }); it("emits CiphertextOutputPublished event", async function () { @@ -676,9 +709,16 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await expect(interfold.publishCiphertextOutput(e3Id, data, proof)) + await expect( + interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ), + ) .to.emit(interfold, "CiphertextOutputPublished") - .withArgs(e3Id, data); + .withArgs(e3Id, data, ciphertextCommitment); }); }); @@ -741,7 +781,12 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); await interfold.publishPlaintextOutput(e3Id, data, proof); await expect( interfold.publishPlaintextOutput(e3Id, data, proof), @@ -769,7 +814,12 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); await expect( interfold.publishPlaintextOutput(e3Id, data, "0x"), @@ -808,7 +858,12 @@ describe("Interfold", function () { bundle, ); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); // M-35: decryption verifier now reverts with a typed error instead of // returning false, so the call reverts before Interfold's own InvalidOutput // wrapping (which now only guards ciphertext output). @@ -839,7 +894,12 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); expect(await interfold.publishPlaintextOutput(e3Id, data, proof)); const e3 = await interfold.getE3(e3Id); @@ -868,7 +928,12 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); expect( await interfold.publishPlaintextOutput.staticCall(e3Id, data, proof), ).to.equal(true); @@ -896,7 +961,12 @@ describe("Interfold", function () { operator3, ]); await mine(2, { interval: inputWindowDuration }); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ciphertextCommitment, + proof, + ); await expect(await interfold.publishPlaintextOutput(e3Id, data, proof)) .to.emit(interfold, "PlaintextOutputPublished") .withArgs(e3Id, data, proof); diff --git a/packages/interfold-contracts/test/Pricing/DustRotation.spec.ts b/packages/interfold-contracts/test/Pricing/DustRotation.spec.ts index 5febe1a7e6..26ef2fff8e 100644 --- a/packages/interfold-contracts/test/Pricing/DustRotation.spec.ts +++ b/packages/interfold-contracts/test/Pricing/DustRotation.spec.ts @@ -146,7 +146,12 @@ describe("Pricing — per-E3 dust rotation across consecutive E3s", function () [operator1, operator2, operator3], ); await time.increase(inputWindowDuration + 200); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ethers.keccak256(data), + proof, + ); const e3Proof = ethers.concat([proof, ethers.toBeHex(e3Id, 32)]); await interfold.publishPlaintextOutput(e3Id, data, e3Proof); return nodes; diff --git a/packages/interfold-contracts/test/Pricing/Pricing.spec.ts b/packages/interfold-contracts/test/Pricing/Pricing.spec.ts index 86263fc46f..2b0b98e15f 100644 --- a/packages/interfold-contracts/test/Pricing/Pricing.spec.ts +++ b/packages/interfold-contracts/test/Pricing/Pricing.spec.ts @@ -381,7 +381,12 @@ describe("E3 Pricing", function () { // Publish ciphertext await time.increase(inputWindowDuration + 200); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ethers.keccak256(data), + proof, + ); // Record operator balances before distribution const op1Before = await usdcToken.balanceOf(nodes[0]); @@ -467,7 +472,12 @@ describe("E3 Pricing", function () { // Publish outputs await time.increase(inputWindowDuration + 200); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ethers.keccak256(data), + proof, + ); const treasuryBefore = await usdcToken.balanceOf(treasuryAddr); const op1Before = await usdcToken.balanceOf(nodes[0]); diff --git a/packages/interfold-contracts/test/Pricing/PullPaymentsAndAllowlist.spec.ts b/packages/interfold-contracts/test/Pricing/PullPaymentsAndAllowlist.spec.ts index 372103e256..21af77dea3 100644 --- a/packages/interfold-contracts/test/Pricing/PullPaymentsAndAllowlist.spec.ts +++ b/packages/interfold-contracts/test/Pricing/PullPaymentsAndAllowlist.spec.ts @@ -146,7 +146,12 @@ describe("Interfold — pull payments + fee-token allow-list", function () { operator3, ]); await time.increase(inputWindowDuration + 200); - await interfold.publishCiphertextOutput(e3Id, data, proof); + await interfold.publishCiphertextOutput( + e3Id, + data, + ethers.keccak256(data), + proof, + ); await interfold.publishPlaintextOutput(e3Id, data, proof); return { e3Id, nodes }; }; @@ -195,7 +200,12 @@ describe("Interfold — pull payments + fee-token allow-list", function () { [ctx.operator1, ctx.operator2, ctx.operator3], ); await time.increase(inputWindowDuration + 200); - await interfold.publishCiphertextOutput(e3Id2, data, proof); + await interfold.publishCiphertextOutput( + e3Id2, + data, + ethers.keccak256(data), + proof, + ); await interfold.publishPlaintextOutput( e3Id2, data, diff --git a/packages/interfold-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json b/packages/interfold-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json index 057ffc738f..4f78360458 100644 --- a/packages/interfold-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json +++ b/packages/interfold-contracts/test/fixtures/bfv_vk_binding/folded_artifacts.json @@ -1,10 +1,10 @@ { "dkg_aggregator": { - "proof_hex": "0x00000000000000000000000000000000000000000000000893e2589fc7272df300000000000000000000000000000000000000000000000f9cacd727086112c2000000000000000000000000000000000000000000000001087d088d5e0eb68400000000000000000000000000000000000000000000000000012265e9d423bc00000000000000000000000000000000000000000000000848d741a33c08ace2000000000000000000000000000000000000000000000008900eb4f01074c33d00000000000000000000000000000000000000000000000bb603d265d0e8c3f300000000000000000000000000000000000000000000000000008a6c01ce44080000000000000000000000000000000000000000000000056a1f3c8c8cd10298000000000000000000000000000000000000000000000000f4913d1f1efea4390000000000000000000000000000000000000000000000055187776dfc7e27c200000000000000000000000000000000000000000000000000020e60b75114b80000000000000000000000000000000000000000000000037252d99ba4b6b4e600000000000000000000000000000000000000000000000774c7a54897b11a9500000000000000000000000000000000000000000000000fdd40227ec51bf31f00000000000000000000000000000000000000000000000000019c9203decfb90e15854237f5c72c41d9082a4545b24694b629e686c58d51412f7fd32e13d5cc131b256d0eae84688fba4f2c0c00f84a33ccf9eff8eaf9f96b18557d2a7019f3034e1dcf5038db8476b5ce28e0eb6d0b588a3d92abeccb8acadcf67559752b4820a6ae16edfdf62f6c4ff6f5dac318c159ed8b8a98adb2c907a21b91bb74450924ad1b7b0beae123ea31c74f103bd2f0d7838483cf5960db17d47b987b8eb9f41868dcc4c2d77185ff80d4213515aa90244fec519f8b4a3b94b789e212393534132732aa313e4296df8b5f17497adfb0e14abd79fd3d54f953825f194baa0bfa1b5875c2c1b1876a47dbde1ed563a4d0dedc8c3686bf29a39fcabb4f4d138a4305b305e25ea240ee1a7676ee159c5c0cee9881d575d82a8436a3047e0b16bd4d040372200291485daa1ef88b8e351a3aaff641c72510b642515345321f0aacdc2f1138db62d6540fd8f07939380763a72892091168fcae86a010b455afa401db031ecd41783b303eb5655e67ceec7775594faf23d9531c1e438fbb2a504a956e1b7bf6f6a9a1199f84d5430aad0d3d92f6f4040ef2b13539270b3a40d7505f931eca2310d783a3021e50216a221b41b08ac834737f354d673289128fd36786d6136e38d2f4d0b07b8cc1bb220bc7b8e57024195931350e83657d029a83dc34b7193c7c10e5f817db7d9edeb2e56536938360ba7662c40955cdb42cfba3ffe3471db3b457f7abc3da3b5c6cc1235d1443340fcc130ea8c7a1a27bd327b204b8bb1444f7df9b30ec99fb363c05cd8a95c8911703089acebf0e5374476e5b04ccac0ba4bae2950a693e469306142da1c9a6803cc03aa6751a5ede2660b6456d7ff50a22b46ecb26c32f8483b832badb3bd261b76147946ccf32ccc7df80755c970323abfd79e860344af0a77ef4158a686473f2ee44b9463c55a5fbba510f61820608315d582ea7ff959f9e0e0ece8f579c13bc173a81802641c6d59db9ccd02fb8222df1d855fb1a085663adbff7682626e7364c355592466ad27289f4e763e4150e11f707808d36e43f0942b2bce4623a17f32342e6159406377ddfc6a610497d064214c534db9af22e91fc4790d334549474cb3808889a7b233902313e8c9c1a078389b9a6bc5837f2c323f9c93da198c6f7ffc7e8506c22b6ea42e0bc92a9691e98e4a0334ff82dc0c51dbedecf9540cec8d166f3abb7acec918dd96d10159f277c4473b121ba1b35f5a6af679116f5bc600f42b77326cc2369b623347572731e3e5c676b3c710d4d76049409b96139a19caa6f489579243903a78bb5cc6d8d26546bd4ab3e7cf4e832a8158c91ba19a9e56101f466aadd4a5f6bfb7f8825d72c83d4e8965ba1468c1e93822666884990221c364cc3d56baf7b47217699b7af230b7d3b3d622b2ed8763f89c57955223d99ca2203786ae090d3a65884abcc6b117cd2bd54d1df58312861771bf6a290452d4c980ad6d8d77ef4455012bc47911e89bf3e709ae1bfb2731c4aa674fde1de69a4801e10c4923c4de7f339f85d5b2f00e7fe872d692fe397164968df3140ba2a3e8758c9a0e530903b569bc20ac6186844791c107f85970ed03a94a4120914c716a0f0606f6f66bdefb596ea706821ecbc8bd8932e21da71ded29557eb4172d7c4545a93a547fdf16e2768e3ec322d0658c1aa5b422e4fa9772c6222e1018db983236a2fe4afbc28e3a7d49aae3d0ab553e9239d3502e082ec865748cc118e8c4940a2096666785cbe269d84a3140ad922d438f9351ee68dcced4be0cc1be0096a717b090898c7a4b42c709cb2321d461e8c48dc9abfef867f2605097e9cafceaaa1c13117593bf3e4a47c350aea0f9fafad053548201fb07ac10455f6921da3e042a0af83797c1f518766fd5d9b1eee4e50d2912eb8059b9828ca6e9abcf7fbc8ca9fd31040dcf1a854b7ddce1823db49a85ae8c738472c347d5d332b51435ff82b2f9be8299e4c25ec3cdad2cf2372f312ed18b598f946ca078925c6511a63fcf014e95611009c314dbe8251d12ae84067c4f60fa43342708a96c72c8384fd3dd8510180f6b49dcbb0d6b0facc1431f6c045348ce0bd87ef9a7236126248b2cccc0697081632bc406775d2a81908d720f4faf784847862ee70967996516e8b1e6c36ce347628104e81f7537c972c8e4ab9c91a6f1f77edc7342c14fab39f3a89e3c77f02d08d5a46f3e07b31cf0f6fdeeceeba4efec088c521ff006ff8c62dcb71f444d65a28749a9192cf0a5c285a1f5ff79e8b76c3d4b15ba348b53041aa272efae3b2e1229e5b848a53180f2dfcdbfca0b368a59895ad8ef89c2db406b321ef980a673d66af38309bd1f8c02f01c5dc5bc307f642fa10ea809a214a256ac01aadafaec2fc8afb7e9a9060002c308f5e70b3ddc778f6aaa93630cbd17812cb210d316ea765117de0d6a975d52be3b032ae5b4f7f8efd0c387d042777cc46081a21b01929a0e851439ebcf53206053531bb680c462e2d8384ab322ff49426713b8a51aa30799d442c3772e7d72e53de315a6be54e85a3cc8b085e2837708d04206ef9ed7c075e54a3a1afd1ba122d34c298db267bf0de8979d3ea39981d8b826674c14bfcc73e1a40363a6a8d29858aa7a71cf3b41962433b4d4c38e6551698c82f67f33d41e13280121e551306c57d9e157f35ea90947e3e0eca751dfebb4528f409f8b7afa242345596fbb005cc617209a7bc2349235d7a01cbada55d7e457da18c3dd779f95a045a29187a18f7c25c8cfa61c702da793c22ba1ce87f369d82e49eaed8d7d99942de1e71cd05211c1a0da9dceb8776cba9c9de442336c572ea4d9deccc148b68b634693f0c2e17a10268df741e380d585ff3ea618b550537330b5b4c046c79c1419c7b494b02096cf7ab81dfae1a38d3e1956558869d84bb362b3fecdfc06c0dce58493bba2eb27fc58a2bdc4ed36c00bf922c5c1db5de02a4c432050a51ded9b099b41cbc061cc328788be07e4ccafd40b6bcd297b04797b97014eb32d258ee1ee2db13720122e99e0da54f6fb50245e680a31f64f621db6d92742171234e7586eb47891506f63d0daa7f8830c7f1367784020113578b8aa8b5dd4afc9fc9cd33172555c01eae152d42a6ac71c10bd1bb6480b7e40f8c3e2479d6c13e6b170811614e30c10797e04f4a794b23ad86dce7b68cb182d3d85328272e204224e373c5e5d7b41d29f8ec5570fad365770fa970af609eefc121da6206dc0d7f9391279e1948767c2eba3e936dbdc0cf22b8c0c670eb33a91a751d1580e32024a2a348e43c54a1f524c5c7dee7bf08b6407a4131bb7930d20fb78abc761d045841181c23b71807742e66ddd71bceaad5da2812d15f6bd7bf4b7abc39a746237b0ba166a1eff6a6361dce8dd8adb27ab557342db41bb92bb4dc1cee964d945cb4498628d373105d6a13ac28ffd7e9d74791f69bea43c9a30cc3d94d596f9680c3f04eda944c3eacab279565526a000489a00586d9867741b8c2bca52d99f56569164586ef339b1d0928cf8a27507b425f09889e3356238dcbdfe0d82ea0b25bf9fc7dd421156102771050857c3d200468629be6b8d50cb2f8ba886aa273d990d7253872a176ecfe2b2447b44957ad7a69fa0fba44fd137cf23203058c369401d2a8968b310b41600a1a8cca2c4f7eb5c10fabfb3912f6b4508b1499b61689286c92e2e10253fc62050db4c54731b5dd71fd020918713df81f373894c9e02ac407850911f7c65385a52ed9beb9b040e0f864d586e70ef47a84ab8009b1c26a482c661cc055921580f222932759de0b675fc5798bbcb1c97100d0e1178c3a9fdd87016ad164dc955b140721c4a127104109b1c4341dea673452c92a61455d7428e3fb33661a9cc6e805090b9f3af1250dc3692e5059ebf26b55ed24a1d17aac0b68cf098f87e87ca7cf0ee33d642a56905b9fa1ef08da3c79561b196b80e60928ed00339f73fb46fa1414a894a6a398d2881b92cb79476d91e9f05b709bd710e917802dc6cd31b342070d5aa5d7c38d8cc4e50461596b5d7240aac423856b44ac1d7695422ef9d190410a475b3de9d662aa4db4bfa5ff7f48cf9134f88de6e3824fed4fa82b8ea0eb7c0841152da5d56674987df02cb6d40314192857fdbf1e72ee745126823d350b1b2755e28a5733de1c902e753dfeb0345c45374985a8230c4719ce19642a6b39c001e40f6a1550dc098de688f2e5c20ffeff195bea4e58d45266c19d09ac4dd1c919f7d04b1c9017f95e5d6cece41b7f51fa6a767a74629c3fbf7f8a8c53b87e14172b8536b1752f50f587b3e87d1d32fc1aaf8f5c8097788a181144d396004ea52c248fc06ca0532f69b66a94287f5465e274cdf660854ef5812e9bd7d202cd361a6c9ab24c0d08eaeb17234f7b649849b17a82d2b4628e601165cbfa735b4a970d74e6fbfdeaacc9d23d2b7552f3e2e7f9cf36f245d72b9b0562233134fbfef13017c428b5d653681f822febb94d0d5787caa2fdf62a065b3cbd9cf7411fce960208555c6f62f6d0a9753d603c45b0ff2c26f61463fca3e9cc701ae605828152173319e1ba545079e1622b6313a693e3c91a61280b07b454303170ae71ed3fbf10221f39c22c89c3dc16ee2a8d3ab33f3e044bbcafceb519c20a6da079f6e3d818ce53aaa8f48a1cab2e844af148fa69cb3352af974d9161b8e46e514a39aafc211918caa8dbaa52c6d92b19a3c0e7aa2e5315f646464aba9c170dc165f088d92d3eb20cb4e9b6df442a4581f7bd621f7359e7107aaf2d6a96c8fa679b61d5ea263408751bca74056732ca92490d524dd393dd1920ad5d73bf36978c69c5a91413eeb815b94283fc18604a92c7d581223a897972e1d11f5d5fb18ea39d2c7c082c2f92b900e56c6e89559a144646c92f7172428ed7dad04833905b40d9fe3d02175c54ec7dd5eec77a2f83459dad2c7ea0afbfd3990e2af01d3adc3bbd2d4bdb2cd9e668a481f993b20b52d6695d4cab937d3388872e7f5292a2be8f19e912c51cfa1edf49b1f17a32fe84c10339ef67123b970a0ee9c32c498275c4069d665010942d89642d918d1608275e3683a6965334ec106a0f33fe20bb6e2cc35d65020c2abc37ef27b01b8baf7861ff6e75a6c878ec9ae8518d3193d7ba6211cf17610dbf3da6d82edfbd998175540b07c81b9b82554e8595e48c14f31e6fd979fd120b504192bbb4041af130e3443a95d694f484a388ffbc15a9f5cbe69ec8df85971e971559580e062fec279baec48c4c980a5b3ee9d9468135b28e6456c38722b024717827fd83ed7c07213e618ab3fc32e8a7afb39c5c295edd906eff182638a527576cde3d29dc6ee178378731bde6dc6b6d3f86eb97ead0f38894d9ccddbfc7009cafa51d2cab27496ad63f1e8dd6fba1d0f8d2ed6472d4d1b0fd0bd84185161bc89f8431adc4ae1c564fd79f0cdf3d331699e02813f944dded4444da20694722d06a7a3b2f66252781c0702e08d8d6eac0cac41111e1f19cee0b32ed5e4de626ab830809f85471c97ee8d18f0e49a9f59e23e2ddf20651ec29cd4b358c6c061cdb615bf651f6007a2074e4f5679dda0f83be4de87b9649ad16fbdd7e951c2d10afe06e9a07edbe7d7ac216cb7210f5d829c8e094aec84046bc73b3ddc8eb0d1a70e728e336cdad54f8c03670cc53a4efb8ccb1c64bd687395eb426c63fc3701284e98f30c881e829a47207642ad663d6fcf23733f0703a62f76b9d612c642910524dfbc4ad584ecc9aba8883766d6ff71b5bdf87de0301b7ac966efc5cfea32df53aa6133c431afc06ffe5fd7f230dabb3791045aa1b06df3031c9af4007ff16ecba9d8d3dcf9bc228867fb0d0cb6f7cbbb301bbea190b19d53dea570589ad22f0a4c22f7c143798bddbb1db1ec81e892ee35b7bc566412706f6ba39db47222c5b24ceaa70b934f696b3042014f4d71242f3465fd6bbba7fc2aeb209da45d8168749bf202b7d7751a2c7a6738b0dff17d8ed462a2a4d03940f089083b3e07113931a991816788c975e884ed4fabe62624354c7d7cbbb444f09226f28bf4c88180f64406dd0a9d860333e34601b154a0f617b129b91b798f2d6642b1b3f6f4d048d5f4ccab3a704884851c7dac301d61e83eb8650b4101bd0b5b2d97ec88c5022f0f15f227881968414436094841db6d1ba966046c9f9896f897c62811da7f10c2bb7650d2a76e618119fcf7be78384e4802def8df8e81700da1295a32a138e2020174ac7aa7bd8b333d9ce80f19d89cde515e77c87894c45bd66435f5603240a0656a475363a01ad7fc570af47536e52d70592ce4e9a8b45480aa2dcbfa1da14c96f85e04ec5c925b1fe7a72e20ad432f905dad4c272b7cb948147daecbda602fc461ce29574a5feab8a23c9f5c9530f4de936aaf119781321b8eb04fd221123971631c97621631d403795d5d9908aeb33310de43fea8007077a7acd121ce220cc548aec560ee0fb11777ee0fb6034800a009353c47fd8d9f59fdf1812f0e6165cd6906e559d0639f2b89305ed45e9de8ab19564a549b7d128fa38685eba0618a16438b5e899b824ab31a49706b90bcb5c838d18b9e70376a54ac54cd871a60c49d283b19468ee15da356cb55ac7aa8ee6a356dfb951dbb8fb928d79cb39791ff85032801bc21e98725d3fd417d948194e8f93d330586082493206aeee5f672b47cbef3d769fd4c06e2adcc54b93df406d84ef63f6e8142746767963f1e4031a9e7ff72c05e1551d2626d1472dafcf890c11f1baaaab1bdcff02968609f6f4154a817867460ffa14261ad963b2976cd6d9944338acdb4a91c2a15a421d577b1f0cd6eafde870d2d1fcd8b3d03873bb113f133f2165785cbb4ec4b99137a4dc2db3313338c4bf136ac9c39b4053ab91a5017676f447a5ca720db1c5f33ba2e0203d82562b9dbfdd0b5464cf411a4ec39ff798b2abd5479d68a18480641310eb05c1fca5bf8c5132330c5c54bc23c7913e2b315d9a8271db1b621b500612a25e23482623e037b0b6773980a4275e42c137330ebfbf721a39196f153b0328130c0b2aca7467cfef01cc4dbbf9a8a0926c340a58883e4b0b59b9afe62a8c62d08d18562a4fd95a6a3d70dfd90fa1a15d6952d83a85dcb3ab079a91ba67cbff6775082abd4ab25e8feb4e83857e5eab021ae8a4505dbe7a3dde2d36aa0ebc508cae1b49c818f5c7165e7ff39a473235a75a9b2333e588211d0ef5e7129d3986e9e0213d2de49dbfb62daf700bffebc1727aa70907b77e8cb713c6ba8cad1f0d0c800864d208c935343fdd3740cfb370faac2a80961a0f3b8b35d0447005fc0e82022d949031d5062d4f8aa744cc623c4d6d671768c62cc023a0a2461b3988214b8f215ce83ad729227f4a3400be99c58bfabafab8ad4af06c17e28a10ec8f8af06626e1454f2963138e56c19a4f6ac189a552f48179a0605425fcdfe1ca7a403cf2297e9a7392ef35241d75085a64983b8d68eafc54dac726b6d84a94e16874e0860c6f472b3b0981400901922b07f2fcf01a54c30cf6825b20dbbe1146991b852c1a9a6878a7f1f43af6a26a880f0798ede86d0430bde95fa493eb91880e91285f2230058a0cd7f392a407d2058b56af8f3dca57b484ec6ca4526ee5e1ae36f79401ac6be0ec199215cbbb9342f6fa48ee5fc2079c21a44fe98d901c0c437ded112b20f9e1d14722d0a1a6f8e3c5ae5542b664e996bbac6184959b6007b43d9c960561005f6d238f5d3bc6ce60731faa20b64e59ac0cd270533f6c44cc6e9d5bdc057500afdd58bd889de4b82459f36be31db8afb91574243c8e1acdb67828f1e9183add21c8cbffd759306175151d5c4fa4f472b2b75c86e3e25480cf56c48ce4141595fca7a27e81a3c41d623170d54577eef77228a740c5f72b306348fb220d2e48fdd3a7d964de9ba0cf246c99d67200ee6e340a0c8367579e674a4a5f33512944c67f47c50e3570a3b47ae1929539f12c92075d326900f390b576aeebe9e6094000860a65184372332c28dfd700c53451f69568ea99c67309a4f07fe9965e12ef213d1b038709b1befd318e147d81e508fb2bdef04cd29f9a67fb0d4a1ee312e3f5792c46144ddb8352c4f042e61ed5a9a3850fd9850c9c7f1cf0630b3a6a1ec33bf3df6527fe4b12da199a1e9f94e31021debbb6ffedd6f10b71a1cdabf91e082b655ae4cc1d2e1b60ab79a92a5885e534006c0bbc303120f2d6824a10f10bb91d471511c9c24acf37c1061aa87aec6cf9f3660ba178576a0f482364dfbd15bde29fcfe07eb227db46d853af20da62ac6469a7e96e1e1d423177fc3309ad15ac488adaa1731baec815d86b4dfe6804690606a8822238f26b3c16b105dac12757991e46ac2def906b4a5ce65aea1d35ff0eabeb4f0845f583899205f33925087b24680062abf2bfacce5706551a5db92655b0311e8956ee3bc0d8a34b4a83244d664d1f71d3f4f807e7530c496f3504363d1e2462f35204e1b5fd4b7592e318ed8d0ba6c6cf82eea8fe98f6a3bbbcd3ee9c6c7672b4cba6773d47df0686b3051385b0d91358f0e9c73f6e71a93c15342fc46a0aaabf3379116dd12f95a2e30f7168937816ce74020682f78f0f15a4eca7870bdc17d4f0b36fb6db0eba34a517d878fcfe8f2160a608e9872198e628d47f55301e95e72184f9232b641a9f7a061c56f08d53de42e7f013c1112f76d21023a517b7d31548c2eab75c92c8d8311df000ef658c3423d9a2689069ce94d84a3d4f0d22781c03580962692d7776b4189c2722e1d652a5c109bae7de3860a66cc7b24d72860e3f43e9d0525bd21c9925e3b3e4130a73259fe1f10e44eef6a44da0dbe5f23dd48f8487f0bb7944f6280a507cab9587d26c812f6157deb1f312c53454e855a178d8282c34d93f20f06f1ab53520ad6cca61d9526c18ff7a37c60c431994b63d90fa5a7a16e4d34a1ddc0440c54904a6a94980e95c17224c4729862a9d26e7148fcdd79479f431732ed609664b7264eeacdb27c0400293f46c5e78edc80fd0d329cebbd45774ec88a46404c02b85d4ea7fd4ad0af626ef8268dc528e42d88c78c30757b285f07d2391fc0a6b4b8a4594c528d07833f1799e521fbf56aededc873143d5e7f027602e3cf308e4696ba7074107e534a1a545a613362eab5fdcf4a7e24ed0131349f0a138ad2d06b11d96c5b243992d1043952d17c7c4e294863c4a935fdd19dafe178bdc722ab0484766b0df419faf509b15a221d03428158513c3976eb5fe8d608ad3cf2b288fd1cbb13ef5861622006944f60a12f6bbf6bea0716f0814994dcba71de0f002b63902f9a23d06619abe4bb5eb4765dd8a51dbf12f94deaea567e45397211818ab423556e04576e23da8465df309f46b735955dae455c92dd8e9a1108a41d50e8efe970196f109d249c781077ad9f6454fdefb125ac4018a77e78ff1dff9c106f125c8952b7af0c9cc3e31879428adbc797c0da2d0a15caebaa50e95d965d80f9e7ccab0c03042033c2324b455283f43230e429523ee4f5959abbf2c434df007b5f1d715595f140e0c8f40b7ea9e7421d20fea459089b89dfaf43f0c88551b27a3e65b3945e380221082caa460e084b04aa109b767292d056c9ee9f33d5cb10b1b1f59a0279318cfde05d94c06b3fdc481219467bb3bec6bda69c67d53ed402be155f263eee937cb54155b12136a89a46e1734f4deccdb583e7540c400dea115a04cd09b2f88dbf70ee025cb3683b16c9e4243eda18272a727ef90ac558262191c9cb273d4f774631c1bc62857719ca60acdc1b962c2c94e43fd2a7fa99d5f0ecd0b58485875e38d85a12f1ff83a20691b7990b0fdfb562835c47435700ab01f5cd6728582866d6417bdad24896d682f57327f3f357f92e231d7445a88e8d62a31657804bda891fbff40aebfa7f1998e0238556c88b06cad3e4649fb8ae0561742e4f0a5470ff1d960765815806655e27dc35a481884aef885816125ddc6eb204e45cc9e3a72bf6baa8b8c842c5fa47837fb7f939bcd87abde3aabd1e81a732bd2dcf1d6945a33155ae5040e039f4873ac6d10baf1a9e43eb12078833541b2076327aa6d55a090b541f4810fa7b8884ea88c34ee43cbff40d44adb4fdbef702bb488a88099a373799583c0cb80dd2d248b42ee1b654fff03b3806ee493b2720c9b3aadc29bf471698a900bac7456c00b3f89e208250d841ca24424ef4c6e3b07ae9aa5a00ed1f766b7a929a6de5e3a70dbab9c142a3510bbcf84f88c347400197ff4a9f7da8346713e664a231959802d7a6cf75c2a173c2db344e6d4a5d56f14ac840a76697737e218df841fbb7a8f3f08513b3c542e52cc31b94ebdc443d1078b4decdf9a75e95e8aba608d33431ec59b57febae0f555880e116c692c2e9f1a9a65de6bc2837c768c3eb51683d2847d094b175a879ed511e66165f1de8abd1dcd23cac7c1ec82d9a52e308e963a77cf65dca0f0db111d46ea30706015beb00ec729304e0794895cf4c9ffee381b9dc4db3fc4d44181e018a6ee8000b868ef0f6160804464b254d14be3559d4caf9678b5de7b7b1a7a9070d0cf44ffd032e70fcc92e5bbd5cf184b555b97e34c458f87a09abe6de3908048bcc6f5507a73b2223ecf3d9c29f17f00bdf6d61e208cb9005a768db218320e7e978fc959b55e7302ac695dc17885a23246b49bfd619e57d49863161c31abfeaf8f8cdf8833eca414424e4e8845f127a575087d5913b89395ef2aa55d3cf8b3b483f396b713c65a0ba185653e2986e5115071a047fcaf0ae1fa19ae7b04081b1310982d392383bb222ebfa5ba52744e12a72513e438cf6d03af216476c26994891acb28f59838741142ef12497861ec13abc8acbb2466268e8caec8284202d03fcaded555ed974b17d41c330f848d0e2f1b5a9108855768efac063c9920ac12b6a879a08948d0f9200ef3f75da5f41b2f543761bf7d0d86e56cc989297922460db73a03ce84ccc4030fa70397fb5ebc5cbc8f6cf421f23c44bc6189df836d6ed6a0fc78038a5a8608036e674999c34a70fb35b8465c0d6758728acb8d73eabb3ac644d6758c0c73296083f3954c9432d9ed6c71996b021695e7d65b5375b2895a334009edfc2a6919cfc3eec78ad4b9287987f1299da8bedbec20a505cfdbb44723d4bc3cd2d1fe12f00b19849d6f72a610abe23dcbffc8ade7ec3bd0317af222b65c7ff5b5495220fc13e5cda3fa09da3f95fe2d8d76d6e5445d3dc1643b9c66b9c7c8107ed50a0a29b31e66402fea924c509767ad063dfffa4ad6d54d7f58544f1bc2358feb112f8ea19d97c6eb91cb5f369ad9b4107d899d1cae3e5c724bffa48b87ca17f35306d3812384215d1abf008a7b907ad0858d50c125139dcffeaba4361b7f953f6a03f074cca6df53e91ff16c78827e83f0ee880f4f5195310028394fa5c5f3ba09186284bc29f4b6e8416a138505cf499953a2c6c8ccf9a564873d76e865c9910a20d228283e2cd33fc3f56c013a8d7d07716f9d818dd161199b436dd88262394d1a87a38a541a85f8b7eb998dd13fe030b3724d081dea153fce02a84f5558de530c44755f6a9881fdf2e0ace74e8717b9ac72bd9eaaff7885cc06859aa9aebddf0ef40c17f2d1a683b99702ad953a8ca9a51ec84692e1aa88ceea09f4bf605ce20b8cdeda1e3a28db51fbc731c8849bf745eb4e8d856bd9693e77980f418550012794cc6d95b22716d9afe4d185781264b1192ad706040d0e15d4821e30e08f34048456ffd93f3155194cbd076c24c1f5684354f0739143b8211d2991f08e454427e459b107a71f3e0b5f0606c9daa4b4dd3fa76c853bc858ee103e50e7faaeb02a3421bd55fa8a9e287bd2e05ee9a2084aef08260f837b4c3013fe8e3f6cf9420fe4d218ce62b4da5abae4361e0e5e97561c9d68188229a44b345cf28257cf8f053e9f953d6e47e881c8cddc7c1bbfdc923ea870e8c241ef5e7902e730fcf0292ce2643a1ee75a36fd97025cc20e150b3080d378d6046ad87a77ee7263472719181de493b6074cf5a8c4582b691c75bd21d7affa7719d90ef574240bfb654be3072740670a8f778713f5e79fa0343d7c94951d4e1dda38945c1f1c4c79b0f46b1794adf40742c52f886c76405a4e43249a6cd0ad084b03e2523c8631e348666d2f48aa9e998b93e0e25dceab0e1a7ef1a55f7c65f19211cee7cc13f85450317d0b12dbed6276515724929d660a69001e89c88430b48d4aa0c27214317d9ae2931b35e51fc52919c6c6587d109f3ee90e3e0d362188a26ae5ce80ddd83b702b7424ea9db01b49731ecc57445d651091b4bbe3d1bc220b3e5185a8d49a1fe80a831ea7e2fe521e3e04fb11b42c2e4a609ad6015bedee86f0189457819e71f14c3627b9f45f6ecc3447684d160ea4ac997c73642271ce1e6a46ecb8bde88038c39d123f4959a78f0c8007855cab251e8d3da4d630000ecd9126e6833d63328a24c422fc59d9359e12dfcf27d0c5f0199b4821e3cd1de1ff163fc49a9df289a9974503df73519f1552e44e1a98569af102affe855d8f39d6a34742ab7064c82c88bf08e8a01352a500a36f795cdc0b4037aac666c88bd9871982bb6ff04dc88a5245039e2ab2ad19240ea285951e6177b10884632b34fad1217a07b38d550559090520a9e1b863b056838b479879f1895435aa98220a8f9a6d76db3473a6d3847f65040f7ba4d761ee389d4da5f3413232a7046c0abf5070c8b99d88e641b201f5da1c9afdc9edff2bcdc2f470f991089f05dd50150db240ef0f642d811eee33b99129b73f096d8cdddcd5859c0d2e197a96707b15cb6b3702c6682907c8688922ee114ddd36d9907ceb5259cd5bba0084a436ecd1642d23b7f66c6ce0c64185c7d8258c977a52178a57b60b41ab9ece7b84aae11bb5950bbff2dacda0d64240fcb40409ed7a53e69477d230f149529d3fe6428682453d6251fd921c8688547eedd51b5c68844880751a48612aed8826a37576d2bdd8005f765ac392551ff70cde90073d7f0b5512a16dd2034c1376a4080032dc0abe900746558ce59dd2c4d231a706d2665067273dde3df674cfa4ccbadb598f42e13e846fc4a22035f9b854af3c2500eb992c01097039140dd976c37dd9fb5be240f8f89ffeb634aeea48d28b8c04660eceb21c793218ca51e92982bf6e6f26922df5298239c4a89714e8a751cd02a659df9529860a1514f1a38629a5873ddd9b6090e6a39a042002ede0e9cbc9296ccb230a9bae17171ba4ef5cd6001157c8984f129d7b7a851066bd1fbfd5d40418eb076677587b8ad3f0d30aee8b11a1b309a2a4aa67cb340ffd2c851a80ad034548f1cdd55bceb68bc6d92b9b9d2a6e0fe0df3fd0bb95a18ef580e85c6b74262443a276a822babfcf27aae1c1c34816f3ebc80506330c8a1061dab2f6ac40053a62579fbadd88d3554c4ce5b6831fee23a3a531d1ba63e53bca00bb43fc391d63f59a67199feda087c1165c1d5995d0720990e89c48cef7b25de004fdc9190a298c67c460d776b1841fb80ea780f7df5acf91dc80087a3ab194c2a97729c024e42668964e26f5375a7fbe24c1520643ad2f349fcaf537c48bf433f5b9a45b012ebda2247a0f0bbe48f1b1d0e846714989b47d6f92f0d88f5c8739a31bf4133023e14fa286411665dc848f4d58d344698847724fc929854caf1cde8ea0d09c07b9f92374962f73f2d1f40e3902cb7d56b15e7d0eefcb961882c0dde1878b362784afc69cb0794f0fd51b61c1b9d03a02fc47ae558dd9f4deabc27b59977f492e1614d7e474614fd8dbee719e0f69a2f0ce128a6f34032ccb3c35f82d313e590947f4f99ea483df92e7639d67d072741304e8e0bc74dbd0b23f3cb45d85a3bb26374a4396eb3b6a4c00355fb8cc775aaf6703f201ff59b1b4f27a182df262d7089677abe9ae5698d33b15fb7d4dd4ca5c3d907daf4b549e07f51ae0b484c99614a72ed2a0e63935ddee0ba964ae607aba417e84221123ab810580d225047f4929582b6a546e716b2b9c090d4b9ef3ee96ae81e494a5e9adaf4e9643b9612c332e3cc93d565710a48f6e2090808a46e14fd79075d0a72f700e01ecfc85af725a14440a5a40c1004d11b0332ca006e574f5b101aae2b380d39a2a74073f9506bf2e0a6db9e9d44f3c0b34d8f4691cefaddac68fe1f4b9217b8da1ad1c6832af7516ff283f1c24162d5c9d43c6535af3b663c8f6b317999b5a467360cdbc798b621d6450be808681e1ef26c3b9b41b45b8f6ed4a6a3595a19a15eda260e91cf4bd27cc6c4a9a88936d82713001dfb2cad647702a2bc220ae6081bbbc13c83d4d4e062801150d72d7e5118df025a8358f40f4210d7ccd0c64a724bfe36e0a125e3f2f7a19d5762c83f155a224598217f7bb4e7888d0aa934e3093280e049c77787906ec5f65b531dd8523c41c007152ee734bb9f3b41c5ac053e08c2a114b7cc8570dd2060156591ffa67b27471a6d3670e9084e2723e81f98deedafabecd6903aa119e5a8e848c7516df9aa6642fe93d368010ecca14808cbf3b997b04f3bede532447812f18f9dff221fbe5c04e44c2a574bdd76c15b1f60c84093c165abd36b325478cec46b35db110fec226147ac00e55ebc8c2d694c9c5a5a94fdcc3ae9bf905c8a7aaea5c51011c79bf922985e92c6e34eb378a308336dfb376803039ce0e234d2d8a3a1a0ee6b3ccfed7b2e36176bdf444da598ba702c752e2fcfd2e98a4", - "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f710ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c9904fcf7f4ac91f0dc986701c89901fb7d914b8da5dcd57d430d860c3979baf98a" + "proof_hex": "0x0000000000000000000000000000000000000000000000050171e1c76882125000000000000000000000000000000000000000000000000cfdf1f1b488062f1e00000000000000000000000000000000000000000000000f962e434261b37a730000000000000000000000000000000000000000000000000002e0e72e3a7169000000000000000000000000000000000000000000000003632118af1fd3861600000000000000000000000000000000000000000000000f3be15fa21507e979000000000000000000000000000000000000000000000006da62c16a519156a00000000000000000000000000000000000000000000000000000ae34beccc39c00000000000000000000000000000000000000000000000c2d6c29afc67b101c000000000000000000000000000000000000000000000009cb8711b402b7afca00000000000000000000000000000000000000000000000433d081100331cf9900000000000000000000000000000000000000000000000000019240d6a5f208000000000000000000000000000000000000000000000007b680e3643ee08d4d00000000000000000000000000000000000000000000000db2f02967a31b6d1800000000000000000000000000000000000000000000000d8224e1aaf3cd44a90000000000000000000000000000000000000000000000000001e3e986df6e472a988fa1b94e96b9bcc842e1ec09ad2835ec6539b20a216d94832710f34e12a11bbedba09154d4bdb6ca8a864ed19ed0dab77199001fae75d996691767ea956b04a0389bce5a23d5fd869aaf9c5e5c443b43b84c5b41d4b2a0d90188989c511a145d2197e8a1f835404ae133ba729ff0f9e5db0e78f86e967e89a28eecd299702170e094855e18faf9b08036a4ab8cc8451b9e96d4a3e4ddb294ec58068c86cb28b5a272fe283333c466d2b063e406c9b5d5898942d5c60fcbf13a28f333c0172e75ee97db99d23fccf0100b7e768b832f63913b02f762a179772a656dd7f3eb102bf5c1f9a9bd5ca2c2ee9241a4d4088f679221c0288326ed6fb9262962ed1b10bae9d0f25b5935e7684a6e3749e9cab8e2c12d53e6d1d284267887e58c05da28603176d9f1ea891e633934fa4fca7ffc9161f5a3838dd02afd160b0233cc2f1985db340cca8b06e4ce20fb357bdb4ee18bd32fd75c0c529e114987992e62c31533f35e6e095dc8e36fd57bb8046002ae0471ec3fcde36bef53e375cd0f3e4f191a2188d3e9a6fb82792a50d4ff1360640275046de2c21d4f4a3577e8f79a8519b47cd6be30649c380eb4d735707b1c664f98421938cd63d5f656c6eef8048b3001073f0fb231803649f60355fc757e41658a95c817594e1dafd8c2691d24f00bf99821e74780d315f5c5ad75d8e983e6d5085993e102017a72b2fa266960920a8e7e77a2ee6d59d798f12d92b424782833dbc7d235ec3e43373ad3e404f1cb1e08a2bd553428c3accdeb393846323c7c78adaa32f740afcc9ac4d264b3ed09297b45a3413e22cc62390354d759b264a96544e1662be66950fd42c67f2dc79c046b48d8eaf419dd29c1de1171719708091ab038efedbcab7ce18f60d73cf851144e9914268e22dbed233813cbb531e7cc338776a52b34c5b445336a93a82a3505ee10cb945134e955f56c92798fcfacec8ab4312b370d08ba9e13c6822f7b2b251218642289c021af15cc46ee027d7b415eec7ac6d8701d066c7ea7fbad0fff1f44ed8fbfd3209ca7c67443b852e7eb2153ead095fca5a334f74adb331a85071d37e4d8fef5c820bebfb6f8ef7cbbe9e595b09b923eaa754d813eecb8b431b6252e189fa9fd09540008f1a366d44aec26b5f3d6b88219b8acc0132af1175d1303948e2483093e739c7657de30ffc650be6016e8b7b644f1706af4f10794917723b79318a87138a13ddb9ee54f5a386fd236ec981a583a22c69f30ddd9d7684e2cdd842c10629c9b803f04e709db227ac8c2618b2ab90b7e272e60602fea839906c91883e1ba386f54311b5f8dc3e654a0d4ec89e0e84c28bc6de587d46fcda612aa42f202b2336dee7da1bb663559552831351bd8506a5e95299a7305b38f87141a1d53d730ea5f7e8327f36f8046b96f06be138f225d542397e91de2db853c118243d8072071c8c2b6c9b8319b2364cf2058d3ae62883cd328faed3808687d1e6bcd832417a660a93375eb3b6949753531fbcaf3e9dfda64319654db11377d0d30a54dc8104f72b9ada7db131094a3d563bda7a350f045ba02572b53152c9f0b81b3d85c069c07f10b478b5e43103026fe9054094913d3939a7dfede87684e2ccd8b577e3eef430358e620b504e70597c6fdef4fafcba52e4ecb198fdd7d7e2ded4feaa5e0f4e46f5928eb7cbef54804310bb28444bdd8db0c2aba73c31c7019870268b2c4ef8557b3adea63df71d1ab57662ef45b9340068707f834268fe72215eb567a317d10a1184f97b55c41dedcb2b3fde60bf5b36f8db7ae9a86679e033d6ab5ae65925449813af86b5ddc4e84247246cc5979716414f6543895abac01e65a1745a512cfa85259e0704601b4e96f4fa2acb1810d93f6f5f7c3c3facd28d37db2dda672619c9a74af9fc8590f1e019816aed3efd4f2431c42aa49707f2bc202af6e47cd30525b3176d9f656c8f38188e47b4010e170a5c9540e8d446907662106b2f16ebaa6d3b31f76676b63b88f6b5f201fc55b64fd485a05dc54e82ea332f1cf2a5e4a3ba0fb92db8a4e2582d696f0e3e9544f1df54d2a150928a21c64166a1eee5a7acf0ca354f1ef2c597a915abf5eb1f2f17f4444a14ab73d25291fd606842f6d46c423a3d5002ad5d1d85e8f2d5aa6facf93d277e8ada5be2d281e1d086b9900f04949511c28d3e5e5c042336a9c38d499e0d9d4a0e22a011c2c1d46ab3419b71c538300bf07222fac1ee50f30f59fd1606b7a733cb89d47c01f240b094462a58c6a48f2f22ea0c311cf71059da4b6eccec988af99298b19851a03b84a54289cd63995596220af919f2ace0b6855f018780539198fa2b546722a38ca2bcc9ef20fe97d16857bc21184cb8c26ca77dd0a48d21e63a4d2e309941336a5aaf3f8d884fb066e1be202f0a5824698aedc16b097163316f2e9637c3e0b20b792a3ce06ffaccc8c01feb75db6c1a8a5f691fd6f0457b21d6f96014d97181c7e28a5e38a313ba81781b44d944fa5180921b4e3a685c67e7b5ba54522b12067ea024995c2b4d39a4378e235bc9617cd45226b0b462acc8268376f09ded9148ae0c2c54cb0572c7ceb489276b6f9865480d1328e52c20b2a87bb25f8f8fe19c2f1f9253a2f9d91ce5f306a71365388975e901501ed2061722b40b39cc5e126be39f84c67f5d309093a230fd41635b221b3a842bffc6c82b439bb4f30c82a0e455c77499e96fca527260c2387b5b33a342fb731983cf4493ce8616a7a53c020b4cc0c3be0b632c8ec769378bb66387a1f5aef060a93837742564a44d13f722b3c33c50977596828429b4d9cfd84efdebb1716ad8865c2bb0b7a428dbb76a510b3144751ed6f56f3e4a1725894ae0491db526f33ff61610340d0ae06c3c2090a090850b2deca290112c8c9ee587277a28c6783c18de6edb089175f09c0cba60ceb6596411449d0e45ac2e45a96fbccd16876400fe6be3abe02546874f1bb2c02ee37e4891c999df82ab2e71bdc4b8565e904d46de6572a8e13bbd57bbc7666076ab48a848eb008f5d150b8f34e2950e07418dcd2ae4d4618bbc20d3ef16d280e138a7bdbc01702cb05e90d7216c66cb9f4ddb7036ba9a8e490c2d6706f6ac61e64503d935535e808a69eaf53e3c6529734aaf10bf83f868f942f8532031fea1b8462e093707d67a47944a349411088c6642cd6a7686fef5a7e239b0697054c11236b5d3764b83f9a409821ce9b4b87bedd5ceb3f4fe6afe7a7c894738d1c35296c66c8d85376b5a864281a54897b64e90cc5bbf2778ab3edf83387c80734661b77c4e4eebdbefd15d57a22abfa5662ad616b857f09acc5f7c03503dd36f569035c3c9ff43a306932b0c6921ec3ab08210793ff101a1cdb4d52ada493df83561c674eaca29b3732bfeb35648633817b65654639049f14ed8eab71d7cadc6a472d72dedc4c511dfe6eec2d6f780d3cda952417d70927de7c890c822180b751cb22efb494f2c65804b31df2d6fc8b2e02b1c3da3f32183ebcab8662f9dec0b9db27970150805f57492628d4f2e5cefeca33c80f49d769038ecea2193dcf848bf626721a1fc9537290fccd8957f41fea37a04af789d5a699ec186f0c5195b9da3a0d289910128a71cc047bb54a1a2348c809d62257a294655ff515866421c786c31b60373c7229263449b97139a1e73d1632c5c655a5298e01e0d93090bd458b562571a3466918118d55c7653f72fabdbd090983f3d374b657938439592f27e63519b3836279b0887e21105c5b699c6402bf9926c8774566b8696178ca6e6019d60fa85a2daf85687adf80a426ac4b3280a35fa0a03fdf7caa03453744d3c95876267ae5a2ec7cd9bea56c9f4791aabb88c44f77aeb2be859b01c3e657343a1fbc0301584b569bb2677bfe761033251f642a36db5fe7a900eda00a899c6436b3552257ba5af5060156dc3cf16a744e6bb61f304c2e8b882dc5d920a2eae4e5d8930a12791bbc837f109d715e94b6f43c0ea0f912edfa65b296b79fd2fafb4eb80d294d411f94f57fa6561c81af4590e4f64e246346c585b9b1825e260618666d790d3976646b3eaed0b62adcf8ca1eaedaafa642b99b0c668fb2ca646cf83ac831284183eaf859b2dde29a5bc4ed0fe1ed9f3b3e4b66b5b1b1b8e2ccaceff284570e94b8e30962aa3f7834b8ba1ea36a8ae66af7c05c9f26ece5af36d3e62503790341dd82ae3f277043cdf576765127e8b1ef261938dad94d9253166b12e3012a098cd13cac7440a796ab7cdd143141d75646524728a119a9b8b7a6bad74992b229f1da3b792912490932d69dcda2f002679624dea63b05b8a626d29cf0a21e281008deaebe2011441e2251c4163f566316b754bd68de1e29d872314f14c98acf06c65072574039e59a4be896da9457287d943daa8124c8112cfd53d8416b5dbe2389f9b0e142bf22bb249b8a65aea8678c3f8e337d8d01cb053da0865c48b95c2a98cf96bf95776f89fe16e6e735b6ff6d77d65b19c713ad94b2d833e274b28a1d83ecb08d14c57a21c6fc084500a03f20d2f2f4e113c6234631c4a4c862c8452d8619e2fb00d51f4660d7eebe5d0b485331281e6e4fecab05ee5b39fd5a576007a02effe3276eb44bc256394bb45df037d31b8a03d4dbff274b7d4dff96796329900a5f0ddf1afc22b52b45204173e66c015f00c263df12c81244e6aa531df60424de20721c938a170a8ecae4ca005937a20beb47b21d5114dc6acf93ea1612242dc85ca47576a18571f7ac8619b4ed0fab62fbc14c988ea251c175ecbaba5a2120eaef75b4a23de5516c4409c15984f80e7a2754be08f8d8a586921d36da642bde79fe59910f9c9dd77ea3043601e017b911b2bf632d7638bfa2a0df8dc4a4158571fa1f23328c3780dbed7d136816beccfc88d346a328a9b5bfbeef4bc0ce04edc95d456661d0eb8b84b5f49bd166423dfe4e44d292b5c221b1a9249bcb09094fc663b9b1a33ac12f371616bc82907844262a4257f3b0f30494ec53318e4208e1927d77cae51515142b0379df332b1a69430dc6b1faac64d7d5c4ea9b87a71af3ad9c2c137e8f0720aa216af2f0869467dbaab2593db8e98a43a77e2c688e0f4ee2b6e37d294f473cd9933f3ddf4a6ed9b6c32bbc46c95db64abdc2c665b60f30f0494c32e794f78d06cc07204763c577e6ea2807cd9129ef13c0c63d564026df11741e1c38e336332e811beaf01a8336ce345ac7558d23ced7c63d4f7a6109116d2f26b10687f2fec3bdc80ab96f9d6cd940dbba2096f69f4cc07cf9b05007073bfce2438fdc73e5d2187e676f286fbee1c9ce169d1ca1bcc3a71d5b515a2cea999f3f4b8b2000e1944945a0ec5719f2ff71908c8903f2ab1ebf811139bc1ace82e5ed82e865146a52e18acc699d0583a4b0b8469387b04045acffcc9b8a1faaac1d47dbf656c92156fa8b864b34d75e6ef4e7dc75b031b2a6f48e9eaa2d2fb3c68e3adbb2caaf732d6f6ea726b8904a855196a864e5a2f835935b51efd00bcf1ff872cb1b4135fcdbd5d1e96a7a58df82a1a2ecfcbf69f5c0a9c093333417d3dd49754668e48b033d2dec98fa0a2adcffa47985e039acc5e49d12377a9f0271e8ebd87fb374d9f854def3b254c1495cd5722b58cb04b6da4484293adc012b3ba3498c119faaebc4d3d3e7b54bc4ed8b68415797a813ae76c4fc43a7818008ad9f53cb63132d925fc1f285b75966339371c9447b2c45f9610fab11b15598273da77731e94ebda44ee2fb236383a0a0deeaaa0ed802dad3b9cbf991474c9f012afcdb34fa6eddc42fb1d2599c2b38fc70c4baabf6d787bdea3ff8bc2cf9631517c0ddbdb7ee2e008622cbeddf715fdceff1bd1aa94a5a280b1308b9751304250c62c27c3989eac079c11f437c3414111356ea1d7987befc81438ae97b6b632e61faec19757d01bb5c31c78b0c90d26a3b71709ea3626198c5562241b226cb1157ee972eb53a12fb593b473df72aa843e1450832cfc721fd2fd7f037c1b6d4263a464d40a4302aa2495b9d9be79915f656fc201bfb43f1e6c11fe7acbaccf803259bcebde2dcc3056bcc63c53d6b292095447edfc39d783edaad8a5e798f1728c64ab0b1c0489089ea5b8ebc7b53209ca084d722795ba667a77ce7f6b45aaa17c68ebda1440c7545e684bbf9e648ce2fb4c2429968a2204695e3e28b1b6ae90b2837fddfb5e70cf62e75c6a0b446125f793cbfd4bdf28d9f6b99da1e276ec12f63b8210c9faaeaabff24bff05d89539e3d6753a5d63ac9c8d6a05482bfb13e0fc8f6a95809478289e225f918f6baf43748868b25d45f846e604fef59e5d00b109fbc8e63307141368905dc9d3d0d0cb3028d7f778215822a3fe943c1f746711fbd74bfe4b4189f88173b2223c3c0266b82b6ecdaba2542723592c530aaf2301a76a882bd71dff78c2d22603790c9650b2e1e1170d05125af5d0a319d745b2e149f60779eca2908fab92f744af749856fe553d3c6a29651aa82d2f1dc8743a8171861bca3e373e295d7ad740a458d2e648c1d0172b1fc6466fc2e6a67abb97712a837b4085cd6a5c5447ba344c977d514eec63dae387e57bbea863222aeae2f17c9f83f0915c8437b28107dd00705f2dcccbc6b5b86c6cf65e7b67229bf72ae1ab5db1316dd37ddc470c48ee9c01f73f4eb0a5a661939aababee0eb10cceb7f259142020f2f2c2cfdcf7e1a73a9788ed61dfc804d1be7e5d2a6c4697a5b1d8a0c647fe72135aebf86f18b0db90bb6bd0ccc896829725c28651d7e1307fcfcee2f4cf4809ab83585d0bdfcc0b7f11245df7eb373b7639e41cd6947e49dc05d1d24e93ae6b006bede35d521db286ea335822967251ca8b1e75fe98c6d323a52810912269918429ae971037503f97fc1930fbba65055167a1142c4029bbd13815d298a459d0d17f83607b8e553b645b928e12a5ba47c3a29411d4660bfd27b522d2238834c52fd7d29853a9e34abfb12528f33fb3d27618e6da73288e1a0ae3b9c011810f73a0e7f5e4a53700d0486e2c7b89210ee348db7ef440502b39a6cf72e127e0a7f12d0b42ebd927e5f3c91f306c2755a4d4870e0fd4145c4a868afae772138c4188bcc47eabb5c045ad1a6d677212baae9ef7ead5989fa664cf1afd35e2a0f79fecdbe7b8023c60ae6f6daea7891ca68e8e995afca7c1ef6a39f24711e02416e6b298dc891eb5a6f85afdd0a44d8a071b576fa14236debe858125378cf160831e632c434b386866c9f6ee7c589a9b181956360d998d1e2ee3cf4d79e832ea36e916003c90f97ff0487542b33d0332cf34ae74a654da9e4e5a40e8e9bdf1651b3d3197f8097eee61ed1d6425eb1975712095712a5c7038285ee4fd16be228d77c66915e9524b9b0cdcfaf9ecd26b4b3f10a4e425f44480cebd3003b70290bbc5398f1229c4a19810868a35504068ac01326812b8a0e9f665d9195d64bd42397b246030c014d748e4be99065f8ea3c72c983aab168cbb76a70e6a8760bda15d4d22844d77f4323526f30c54d604c493f223f4a341675b2696e4ed812bbd81516245b2e5c3879275d6e7a6cdbc6b978064be19dbbb1f656d4c803aab83786302a6b5a5a43a22f99887ea0a812fa8b51aa8637e5df1d7ed5cd318fc5d00766082bcc1def74470c7a872302bed39e8e051ebe2ff94c45217cf79b2a4615a41c126eae2b56037c4399d124d085ebb06d53917a7bd73c1413756a8a78125a64c4227444263469b7b5edb028c7b98d313831c93cbff689080d1bdb6f166644284b25e9704af7c3ad31b34253207d2064f36eb67cefe487b6fae26969b8289ca5290953c82bcd3454e8ba7bde204b4f5be3e8b5afeb15bd8e20986fcccb93d08e8825e988859679b51fa0f938c7476f55dc3929998d1761c7aa25e390caf801f8ff0fe2d77cd8755a04a4671dfb8d0ae1d2e917a66802e786425e13cd695a631705284bd012acd166ef99c75099b6f603dfde93e2623cf6e47753c76e2f3d8ce507298f3e71c7340938679cbfe5e5bc22a969f08c3372c9c084c2636a1cd76fb2e906095782c9c1a9643c968d0b146233a57ad730d77332c10c8167cb180dd3512c24a02e872ca9f98fbba84d23141cf5d66207f879a928bfcd22e5692396ddc80c2b9b1b8b50b8de8cece0a17d3c8ca30c36e9cdf045e4924494d6c99b29e929bc2d117ff452edfd85f7c4adcd9cbbc8a3ff76011351aecd157070ff978a6048dc08412b512073bb2152f681f316f1f0625fba865a9acdb19f3992e9fdca4189d520b9f5aa6e222057b464a80a4d04b2fc7b9f92a5a8667eab1faa27945e0081d61fdd29f1a7d5444f74f09a2f30044d16ef1bf6531a0ed6d1151cd35a1b6283c222185f0aff47c7e7a37a6fa0846c983103871dd1870824b8d18f2163da9bf2a70038b0facf58a67165abd01d21cf2429ec7153fac53e2b6e335142fd2cb3aaa02423e67047c73fc811b4ad3c8b452fe327d594d9e7e1d51417edef03990949db1f7e274080f76644ec70b2b6c05267ddb2d6c806e0966303c77105a1ff0aeba72558dac392c66ef60efd29a6357cc644348b8b9ce3c39243e41d3a107355ca050109fab6c07380c8ca191e908c144271b2b55a8490d28296b0bdaa34911268801aba316c2967dac2ada95da9e41c72427c498ea387de3d234e5d728959fcddec1d48b05c86337c38dc83ee23caa8079d5f809ab2d1f30dbfeaed4ea7e4b87fec0424d66e7ef425245355ba9994876e17000b875b53053eaf8f38e6937aa4f0ea2e8d25d8a5e2087be8f9392bd56e9d95520efbfecbe8d312e374bd8fb10a6dba08de8a096af917c4affc0b27e093ae6d1ed63b70b0b88dae467bcac39f7fc88c1a08ba9b1d4db0dc16e2df05e265019349f8c250b2966754bd3aee8abfc280bf03c7dcb8d5c003eb7afa191842ddffbbb7e624da7f397fe89f90b12d349826d807a2e3f357a0912d5af5b2273b32ec9974f43f163f2aff433cd805f30e26edf12f3a6d67ead33ad272e4908cf00568cfbc7ca9b12e9b15631814e547d6569d910866261e817e204b0410ba0fa7511d7878dbddd4e456b5aed444d8f730b5ced605209c97a9c9b775e9679c3664e2dd37ef7618fdac726bb36ac97ec093ce3a85241b49b290fee4fd53ecc38866dda42ad9e89d81512cd5482f6feba6b84d099f1e0d9d2544c2462149b6304394161e678132031158b1bd24066fd2e943adcb202d4136b5fce7facbab01cbdc9352aa2e773c8a40fa8fb735facfd70c685cb4941818959346ef51c68ebff31f6886fff418c58b64d22b17c70ede38ee5048c06e1c47d7159575e4b31acdf5e1132543dc1a394dde58683bf6839e222d0da5303e1eaf022ed8ff621c383856539f24839aa597a53329b6153c1c663d94558289991e0efd67c8971dfeeb6f36e712e835ca6d6b12cb8deb7a39e5686d0b7105d0f00aff977aaf69f9d045f19a01d2aeaa20d181dcf04f46f5557e34205686f4ef090aa0dc2f18d59f049b313b135c52f2a6276928cc0f11ab4948bb463b12ea9e3e2aacb661846247a5c3e3d349e822594b61dc48cdd93e68f559cf6d834acc90e728dd3288e94b99740ce069be51320defa30e03fb5799a33d7440673bb536d34817b1ded0cd3003019ab911bdf5d0384d48152312612aad122f8975d4b358bd2900dfb7e65ca31b2f7be187ef465777c278f670ddbd71deca7d5598a7b734913a13762531d2b2add16d5e37c92e7a1544011be58bca9f05750b4d86c9fd2abac413244404d2e8247dfab02c91ce8f4e6e0c9731cc82cded1c6527a844df0d6da324a192aeebcdd9f6bbe1db18a50813421271ed0678a8595c0bff9393ff84db4702f02eca84f25ca461eb06c310e1ecb75863860e47be4117884f075626c716af125b03ca92208379f81dcc34e4f41a414ab8b5edde232f8fc280ab049fd082fb2a8973bbc3e8fa46937704993202d184e17f80c74d3d66fdf28510fb1b1916ed1bc7414792af8f0bb1c5029dc468e3931fdcba416def99099cb00e85e695b28903636b366320015aeda121084dfb493171d0f84cc3708bb15a827b9f4f8af6782cf047a876096716594c6042e2c62770c37c86a6992e26561b4937be8deddf762235bd98c8a4abe96acd8f44943988932da6622c996564e8e4bd6d86044becb1005c7014222588fced532f040d85f21b694a4e940b7292545c9d7cc033b6ad4c1508dc7da02701d8d5c819deef613ac4d2f6170cab35ebbde63859a3f1a4397e24c51253418723f2a37e50d1cec94e0a1ea1e3f4b9ab19bcbb1fe320081e89f122d5592111cd83b86ca5d74db8aa45644280938af94f30c246de5a9e42a4e7c806aa4f6bbc0b40b66650fae09f068980329ee6ded77e255033c84f9fbe734bcd2bc175d335b3549a3567f0a5a242cee45c1d37f0dc7c0e091404b766ca4e37d40a3520a2538997773fad1285b4da877cff9e302bf838ba0dcef08c346bba42cf17e1addce3b129357a52ca15e1847649deb1725b35a6f92cb599de7ae5bfe1312cbc1e5327770be0eff878e8f1bde2a21467e5fbecab7290a1ede10b9df07eaf0b04d69ffbdaa12b51d1fa9522f982c4d89239d47f4b56ffbb8fd630b3e6636d257e22d3f31fd1f59eae4428b42fc9ccfac6cec11aff3ea7d88d37f45b013c340faf832ca6f3044dc026011db9172ebd8a50ab81f86db195239097ad5226b5fb07ae137250b94a651e40711a345ac56fdd076f56f9d2edad70356c1647853a562df655a338313805345bdc388451870364269856156ba27dbf9f013a86580a58275c3a0c96db3c6bd69e69c6627e8b37c77000cae86f388c855d88138a1d540510b7590554caf3b3ee1c4de0004826ded89c3c2d886255eb6c352df92ef402d404b008751a6219cea7831bbe590fb7484973247e7eed62a41fda7fe1b4c517852f9c46a3caa152a6ba19ed81d68060ab7de2ce648f2e959149627345df0af88013a778e50256572cd0f0db53e6bfbd0b265226056157d842adf904d66f68f5e82ffaf7d267bc206cf126453fbf97aadc413e8bfd0980f6d2e51fd12c6b8c450d22a7632ff78cda0c94ec01807bba33e809a36bf6d5c3e15a65d0380bfb5738f20fe99bcc5c24df1f7dfaaed12790f48d695d10fc94448aaa6483cfc44c668d2823977f80ca02bb04aa050e297c39a336ba8ab7392f3f0ea13924ba2e4cfe4c5320f0a6ad82e7eccc5de9b85d68ae340c4d1340b64fc691e2f6d976db379468c80f1a2f8ca7bd84540963fadc8241efac5f7808f44d7f7b65c84a9e597b4a8f820a8643ddc0b3bdc9b3ad0bb1c3af39bd93187e37b6adfc8acb7985898f3f7f08076f5a84e1f44007572f1cab6721c2d2e5ba74f0237b384b3d2f801cb2adacd71e00f0c0d1e7c25ef230bb81a52cfa718ab44ecaf68ae3cb224ccb24b78ab3f60e445b67fc38fb2b395346370197aaaac7517d2b2aeef97769479d46358d8b5f0737c3304ef4cb623a9edf6f53b433d4ba88f2a71de5a9560c0494de2cdb2be50b0b228b1051a2708fdc673fa6df41fbea855fac8594d675b7782b86d3fbe2d010a001a81c82e8de37b026d989c382b2a463ae5855553d2a2fd4fc239307dc2006cffd98ea7ea19c1ab6f29976568c0180742ceb1389f2b787525d75964aaacc03b7945f1be91dbe8b9671553c5390fc4e6b504216f535c8898e54e8343676c61faa9650f3b1ac01af6629a87cf78d157ebf2576dfd4035a5c94876d5c46051919c6574b57939fd6ae2fd2128fbcccaa43675804486b48088d076b167a6932c10094d9cd0a0d704ce50bf44c160e3a4dd947e18398f8951353bd2f7d10901fcc1e467e5ed14b5ff29adf1db4fa4c1ff120a9b6e96b2d96267b24de93e5b58a730355b647a71f8c66bcd9f005eae5f2621d4e95a0e8f0040dea08c5dabb08af7e06e3e7e082a4cd093c840486db4b508ee370979ec8e7556050b81517a42b7f5428e3e929a0b36862db159a17b53ed64e3b19824f29a4690b403e1a06aeccbfe523887a99b8bb389be92479bf4a88bad4e9fa0765e38cabe9b4cb0f8359ac291513e1ab0cbe99a58ba6fb01277bb092f76bf72ff69b056c808302a73c303dc03422672236fc9f0e0e3584834fb3e666af49172fccf5e62e37a5d8ef3c30eb7598053a03524e50e3629e114de48ff812d3ac27f69fab79374e24008af2c22ab922189f58e73e3e2d433cb8691dc28d394416c53adad6433b24c756158e5183a4c72b6217027bb06d3abac3724ff8f65085c9c274f4361f4ffa696c196a5ce5c06d015a4869aa4894f7f23c2c9b723dc88b32d23c7f7b17fe0d960e75d43247e3122149af32b83259e273124e2b7fbba33da026be409cd308e87b99fbd4dc4e3b1e2f82b41ef4d94c4833b737775282fd5879f57b19f814322fe572a1e83eff8e7c211aedfc9ad3826d4fd63e00ad3f6f5d7846c028f58bd97fcf048a65858a6f8d29d245380da910de6a206c761b8f6d9adff7ab770385fb81143e96c8b1b1b50d3038cb42e6627becb2b3f0e88797ec28531752945b90c789487c5d82b46de770143ddef2bd48fd0e0b784ce88b32b93672ff466514e73d0058366d015eec42d82ac2416739bc1d07425ff2cc7b40ca139ac01509eba5b9202e7e721a4e4d372e1e98d84308869f428f96548f633864a57b7eba50b38e021a6226e28072096f713051f0b0f6ccf473d4b76cd400ec3d2fde6d77af2fdbd7e813730995deb9066629002d655f6405da3e09e52f70fde13e5a8002f9984148df1c0ff041ce4a51150e7a76c3cd5eade0672438a5ea1d1dd22bf7a77b23ef9faf91d032eb18c6ccc507582531d1d7879ab921faf19cb135501352150dcaefcd82dc1ffef26d41ef2228297b04cc49e099ea7290257eb1683b9bdcd3bd34921f0ddc415d4e79498d580f340704eeb78eb63816c3bbcf6482e4c2ffeeb356cf808367622288839785f02da91875ebd91f8271b60ced8088c8c10e1591c64dc26baea11805b46580dd9f10a9102266062bee1e3e475b80079c900faf306e1eaf8f1aaf4484f0000ea75d17a0b8d9ac1d396615d1aca3af0b0a9f6a3d86f798679c129e6022522ac7785f06b97e54dda22274b7f6b28c57df7695ccba1d1edb1ae386e8167bd352b49b54168f0b01c77ef1e91baa5223e002ad97d1a77aa9c249dddda1aa025b72ed49a10ecd92d4b1ec8011ae096e6eef733c7e305304d9a68d74a7d8abbfbd3d41ab9d05d1fdf5080883cafe6fbbcc97a843626a9541efce71c8bb4a6b50323193a2002562b7a415d4de5baa9d5c72068d1442d7498990f218fc03b5ca506e154ef325120dab908552da646fc5d6c2d2978fb3cd67bbccc28980114d084481383b60ac18d9cf5316730c0a9d02e46596426e88c854b9898b7cf798420776e779e9c51a084aa19f2c753f3de4ac67e558a6427a04705884c183295ec6c48b9b6ffa67a4258ba74b690d12381bd1a4a887e0b231ee84077fe2797b23ea41290dedfbe00a2446b17ad57771abe27f3e448bb01b17f69e74a063a253c91ffd93726a7644b12442d70b8753689a11eb6de126041730be57e8f71dfb56179d1507ae113d480827bbebcc7ace9d7ad5a46ef018734d393e98333e8b9fd0f77317ea5bb2d594722e3e43c556d5088a6b27ff4adfc0c1384a87676bb2aa30217d642bd6dd2add260d88f99572949c86c1fa4a1332bcd3728986c45ab37c9ff6db79b662323341b9013fd43f11c15eca886b4d13c8500dc1d8df937dfb49156262a412654347dcf80afc2b5ad6847a049569a52d91a93b047a0cd0836e6c165a3337adcee9620a1f19a5d392987cbf44ed846c39e36581056a5bbce8d26af5f81f9f2cb1bd58b17501e80853d15b8f735eae9ab20741f04b36654b4eb0e485b28bf7786d4ca494872c8abeae9a358850bc62b4e248201f315885a1b3007d4ab32ce52b3f4fec9968137edcec321b6f4a62112e4787b2bfbd7602cc6005b7eb482de4aac41f4f3403042c688454034386ee1aab7ef75896beaef9e6d178f650dc211a4ec50aac20e43008a659f19ff1b3b52ba2a53e0d258633e091137c025085850a13db466755fd1a387fb0b270186e001651fb51e422f31710dfce6f3a56e94cde2e9290d0cd3d1aae40949d1b7cd01599182d3a7dcdb3ae8cc005e2a14e1b39df73084f84db292aff9b4cd5373cb5a58def79c64f8f9b124ded447ca83e959ddc955e02f5786c1257a84c5697dda550ad7c7fa446840f9c52aa3673788a425a8f39898b64223b03433f14358f511051ebef163691391a110b6b9f7700ea415e2fdfaae627af710e8fed12c0e416b4c0b58b67b6de9c7aa4f5f22177786fedf9f06ce3a94d21f5221bd8961a7e292e9cf231f57117b134f0a0760a6748d626834b1e96296635c430371dbdd772bc5fd6a3a8cc16a23a23ad590243e746fee1506a882c081eeb2d1806ec3878562fd5539690873f380628c189aabae6ecef7a59a33f069aaed9dd117596a9f33de6768546b01bf20b4caf6713d148cbad539fee2b5d69c7299e5c172c53a7974407ed9212b8abdc2f9137fb7c459806fabccb825f75c3c08c0dae23d223d74d5b5890fb1e84340b3916a7cdd466379302100aa313e76ad493093d1ea729f88743430d4b9de0c070ac5e69875be9fb9302edc0b8d623750b727137108494ca5bbe9dc5605496df7869a75af39b8003e759e2c02f8463f46e93ca04", + "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f70a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510fd2e0c74ac08efb87cf1059f1e30dcc9468113293de905e1b6098606e2dbcc3" }, "decryption_aggregator": { - "proof_hex": "0x0000000000000000000000000000000000000000000000056cad7c4d4ab29b08000000000000000000000000000000000000000000000001c619e9b18c75b568000000000000000000000000000000000000000000000005d70fe88223230f090000000000000000000000000000000000000000000000000000f4d3fe76e6b400000000000000000000000000000000000000000000000f3b1e196b01bccf7500000000000000000000000000000000000000000000000b6a2a87540a20bf3600000000000000000000000000000000000000000000000daa621f0595b95f1a00000000000000000000000000000000000000000000000000008d5a8ba7f638000000000000000000000000000000000000000000000001accc4779895fcbaf000000000000000000000000000000000000000000000000668ea7d6e9d31a1f0000000000000000000000000000000000000000000000044b0fb30c4478834500000000000000000000000000000000000000000000000000006bfc6495aec80000000000000000000000000000000000000000000000004f4f3c14746f379b0000000000000000000000000000000000000000000000088dbe00e529eda58c00000000000000000000000000000000000000000000000f2605405f1946fd4000000000000000000000000000000000000000000000000000025b1f866541452ef1d421942cbeb1c5cfb5397da431759d5d9a9c317d36a930660d1bc170b4702ef125b0f2c11c7a4326be8bccade5618401aefc5255a1c696e6e85324f1050f268c15d9ee4f26e41b34cf4f0d5cfb130caf915adfd5ba31f1bcc79825f919471d415c3651ca431b5f3cd654858e981efe0855a21b2e38d123135b44710f1cab2c035e4105d4bdd3529bb5fe9188da07432c5a89e76b8f89a6fa18f3529cc0bd0cd2927992356821b6e43d1bc83f471bd00bc8f49254474a4f608093bfed179125ae77567866514f161a7684c7e6f6655e7b13e3372a7134f9af19d9f684fceb06f4c1e272c65fdd85029c7fb523f641d823a62439843c26aa5cacb8fcf0dfa10446d9cf70618a9814cb612660cb51726a62b6e43e543cfdddd4d001513e0d9529b98f6dfe08ba29b43c0328d7f11c2aaa68a41680f6c09512906652df9b07b81922552a60c62d7866bfc580eee4c7a39fd466127d0467fd96a77f978a90deff11f53d729bdcfdf44340633294c43751c8ed5297483960c58ab9f5e4313a5e58037cc3e1e0d78015e20d0d922b7dc641a5d1ea3ccdd01925140b4035dc0576c415198c1b75ba202af61715a9e087da1e48acf524606b9345ba54bc72b3447cbb24b16a9c8665ed01f422f4fc43ce9b9b4f3fd06dd1e170974b8f58d297c6998219adee798f050eb69bc48e574c8cc88e5f54a599078596ab2010dee8ad7fd671166a365ee47c4303fb7f3814118d649b5ca3d5f81e8532255ed0a010c6f264b0270b360e011a625807a323e92b639d9c82d3ab7fddb9c617a42b341b7da8cc8f2f3a68ea0915dcc62b8ac703522c1ebbe5530bc3f347537fef899406586e07d21d6e94d5208ecdf0a86971102ce7d61860e0bd1b5125ce717315f91e4d3bd4100f7b505fad6af8e3abbdd4f0759813aae3a05e90c23b4ba78c93b25b1711b9082145f3fd8aea81849b9eb991eae4d7047d7d03ddd13acca9a9777f25674154e60e060bb5c5c7be3c78c5b31e43a5c897e4caffa9f7a1784a3421260ea5aee2d02e6433c0b5662245c4120deabd578c95be23824fddcf69241423fff241f95fba244ad1484c09e631e1b800a5d1ddbc91300085db9bacef86ed1c4d3cb780781e1c9e02ad787c161b5797f8f0659efa8344be77edca236a9fd2bf7bf2de0aa7be073b7654a7dab5618a0ce0309e58b827ba0946e73ef577921924d315838740ff2f02dd4e38468fe93cf477bd8895f1dcc5cf8ad4183ca384bdfbe3d46e4bfdfc13fddd978b48eb5ae0468a16c16e3a40d52eb88c6698a26fe59aa829d3548cea01f8791499143a368cc10df96dd9383f216939090abd0f703ffb62811e52d2361b848b466597ff32c1b723f6160f5e2a142b2eb8e636375a1dd708b9593913d80d2443dbfdb9aa76ec2b2a38a38b13f6511248a7c672e7b2361228788754d4c622966be5bbb77049e05d240123925a9c1cfdb7abab0f41c94d1874090481f9110dcb0a7e51c334aa75119c70b570e358ebbe6a273ae63baf45a461b2508e220422a32a363f8a7c9a1b2b2d5d5477762295c405aaab172eeccf35f892a410c5d9098bd985c36b0c0e5027c47d43d38200babc0cc31af1b49741a4af672038927004aeba9f5a687164f44ce33aee7a5c026f2213eaaa2e1a637d9c946bae55bb171e53d2d5e5c60820d878b6e6a3eeda0199fa2608e90a08b0fbdcd80e5f445c6e0667b98efc1f4fd2b08b320aa8a56807767a8d607c28db5ea61a5ecf9976ce281908a1c40c1000f3038f9196f47dc0ffd1d74305a28ba020cd726f6896f7fe390225cd292aeac8305388b6b765ca96d911283e733663900abcdc06ef4fa7570b15b7c47708512ad8abeb9173b1e6871fbf4315c843b2ea3a91afe5b23b82139d12c032c998348c3f44ed226fe1afc990192fe8bbcaa51e4547def8bb76c8a866192b0dfb27ba2db74f99b66881b6b9259e30e7795eb7524f2b82a997ec646e53031ec3c5b8b34022c16181257ec59b0884c7b4fd20d4b9425e8bd1f375deeba525971ea65b4a5f4256dd47880339f6ee908843d7d2cef8dad1fbdb75c2ca6ada1415f83c7b02138f0602169c0f75725ccf52dfeac97bbe61f439738325607a9e255e82ea48ed8af7f60d3a6b9f4f7c15250688bce43dc311e4e382a8ab0c3dba06c7b8c5ede63770e92feeeb31591d9e35f0db391bbdd3602b73bf8a0f0e91892a7acdc0a53834569dc6b661f12588133c0782d14b3516d4a9b5fe5e9c9df5df0c89c531e0bae4e6050957ba7ef3bfb44bf0bfc1a8d9b5b3d72de063dba8772e0f21894b3966a410b2cc849d184369cbfc20a8d2e76494c73f6294745e969f521f0fd22cf1b3dead3888791fe3a073b7be51f92c285ebe305ebb9cc691bb38b02a7360b39a0cd4db80dce561d9e798ae3bef95013b7e9dd5e43c630b824ece8b023679d5122e7dc07c95c35f9e2ef131138a07bf9020d1b62c389fe33b90552304be90309b9169733745f5900911312d4684235470faca34ed59582d1e2d380f22090616478eaddb735390bf840de0e5751ad629e8413921c82423fe4626c0812b612cc2cd48365f7ad6bb8e932a405567f4cafa3e3fd446e2713f9c626c6ff925a4b25d6a356314bd347906144b57400a22f588169bf9d4f30e77b9c6126a7c26970872791915f48f15f1a6378a83f588850df74ad183e97a9c4ce006b3ac640d2a650b8f228902eed1d0c2786300bdafed28dc54498c78ea482dc2e893a60a017389725f4f281f267191e72df183a69e0902c10081a40fc3da3aed353f03222db1ac7af26d0bec38702928d402544f59e76e0bec359e880fa2843665a0beec29bca4e0d866154021b0e26dcd7fd75b17625bfd982e699790f08ac3a44f584a2923094ff82c4b714ff0dc3a3cd156e174bb08f35a56b7cb2c261a886dea21321c20cc2635ffa25ec21be53e93e63a8267a43e3bac1a43172cda46e031b297a72abd0445f4d8bb99f2554e6f539a71cf629a62cbc7d0c64a3b9dbe0d19f4b4620d83e8ad85e85da1a6a18a22d261a036180ac1c3378c125e4a0c03aab46378780672aa764d1267a28d7048f775faace9735fc5ee7afdc9e17fa5a9721e976f842f007d8690aa54a60c95bd9a013a80b59b6a22324bf2c90740967c080bcb48140eeb8246e3d623b8d388a455c9cf7f1c26b5e98226b396810015c7caa384cdaf07b549ad42aab158f69f3da72c1ea1a5c7cf00b7781f5e5b62ab04838c2f6586209c0cdf477aaa4ba459141775b67218e064b09af3be3f2a03854839a097e3a214f03e13ec21145ebb5ff5c81e1c84a8dfe3bcf4892c79d741144d2a996bd8422321999bc8e0395ff453438bbe7395e0695e49bba09ef3d8764948e1ea9cbccf2fe535c918810038418b8fd8f048d0db49bf6c1bfd553b0c394c8f043240a1a01d143cc3c50f981f3e7d6f6826ce7c2af850858753ae5454281ca9f929134e6805f200d4d7e2d7fea1b738f97037402dc6a3494b951274051f848c485d860c2812c2e371e5630f2ab4e56da8b2818468f4927c63699d3fb07611c88e0f2983b6294f3d21bd180cc64a5a2896d472e5b3383194141ee6003b2827513c89e48b0c235cfe5a962ffe156f1875f202fb14d1ef70eca3a0ea8877981010027167b2be0aed6b04ca467b3d9a477a1cf3f9759f2878e237c85a88ce01ee2f97fd97aa750f2c78111ff70bc2d8a535235222a617573f21dce2cf3dd25b70854b9ffd85350129a858ee033ad5f7fc66562f89d87afae6c544a8686499572a035e5995916e183df4a63d8feb24590f28621073a966a61699cd2377125be6043365010e08c61ed3b9c3d001d9c6cafdd4ea120e46860fbca37108a9a5b9a9f2cfaa8446a25b204c4f28ad5e52ab1695fe49da8663e90c2f797425ae367a7b4a42dcd5bd3fe926070c3ebcdba9804cd4a74722f73b0e5fef3e34743e1182ab54cd798228db6315c57f09394125bb7cba5c9d572ad6d255b4b632732cd4ec7063d63eedb4218e1f4f7caf1d3dd25167dd22623aaab18ca729628705911872313ffaf322ce01cc11c936d0dbb5b63c16ee60ad0a85b8964093eb18a940250ebda39766907bce66207f7dc441572f9677aef7a72d3e5fcec0c942e33315dc4ebbbab927bd09a2cd215d120ba8493452622c212d0aab531d9a7733ac743f52608390995cc2f752570304dad42f576fa8c181604c68f2cf87555228663a7c714e26eeb2c6e5035dc80ccb8b814f89a2383e642b8f829691753053f8140819204bd2180ef8c80e93c8230f81025fc3a42a1aa003c9b8eca00e0e3b850fd88c7e61e94d38b4eebb1c47059fd472bc0b8a3b70517698c7b74bb5e00def97185cd883247b4ddba10739fe06a3379164463d5854dd9a241327e5b419a2993704a75b513977b69b96b8fe8b0c7dd4726e5551284268a6c2e2667e0dbb3b28219223bb18f9e5af9d6709cff22b6a031590edb6b989b09732ed7a0a228a67856f391442545e2e1f737606bedc08f6e378d3ad8b0ba6db8d32942fef5e5378046832541b2d12a81ab902352efb246b2c10091c47689a425ec24e5b7f7bc59198f6f27189a2d7f42fa42b6205ac2e6aedf6cb543d0f606d543198e92acf412b5d884cf750f3b73f8897f702656901a19db1c90575af7dedd38bfb74229699003b67fbf938473413c61fb5e6c78b0878fb7a5db4a5b662313d0612e4c04a4464a176e06b478b5cf83921b18342452f324d99695dcf4ce33ff8efc3fd088f49d0747ff112006b954de65c9c8817af0ee60d9137093a9d4197437d2c57fe12ba577ea475d60906732c5746849cbc50162474e22b1c3c16e4d35f0e6a19c5ba983c4a1112f9281cb1f7bfc916a4caa92485487447bb3393167202c3696aaa302c00a8330093f3a1f3ff72baf44420392e5d2dadcad2bbf8303c926c7039c3c79c2041922c6b26504cc48eb5d12c2abd0a7515c373df38a8b44f793ee83bedffd35934f865ea07f10c96fe43e8857907000a4208a2703d320f159a24f346e3bf840260d052179f50919568d032a820df2b38066eba1ea7cffc02ce4c988b4787d58bdf85849317f0f8bd4f715314438f2237e14e38785e43212317697684d4a412ab17cfa0b6a64c8129424b6c7acb8d1cba0efa1a00b3e405602e7d00df2956376dccbae81d3faef40fca3ac6dcbf4f180f72866e5852fc2f0a5890da5d880214ebd2e79b04deda1742a1859f6f089b292e1c10696a966de1ee893258d934f9e851cdc77e848105dedf1f8337b074861e9774475e00815c94a84286c14d1e346f7da8d89ecc16a0c57e32813be3df9f2ac706f1fc284f222caf7608782ca6c7b7fd86c694a5ee6bfccf9eacdb748d332fb4ba7fb8df774b85b2d1f3adb3534985a4437db9ecfdcbbf9e0314a37b7c72205e241cccd78355ac99944501cfaf2c4ee0d0326ffcfe04e80b51d98b4f520e2e9e0f49718ba976711a22332e887c80194195721841e7490949f926bca49c0e2c5ac948fa21bb642670664aad40c4ce3f3ea70cf7902fff4b3debf9857dfc9c096ac7c71452d53f6a34686ff32984305fdcfed1fe0f995a35894efc50182965109605b2c39700a0ad4041c6541186a45e8d8218f4f4b3fe80b45ad08fdc4adf19f15e6beaaef77a30d12b3ca4303b4f55a4db68894cb4916a602f937439cb652f9b0798be3ed4da72c3fa8c0e1652baa9f88e53d45b7f1d762a91733b7b91a913790a477fe63688116c2b9f014462bf1b667c1e4f402a456bd1274c0f34236d06ed70c9b73a587e902443ce4853bad73c7ae5a937a1e5abb4a9bbf069b2ddb4214bb100536bbb39181927d13f2807691da20dfefa9459e9b0dd21bc3e8c33590686c366bcc30074314e6f086c6384de4ad088a49b786d4fe564b3e460fb97e00fd0cb2dcf6a4019d49fb759201a1509e305a20b0f87e49b3eae7218fca5f0b423824dc2d2ae4cab3aa343abe18d31c9e8a7ec65b6e8ef1e7365d2799b931a4c0b2afd800a183d8e0150007ffe345b3693f3acbb7ed7deaed961da6606e00b6f1b7a15f59ea2046f9375819019b86a5c67d16d94ed5b0d64295a6e9e9be90c853062c4bf2127f94e4398de65e83eec4f2e925f51ac77acd291fe3c4408f006040a91726760ea896b5c3dbb049108f42de5f968db4ca92e3341ecbfbbc8bd7968251f3fa3b07e2549cfe3232195b62b1b328895a777653358631d9ccdfa2f4b05199da8bd676437df062fdba92c8d9363bbbfd2cfa9b522c295983cceaf011e002198f97129a3e9981798ea7fd7049cd1514fb8163b0cb39dc8bdc58221cc19062ca8191c9b30ca4b8a7dcfa8066d6491e7e320a0b07c9b907d489911b05be0a726273667acb63e98cb324ca9064fe9a3e625634edd6683e695b5daf6c04ce97c198d7a2448ce0a0cb26b7ecff1ccbaa524dd91b62dbe5517a89643df21a01f1105aad045e0e4151c8ce7f781b40b424b1a071c214c86e28ea60d2489e594830d2a4bd978bf37e94f0f6824811131f99f95e4d63e6a0b13318639f9b78caa1cff2efa88000f5f654df97206a86ff10504529a5371babf812f2f9507b156639609268cc19ce52b7d8582cd9b3c2c12c2a152a085df6366ecab2be22b8620e077c30d95f6757d5f87a031d47d6497a2e59fa8bf4ac2cbbd7a58bb2f2aec7d8af2be0cb08139cc64f33d98e0c462602b4577ea1f0dc893671a4bee327c9b74b7db2d13ce138d323d1f035f1e3e4e0fd6eb69ecab1fe9ec5d2d3984318a0bb7e65c091c416fdf7cc647b1d3db7d46a8fb1e013a33a8f23ac33987832dd47178a51b2e0eec25fdade8e4794a3ee602f3a41f157191b3859a0b5f91f9dbf921cba24eef05f02af93c999a3d7e457d4a94a393daa7ee8dcdb9ee235cd52bbfb650aa70240cee561b03784a493a7109a40e337d51e55ae3de94bea91662a9dc7f3bf8e4d32f3d70587403d8280e55dc12f0afe0e6dafe9c19f2c0abebb0381546a5debccf264e53483931fb53449130f47d1407cd0c372637c0a644bdb8b25561bb28fa030f303a7d9bbbc6f0d2d80986a300cacba5276340a6f95f5a58dcb62d64218ba208aae2a01c8f4dfb42a5f93d44e870b78edd5bcf239888d6692eed1a118b799705f7b93c34b05ce3ae60f439c1742e22d456d35909b541df1efadd8e19eed68f1295e0e404fce2abb84fdb20c7fb59a1796b7db57ede655778fa81bdf6bddc000f06181a177c30403b7a3a75b0dd16518d63cd9e9168c7b891692816985882e40f1d0bce30a24709a075b64799d5b3e42f16d794f34eba8158f842a4b04e46cc1464e3d7f0282d9a85913fa90267ee8565d27fd10e28a2a1495b6ac494faeb9b0ba366816bdf54e694c63b753d9b66ede27540e3082b8a7172755882f56769130f0af577b8c3ede6e8eecc9425911787b62c5468a9ffea09e7257883b554d17704a23942749653ad9a87c8728fbfa56864e69bb8ae9607228bffd91643a828b31357a199ce3f2e4dc3fd57cb963d783242f9369e886376f57b9497504ebb04311eeec6e6c20c50d981fa9719fc9ed87480ddf9799ad62e7b1996293e2d57b0d92d05db41076cd3d90c81f793e57eda1191e5bdd40fc9d4831fccb2d33e8a569e009580985e29d40823ea35fbccb800afebdb2083a963ad2e72bfb0907cbb026e1224c0ce5f59107ac18b03307bf581f6ebcf3ce7800eb87b02a4d25c3c0780690a714e8aef53ad3e7ee56dc8760a1c6ac40b67dc97386716d8b7c8411f8e0fc10885b65982e9844784a2de0689a608bd2b3acb490d4a1a2a8902ffa562e20fea0b3ec2e1baf84eaa8955f757f304d164da3c8c1583567ee07a64bfa1e740f09427fa58b4185e625c869f6220eabe5b2f89ed573e76807d6834a6d93cf392b87e2911224dbd6ba3729d896600bf314e476e43c599de5b638ada7d19530fe557dd1401d2b9f08ce9d2c5fa7935c57f42fc83467dae1943d6c27882686e3f02cdaf1c23df9d61bd4f2b709fa7d2f488f999653318d8cfda4b40f774190c6ae7c68d04892a4456ad9ce39c61f7ccd63bae1f8735f269382ddab8f29590a03db7cc081f900b5fcfbc91245d4cf6e5d757439efc2b1606fbd5d2f98ee420a6b195a7322557b58063144c3b79efa8ca875cb186d97494f99c68ab9216d3a2e281d7d40f158b4dcce0f341a6ec3b566b77c8475f582af06b323c9dcc48fb8f6e4c24d8bd2b6ded7c6bafe9cb0d8dcca57887b1f03e43d8d38b7907ff65a37b78e7cf0648123971a67c2d9dd6a0138b2002ace0cc4839566f50d6095a9aa06a96083951752e8f860211deb7f9eab0bb30f442879145f272c019d2abc5206aae3924a75010275119d2ab7cef59e1636fad4e8bcad6589ba476e38ba5fc71e968541b1820b12ad654f7ebd9a2522d51d47dc5563ea7766799dd694bdba53b7bc2d2ee15f66e0e3fc5a203198545ca949fdff3dae7e730716d079ad70b35a4a3f49c32526592177f84da459ef90637dd637adbeac1f397ac1a8fa7da7d92e2057284b7afa34a03ec549f7e4965203ef4c0f6af45483907c7953bcf8c7c889f8540b93c48a746229d7a407e0b5589707b9bd26b0d13a7dbad9932aeeb8b7e532566cd92a882042b82821e5a9f5116c612818f9b586b639eba41e67d6c42528bca99a7189bbf2428231bf5a4a55bb5412bce1e75a98aae332ed95fcc476a9e18c5b2a90eac937a016a2a3d1ddc5fe9386871595a4c43ae2a5eea44746228ffb79ac2d9e4bb1d9e19cdf2ad6516c16897028def75fe6a78ff95e7062bfed70f2398582e004f7bcc030954895873d6342cbd903dbbe4b6f2f96b7d64579c9a8fca8996188fa3d9861501fe6f36e13a3c12589da13ee190064cdb3abc7143800a2098120cd0636aba23f08f43ddd021e098bfc75ed28215ba4459610ce3e6ee8194d76d83dc50cff7212d421e7d53f7a8dd7c2e1e37ffe54918f94f9aeba116460e76ac28e44f1c3b266386ba3d0083f22cf5e82672ff1bae279291e5eca52f58b928c5e2543af0e20fd256fbfe682dac42b71e11f695165cb77b9c7dab72d4021899aff8c9359ddc2d3310c8c8bcc83fd122e51bd5dea954f2970c5678b2b7e162a9d491a33e1a1b18a7c052d67d102b81301b710279d85f6ae7fb27eca6387bf45bfa08405fb9bb0449911ac0eb0b98c492b3675f3c8b17d8d4071115048d93ea92df10dd66c26523424c8b0d693ff682420404b198302eee8075c3ea7718467b0ea47e54768edc1e5bd11b2690c72032d1762d2bd386a76e7755b63a2d91f3c20a915289a334d82bed12ce87366262c75696163c36ff5b6533912e2416c90b6e307fa71935a5352a78296eb10928a01c2c4a651a4eb3d84093e27e6350fad6ead63ca737eff9ba04a9b5d17b1c78e1bed6711d5479d8d7590f3f050b7bdb7b15df86cba06af51c2a3341060130da96b435ca1e503c509f8e6efb90fd78840546f24a21472c757d0683c8408285b2c5268c325330e3e318ad6f968d606f1f6ba481531195bf905823fdec89b3dec12f3055bfb8f4e93c5756c65f5ba4fbb00e089e1780abcdd4260ad3487daa873a8913b4c45e3b7f68ceb9212a3672bf84f085d7efa6f261d7e42399de655fa523d772ab1c1977833438eff839b68adeb8fe5aa8e59d12c1d70c2ab4d524888f9758141a552238aa961345d98586a78b2ac3038c8db17f6df1d82d04959c242a3e53a402fd87da822dd33050d9629f63bc27f00a9d46cbadee3508dc65c0df4d1bc81f673be17aac5ae7f3f69fcf7a6b1cbbd3258a666c9886f229bc5e356436ac2d1f53b33a5edd19e1a77a12b2149b6a5adfc40ce4f4963a8f1a06ca726e4ac8dcb3631b1423719308baef7996d574b9bb675f8ffe769dba96276d992c218ea1f31ba038b6452bed51cdb97a78433976a53e90ae82249499dc21c8b280bd34f8521011e2f3bd49c88c90af6ec95104bf11178901157fdbc2f205c3f2f523575b57798ecb059e9c04d14156d2cb37bc8e01ad4d01ac1d8a3b2c1a85415be0a1c245d9caa40076146e69123ea7d79e8f66266677141acbb866f813be14adfd28d46f6c387185fe1ca5e7682b6e6349157ec34ac1d1c98c423c220dc47665532a35946c67453844da63cf704e5292f04b810d0e7fa57c3150759b17598d227e1b98cb744472c8235c725f62484f50516e8e3cabaf70e078e0e3a7116e076bb902491083e6e377440b879c0bcae990baaa3a8e9b75459ab5ce62d60fbe4f0a324270050f7aa5f71e5ba518faf8e7bece0338f44047bac43a5a464d1a5168f794f1a130f23dee9035b4aba6d81761a010944d8bc96679a812867312129fc418698487ba09bfe680bb002453bbef00fb05cb50134e0db7918dca367100aeea96655720ebaba10a03ab329a23cf9227874f3f68f4ff6aba63a1e31bf1048679a2ee2d3456d9682bd89129046a3bccda5e9b7e043c4b6e83a6dcf72fe40457fe3fef8d0acee37066ff15eeb9ca6f72fa59dcedd28085f02783709c00b619ac5cd22b0d57011c94a0878f8bb99e32889ee72cae1c797d2d4a885b32d1ce09b4c591d73bbbb7d4eaf5f2de94eaaa39d8ae46abd25c998d826cd3c2b24be42ae4a7c5ca9328b5da8d991067b46dd82b083afe37b7224d60d9c36c74db94ac15662c27062eb5ba2cb387020d7cd53d674b22fc4c48f1577cb2449b81886ba12eab4237ebdce8ccd34826707beddc50db68501788cedb56a75808aa6c7d4aa406a8374eb417615dc633ffc336066aa7437b69436610335e33beefabb58b09e3235ebfbc7043637c7e9c473e3297abfb2ab388fc82c067d9291e973fa7b641530370b330aa26dfecf195301ece3360465b33ad7c72e2906eae61a109da3b01a12b370cadd8bc59bca75c47f9dfb74bc9e505f82a5a421bc28a3878487f40eb18237cb2c22e928498f304584a9aaa187372271de84eeff56f4941103ca0aaaef40b3b0a7a5967383152a13470687b76ed9bf10b3c7bf3070588acc254d0c076b61d7c5d09d43f049275e66ed27775e66a695dabc5ec9a81efa1cfca62413e7c2715246a49e59a1975a1e8c5f581c16953b3238e7100df6d281fbdd12471022d211e9aa0a04c8c5e70bd1f826f3e21f03aec6849a2bd4278dd034fcab56000f1522b39c1bb9086f00b8c3ca230210495fa2eec66b9e4f1605d6dc58ca2464454e404b80261081908b90d9356638dd7b9240375955d9408ad152408cb84c9b3a4f803d4112f330f636ba8078fe23dbdf44f578540434812e91782f9c476a732cc501d8e7f8a273d121de7c3aa317a277c651fd752cf71d02e2fca19761aa849e2ee2d0aac369adbafb47aa9c60d463225df053213140ae24ab4616518ba9cbabcbe2826a8c47881114d6fc61bd001c4f9eae70bbbabcd40b7f46bf03e9247316e981e48219d24777d9e0dd124bf616f6934f8f03ec89abc05987b272f245882d0eb2da402dac09a7b9efa1ce83b590025507e87eb8a4530c77b478ce8b57332df3621a3363ff40d176d60230a289da7fc40d10b6f39be7dab90796d50bf1cd522021b7c8dad848ad2d32698805a7aaa0b7da3a07ce883c27a90f052b3f5c923c0b21051870d5512241f7bf97c74b83b88c648b7a93c2e18c0553ab6054b7d6652060af7808738a79ce157b6cf189d872c3985c4c25402b164ac64cfcec5e751adb3272894740a4a28c7f5c50e676720a3bb3330c596d1b51b40973744fab0f4066a2ef475f092e495adc50e181438b163624430e3289fa7e53bd79e8aedfd1a52141a59a4c51992a031afad71f74321b61e02102daf44c12787fb487e28f020045c2554b70eafaef11bd3b4473da7fa1171d61a148611b91e857db371a6021e02e5082465d45da6c5799563395c7cccc8dc061dc80d09f2a3834dc88ef7e61b45452aa2073ef7f495b56e50e1e7313a17ed454432a9ce4cae176b67b553badf02372fccd7a69af10c16f409533a7e7a7538d1e0604e93e978dbfbebecdfa78d812e11b390a2a02210f434d15b4a58cf4ef045d66d8c411af62d8578f68208aa70b827f8a69a1b792983f900cc2533a01089fd28ea6b83679cbff1fa567930b411b129c86a45349ea27d2850596c0bd0b9153caa96182ae15c2ec6985782b68cc0f12f2d147d2245c42323ec127108569230a4a6a796cc78f730d86bae5ba49997f111467f3da1fc7da088cf349a40e0d69d5d65df21492d82259acd9ca6f97079f7094cf842aa652186162248fc9f05e452c75f78f79f34b0ceda9d1b5bffbae06b08ace101deb3f05e5fbe700a98c259e1527e01be26cbb7aa3f2e7302489f67210225b03b9a82a5ff486478d3e248d9b0ef0c12e8c2a4a94df156b02e7175dcba0fdd5a9c960a8e915edb6bdd2596529c88f4a10ec7be746be2c056b7d9030aa31050256ea76a82ab8c18d53ba8848d8dbdf070cbab935ae371fc200aa8f858762f072ea8b58db1ee4ba00bf879153fdc81ab8fc745472a1ce17139221ab8ba3f24fae60f84f8815319eaeee9edc8dd43285aeaaca0dfa81d95923810e891d50e1f05570e981b9dbe1758bce636d067ed5d29c5c56c133e83e1545014bea6c55612c41bc021267dcc97203ebbae4be62e5f4f05c579ac4e0b550520668fb26a3e21bca88d9323106c35aabedffb98e83679d39c15bc618ca10e2b7c593b2b6e940bb54d775929f73d8e1d674564291b82a8292adef3495560185db0fb6ce8d479203547fe0a5d369e6253126731a156f003a388674cf6f1f1ffd04416edd62df101bf6fd3ac11e48a7bdee8c49d2775abcd563f4259e2bf92002ee822b6436a2e2c95cfbeb3a90669e505da14754dcff65e62d41f84657e33f15e8c3bf939faec2170671f1e6291e9c234edca69495daea06624af464327803b6369a6c536dd9e1faa338562348d3b8183999edfef72f3cc469dc65912ec86b31587856cddd7a60703129f723525803622560a1ca5491c1cab508b55b80caa329d932834aed32324943bd0827b144b4480c7403b30850fae68fd05be4bcfb4b2ce08d74afd147b2b5eb2b56bcd1fa9ad1657d3a6f3f5d0ad5a2a88d9ea287fde5b14f393355c7c218d23792a7020955fca0672dfd551994178df882d67d9b8833cc2763f390c572b2c2bcbcf6f73a56e126464cf60fe45c6b9b04474f05aee1b9e1573e12bad042deb273bacc444a207e11e8e4c047699014d99cc8c45be5db22815e9982bfe391d1968cfc83a1156a5f9211ba8e93d584d0e4a1de08fa3680546163b245bc8d20fb9ac25bcee5fc0f1b48589051ecb1856fd73f9979b1fbabf4dfb4858952d8d11114326a0fdf9729f2b4a305f5c5da2fd96789a25334ce9b29267314198d95e1569ece283d7b30452e9548c23b31c04019fbd1a7ec52097248c683ddaa69f800145cc51b9a45465d0d480a6914e57fc276596e67fa7a986507ffa4275e6c4d50970302cd091a4a8be2125afdb79384433025caefacfa08235f3f8863cd727d920d0aabc78030e70badd682205e4460eb96e24a8773c81fccd810548c7e2ea99292c5096aee3e1c3c96f0105b5e953e61fd2a139c311e53958af1e82411de02b18196bbb223f4f1f3c526ed3bda944ce929e99b8bddb999bd4d4a055a647b35a124bfe368aff68530d057103fc14b6343c9f6574971ebe03ba3a60c6cbc115c41095420da866b399218277a6a497dffd4f565ae24a2e961dada56b3fa30e4de600d30b82e9bce89cf1b8a67b9f9df4e19e98a203ad8ee0603c9b4d04ef96fea02ec5a3e0869195ac1fecf1aa7456f12a00fe30de4ca88255a5798292f8fd1ed12bd16d8770a1e938acd64621d25b319a09778ea95d5d62fa1087366893b689bc0a48b705c9c8e3c656a8cbad9b13ee4c32906f11e2e985127f5e6ee9298f8a5e1559fa1080bb2251b3433df3b369ff51198d29becad63a2662348404cae1dcf325e207fdeada5171927e9fb74abbb31fbf6f71b6ef4db87176bcf88895653a8528dbde3a3b7081f6e02199d067917d6d80c5cdfece94d3f8c8b39aaaa23e6c371173c2843e76b27011348dc6d9b1387a5ed4ddd05234fd7634c4d29c7a1aaf0c0892efbb8d90bdcb2a75ddd1610c1fb997136b361a72fa06e7dd10e0ff9deea60cf890ef3654011ec6bc245ea07272f1c76cf7da601bd9468ae7221b4c880ad5292921ae1e99b829ea974691ecab3aefc1320aebd275709b159a724c601749c52e1ccf6cfda239095cad645145801c9b4f9c2f9bf3dc5098602ba08f4c17add030395a4d37d68664d28214cb83addb4a361a0979108a8c12cf4f1024985554fb2dc77d514c86fdbdcfc0e136d2a050cd8ae5b7cb34e25f64080b100c7e75fa3c052900b6cf63b8be429867a37d8e13db462bd9a96a713bec5e8ad3c35722375b0db5b4daf2f9fb4f63cd4e8684b42582dc4df2b398e3ec51fc454c7647e4cdfe0061699e4d745a79b019b3b890652b297394d4783f44993c466ab44102f450450758052669d8a9b1b0e6e8185906a9168a75babaa95e15deaebf931c5361f21c180370c3effb062108883082b200a9eea74b5208949535ea97f57ed7fd69ab26167ab4df02686727474d80602348bfe16485e5d4999feb423380a52af2f101ea01e756031c45652577ab522390a7e364d6bf0868b58d4b5ab8b4507daa22b7c0068b7ca0af27f9610f9be95b1e8cfaf17225d5cdf6f7d4c5eead3942e9bf83ee", - "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000097e089d738cbdfe4aabdacf499858d5d00000000000000000000000000000000bea27e9a0462c1bbcfe5d7d11e69ab7c000000000000000000000000000000005fe27b65c562e50b0f036ea754579e4b000000000000000000000000000000004d71b2b07473783912b25cf8dd9b9c9f0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000210ade7d9aa4cfe74bb36dd9a0e12531b1126fa2403608e2b7d175414fcb9e2f31dd5a66f5ca90ea104b52c48f4a3e630f174014acc8270d5f4dc613a06eb6a3619654bcbcf5e533790d9be255bc5ca90c779d6375fc717d27349065da5753954032f128b9e186d3fd9cd5460214fd5cc67db90c397056d90b3fa1e1e93174c99000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "proof_hex": "0x0000000000000000000000000000000000000000000000032f917b0fd3ba7a530000000000000000000000000000000000000000000000035e7eee9919cfc781000000000000000000000000000000000000000000000004d01f8760c8703bfd00000000000000000000000000000000000000000000000000004d94ca153b600000000000000000000000000000000000000000000000061836908fc3b8f2a500000000000000000000000000000000000000000000000f58c698fe27f1c7ab00000000000000000000000000000000000000000000000c83238a843749bc86000000000000000000000000000000000000000000000000000212d3d108ebd200000000000000000000000000000000000000000000000ef8085780c77757ba00000000000000000000000000000000000000000000000c3c61f9d2347a2f550000000000000000000000000000000000000000000000019c6e6ab16a366da50000000000000000000000000000000000000000000000000000d7fc69b4d7cb000000000000000000000000000000000000000000000007eab1b3dcf475109c00000000000000000000000000000000000000000000000f3b81a7652ce16d66000000000000000000000000000000000000000000000000b7fbd961c0c8033300000000000000000000000000000000000000000000000000005047797e138f27e2b49d2890a1a1d7d9e9f9d5f8de1c723e2432ee10ddddd854082841a60a190d1e262fcb062cd02b7fd2f59f3a9a5270c713891c8e81a49fe088806914debc146279040a63dd82eb4ce9221aebb89787e802ddaa082e654c975d695db28095217de830d6428843cc068ed10d043596da999068b91711995406145a857879f61aac072ef64f542798bdbbbec186c9ddea949792d717af3f861c541f6d3329c8139a72a4c39e91ed9cc57640eda4f794c250d137a8490b015a87034b26243a7e2ec7f12931d3c8474fc12656898b4e3bf422912bdd4db5374ee12c8f096d74f824c025e27442c76ed1b51d39e2cf7034a4479893de172eb8b7294dc4e8d271a3231e7500f202e19d8877a126052f950431368cef6f95f062ced311b8ff6ea4a4149a4952e3d78ce456f6fe14a68b1e90adddacbbf08765d209dc70609ca6400a22b52ded226eb2c9968f70cc9e8d3ae84650a167b9c9f15c26049d55e1f4c1fa028ebcd480f734412ce5f3a2d710a6e77762d349254e59ea37ecb81347b5626e298a12385b87048dc8debad8f5b2908e0723855959723a666f21eca85d3bc8b00cd22a77a7e4e84a2b36db98f02f0eb833246fd103ab30983c6efd381068b8d71f3fbf5f01e7009b84cf9eb866f583ad0c6e4c1f1b9f457acbec88e87f5ad7642c0a219b76dbcfcdc79d797d9e36eb98bc85294d4e80f324c41aeb5d5c7e7a0024cb722fa8c2f51ebde20d08f7808d710737ca258f5d5a92b3502d21cf54b5a00f101276cd0fa6746fd15fb69b4c0e9c468793c3d9de7683305d1ac0139b3ab0101732e6eb2a8c4a782d8a4de7eec90b02a5c2d018de75c066c2494e6f51c6df134d8f766efbcf3ed54ecb62a51e4ceec128d2059759359397b487769861435d07dd738c9bfd93cdafc20a2bbfbff80b293523f1504d9eb4772de3a8799748ef0bcacec57d8ae3fc978ab8ffd64c15a20b4773db561a5a6bd51fb91ad9226911231fc9128b34c554eaf02080253b584e58ebd1cc6e6c976bd0ef8f993282680c187b610790b86b8eb17f5f46cc044b3bd1ff9adb80ca51ede5b36f46a9f62f1b1a89849470515f82eae676e8f251c869872d45d6aed4f38f7d2d0858bf1a4d93058186322e7ee8b79de71f366c9855390b46d2e6c5a6e3cf63fde1e851e03fb10b5b2399701861f4fd31c8bfd664c4c928f3413f55049a1d90c671e9a1614ee127e412345224047f85d7049836cfc6c9a331c14c1c0857dd0199a233c2d6392e1bc381eb283dd577441c23d64f5878e6d627ce803cca051052a1c74c8b66aa69162662c26b7c6664b363e0727e1e9844ce3d2662ab8fb678d1b192fef266bb0b1dfcc5caee4ca0fd5c615ed966245a26131a576c846c2475ba08597e43b5902e103e051dec1ac8f79d07c157ce88a7b2411788658e0df6dd5c23266a513e8b7a0db93f7d5689d0ca3b5c090b9258bd3a8cd939ceac84c1c2f61915d50904a9de29d376f9dd4674ed7e648efe0ce4c0e5634d8d90b6d1e569955fd105ff2751070c70d8bfc9e75ff4894afd01cc06dabca071edf803c9e8e1ce9637e0825ff5fb0305b5ca6feb8d9c1b0fe37be80ac5be9cdeef33956bdeee9d489a5e18f31b83265c9780c4ac8f0c6460997b3e829684c20823762e4850c2156c80ad47db73440f3887deb40f6d3eb415e4cf5a468ad78053028f2d41fa55af530a305d496a1902183d1853eaaa7e4d7470a5520f2142865d8575bb4d1116da36cad00fce14e000315b8a500a1a46059103ee9b2aa0d9a3a9deaaf941369b4b9d8b08ea36cd12179d921c8ffa4d2f47b68b438df65c265dcc076c2777f8611d75cbd6b1aca59119d3221631736761f87dc3fad1d9f71a4ea8ecfb742b1376c06cec1d524858892e1429670e288a4b876c12b4079cebe718f43fc9acf25e76662faba622d990ff214913406b10cd7b24a94127550adeded67a6d29e5600363f247650fa3bbf1650d9dc9af7da683071fd81e8950edec9bebdabe1f7cfe0195e098339f5bdf2a021d02d26abe670315342dd239fb6bf77024da51b7fe27526e111afa16b312bc0f009f4f13105af83dd8e15a51a81d2ead3d76f67962073d80ad460517b6444342298f836107bd20a98b029f5cdaadcd3918c2d9f1d2596d121dde8456565ec01b1db9eb5e4e16f246568c72c64a8ff78927b7ba1d22a89dc0415f084bf1a5c5e307d2fefe8c7c73dc9ca90b4fd975943518f3f9c1dfe083278ba5064e5ffb805d2bf413130a56e5a4a3eab4bad0dc4a5fdd4611ece922af711f0b99815012b2862d53fba4d59d04810bfda4945dd3c93229b1a143e5db3749c6fa8eb30ca3c6a313d74b0604a7f3fd97373f21d8235ce46c550cfa3c02f082ea381467461261022f035b91ad4e1fa0a244b68d9f81e6c2883473f7317cbc990ab7bb71f52630930b4f7231da195bd1bd644b5b2fe16173e5738fc7b368ba6f1014c055cafeefa21e4f186454ff08d1b64548b75dc5c7febb1c27ec3fc5bb59f5efdc25633386cd2fbd6acc0ce26ea7c11e8f2ff5c03cc27e6dde633edb6703664d9b25ede6297308b872b62066969fe13dffad85fb79b12a7f2ee224c2fd4e4cce55b45e4170c7125ed83804f3316f5c17470b160dde071c81d0e9d5e50f766fdf519bf945bd5921b8d4a8af0f1ee513b5d173b3b1ead3c348bd0038ed7b159be86de0109eb8082ad018b9f99c8d7eff3c28494bed4179c43636eb858bbb17987308b52bece0c10589dd01c8d6c6bce012ec221617cb673e673b8052e7e2254e9e08d84190c6c6258ee080fc0fbf163d24a91a2fc4208add9b98bef160bce94b7f6ea671407c150a42dad24823acbe16ab2537442d072a3f6c339581fd33a1749608fcba9193cd0339b24b250972378b10b92cc76c073072924728ee1f9c112abb15ad1e00396d060b30b0d3b8f3b09d8be157157e00d9bb6de1e8c4e899b78212151aaab332b504383516b0755074c07c61d550b5a354fd1204decf0b6d123acb7442f4925d18041a45eb9aec1f8a6edd6969bb0eaf06b2857963547d0ffd277173ee6a2ea831182263aa5773b19ea5cf9b871bc36a39ae544d732858f70057aa6ad36967f4613041fd1eca6bc20777d0a2e58598b67dc69eebb72d472c989d7604004de653ed0cd21ea34fd34c069dd87215a779a6a01d40d7b7333b8be940d34e3889bf96dc07149af5cbeb8494c5a7cceecdfa9ab4b9a7dc5101745b0876706a9f0fb1d05f16ebca6656b0a546606866f3493164c7c7d2617947d68e2c21c89df9e02b5e821c16f98ffb550e9eb98a1a926a7955b91366fa057df7a701e6b22becba0d5ee20388cdaeeeb6ce41b68cfe8b3d1c0d18948490c8f65bd028e3f8ac92f43f99001a8585ea21888777e6f4b0c393b95f64228971149dcd8ed62ac2245ec2453ec809a4c281ede4c0f8fead07d9c33e8fad95f36e6d71aadc7c2fcd88fcedf2c2780816bccb4df8d7a8a6b0a323a72954c8f469031663d7d150619ef3fe21ceb5de2793216c0e79a32438808983c1cceec67fc5b86965315828795a44245f82de0a1cccb11d340ed2183ead2c424b3fd032fdbdaf9e93b314d7de104100b508ef8b07f682297ad47f5a43693b375e85d181090fa4cbba644ab99bdb3aeee7cbe0a123b1680007468d2376fa4b087198a880b7d943122c64e2739285cb197ad6d87c0f8410a1295bff339df55e97c9e2869a3ad39ebee71f0442026725e13c7894701294e42521fbff09cc72bca14c6ee12055e93eb6a36c3dead6bae7ff69e214e5157a8f7b3ee1cc9a630892352325cdfe7f4673bf9b250f74b0d53a9ec62275ed08fa47c06229ee7065a4200e5d2de129180e4a3e2d896d322166a0dd71bc8ab00cae7d08c8e4ce746faa6ef6b7cedb1987db5a46bb1a78d01235dccf1967f4ce133d4a0e336c78fde09b78763813bfe420d501fa1bb77fd59dfb7e9a5df034a30286ebeffc596cc19e89ccedfa81795a7aebbcc9aba21dffc3e0245246f1099d1aaaa6598a814cd0d504a677008cb789c2eaf178e159f5c20aafb301b4f0e8df2479de0f3717d4e4ef7dc83d738610d2f9bcd50d73dbb619b8074f392837dae12bb62b06a460bc9beae70d089fc01a43d5b6c01d6ca2e3037adaf61eb04dc2ae27c47045ac7caf828a562ae12da800e7732b3bc8c550cf584f515f680fbb2b2f28fe7a9e126ac1e7262fc0c4c15a8524ffec6e26abdb450e445cb62a54df6120269fefb17a52977bc955fed6ffa537a1b1d8194c864fcf06ec5d6b129a2e319227a8fadd3a40dfa0d6819498951b4867672fc74428d26c7d490f3a2718ff46a029357e4d83809324bad732e822805a0136e3765feba528bceb2317fa20879da32961662f7a785dce16e500991e0b9c32f5e1a9b80300876499c96b3d3369232e22522f6faa2ef3d05f5fd66d54f0ff085ffff1777b5eedc80bd244a8247be09d299994111e6aa8d0b60c75a68fa4aec522abeaa11c977b175e7c7ccf154c0bcc19ac59eb945f924d1936e318d57d6418989e411ca5870b79984a5a54e32c1d18128c3ae13bf6ae39462c274431cfafdf4b5901872c1e7277a5f9e9833618290e0e06311671aa5e3416015247a0e2bac183c27dc687571b0b581dd3f6adb8962415c7097dc3d0f19f6ee891547d6a619bb3e3f1cf9bbaf99060d8556daef9b16b05416869515e72d011820ff51de020a7c702c7a7942be41bd5efd5e3e96dc3181c682616910eb09cedaee661f46ceb5918d74d23a760d7555a14bd4d012e90d713fb7320d715910b14bbe9439e621e34a1496e8b60e628c9dd5b7bc1115588c107eebb6e62f46011149032423e6ba742d8f8c8a0cf39605e7539f0f809646a3b25db17eaf635e9d1217fd85dfede27881235abe9479fb8ff0bd5be4af87059ae0b42476793bd6e018178fe9a74b84718d5bbbca46087842120e036b0bd3c578f1e76504ad8ef04a719ed739a9583fc3a4b9563d1904c92849a4be6c57f7d596729fd36cbe2dc3855351d29dc4a90ed15ff56fd6fea033728b792ab1183f256f4304280a6041459cf3e6f67b86373d6e4bec24c6484c623721f39814f7ab9b41b0ce2a10a6bdbc16d0f6603a4b0c15b492dd147edbbb3cd16b9d461c2556cd4302dff6cd7ba49ab4c5f3e468b5569adbe825f835d9290467ca676e8e2ea39f1dc294d245771466cdc3546c0624a2d325be31fd9b5d6cdfee83414c334812883b50b6e68e3c8623d0fe6aa870ef8cc6015754b26cf8e215aca15de566a1cf0e9ac0f017fc5385f6873161c7cdaa3b77538dbb5ae5b74f28dfc76d6e0076523c91312b14d00e6c72ab2a16d0c46f6b5739a3b177cea1aac83de18861d4b1bafe05a11f1cd72972a8db708107cfeb0af3487cdf6528735cd20472c1d59d4d8f1ff4209165bd6a83a3819b94428cfbbfb80252a5891c75da8dd740dd53b8badf933662994154da3d0032bdcebaef3cfa3733ffa311dd21b7f7f2e207797deb1a884a1205c698d5ae5b8290c9471ceed6e6c079e0b4f85e98da71f0456a72fca9bd9d628d04e9af4a48f36345b40e585e0aa98d56c46e59612d8e54c397a06850c45c3051be842965eb9f23840f18ee68e27147a5efedbb04efe0937418da83cc0567a079b805d9b638d171a7c59843997ff23b71ea76ea6d6800eaff14d3f79b4165a22c6451ad1775fd4d26d722bf23f89fee41e312ea67679b1fb12ce5369b497262a1f271bcda2d8b84b17c57de10e2721dc36bac0cbd65b5f9376644d05d110561a00dc9f73a118f8b7bc5ae3c6536bae7ae50f220221c018eb59ac638ea67d7313fe05a2c460ec78ec1fca5b0daf64d4c4bb9a72cbf6be833a3b0b2668bb512c23aa5a8cb69c355e5e0e8d5d0f56bb3868029a33963f3bd54a22cddfecb7953d149acfcdf891b6b5515802e2b341d5b058e0e24d56549defc46bf686bc6fe41e1293f7dea651f9c7024bdebfd07b25b7fe9d1433c0c93188c4d56635d75a808a0e8896aab641b65ecad603341135b0b2f3a3b442e05e7a63befedb318467b2ca253f5bd3a72ac1fe96d7a8399e8e5f5baaaa2daf8798e7652e9e11f8f0f524a8161953d5721896c1806a2e245581dd941fd36674ac0beb499d3531155ff4fe0d20f461de9d964337cf3d6dfa698cbd8d731c91741b16f0a7b018a8f3f85a2d842d1caa900206db1de437e9925ee8ea5a0b63cd2d7fb16f358decba50a96160b52b37ef68a5ef127e7f7226d854dd9a6834d2346ce42b3214bf811823183f3bce29a0742bc573a50a950f17d924fa0152192d75027aea786510faa92fa84aa6d722a2230b297f3225a520b30a9c719a1ed90f1c41e0b857c79671d1c8e86d639517505a2d38d3d6ccfdb9cf0be4243edcf0bd9d9919ff3c1e1423587b86902b6b1b76e4c6801996135d3a5b12325a996971feb683407d29c778a0503df7ddca671ea0fb59d11d0cc0307fa4de218be33e88dec7f09231ad19bbef47a9968884db2b9269ac913dcedd940b1c3c556243184680339d304710414288abdc275f5d331dc0edf3ab16f486919ed31e9edb034ea7548d0093cbc255136f2bda7da0439f1392cc549dfe75586cdb78594cef6290c938aa07916c0312b51733f6f03b1c7d1068ba9fb6d003144f42d11f81618c601f6dbd903082b3aa57ad3ae70e32095f171b7135ac8b3add2620cf85c589fb513c4f0d0778ac8b895180ab9088eb270a2ddb28186c6a7715a004da3c73bba9b0301d0627a70229eb9322cd1bc705f54a1f7a778414f4b7510dddfa983a039e1f35e44611da8d5e362f94a8c5b1eb74360ae4f7a7fa0af058f75ee1fdf6844c43e374bdae0a0326d2996c735914cb999504b98ae3afeeca586dc66712fb5cacdedfc84b5fc2cd440e0e98a9b43807a67128bd8c4f473fcbc4b3515924e638d31db8368b06a1ac274ff1d88cd782337c8d13c3e4a706650ee60fda16e68ad2f012a56639ff3bee948229a4ed8d9c386e222223e4f32c02efd03009b0fbf87f63d798094ddb110f9471180732ed2a461cdc2647fd700c40446c1c60e2ad89da7a5df1917822b47b358092a2bb74628d0b251d52d41534aa1ad6e94ebb146fd01ccb98bf7185bfd8b03cdebc5a337cf813450cae2b75fe2cf53bea9b36071ff4b9fa31e1f24038fc7608ea85c6c3b82a84472fc0fcf682228465a07c7d32e8472ec21e0753539adf4885e88b1bdc3350138118c811a01ad8b224bf573095db46b4647dd23ac9030691f2930b097d8ec5dd100760d78d282354c618343787d24bdec98d94bcaf21ccd2983f1bcd16552c2a50253f8802ddc74ea576d7394758ac7217b42c46c076d68bfd316bef99b75e06a416efaa9597b1f085ac6f74cc6334f4708200c4cf3591d47f0f2349d4fea8e2e406987be467dcbe38ddc69127225d20957a15c981020fd96407f2768b2f03688b1c913d9f79fbd9f2886304da7654a180fed16df5011cf9667271813f73a4688b027f9e524698c2cbaa6a88f6e3e76a6c148bc06930fbcccb6782a2a4791242600950c371942d8bd2dc889606dd9515fdd31e146aa7c8ca5eb676717c58ef26112c127d36931d54ecbf4bef7a2f12aea92d47f98cc0dc4d281ede2170413a7898293f5eae5485ee18bac0fa0adf41e3dbafdefb9d9baea98cb05ecc6b633fbcf9282bb4dffe6f83c61655df8b489fb4c01db5f7e2690b255adf3c6e885599084b07c2514a723274817c1f43a9eea8d89e5770c75dba6e113b6eb2938e772ae5011007ac68d590074f3dcd0dcd7d66607dc6105f65dc98c974e07e388029e132231ba3ca3c3929ef1200454504e844c1967fd6c5fea75f01ef3bc5d64b2b8c1f2217bf3df18b7f0e5c4b29ff22f236f48e9bc20443cc75495e3011b66033d753970e28c4adae4607318ab0569c6ddfcbfbea5ee2322832b980bfef0a1db53fb02a2b0eb14c6176a62015852a72640d1bf6f6c542f7ee40ecdefa5d3acb97cddb170f1db88477068182e6be7206269247888df636da9b456f70590c09149bcbf46a19a9d3bc40996abe93b1d5f3dcb11b526ea1d2e959d5bd5437fa4cf91969adae1b0a097d4b17e7b98449f2a90cf905e3eeaa21426ef43224e1adfa70397b968b086613a03251962c98a0ee883329f02c7e859472dde1b90b17c0ff876213a2b02a8cc443ffea3b98cbdf501f3e3e065a2c5d024e7deac62f86af4be112e0c2e41977a2a34885d25ab9a930ceac1a8be6976d64d16d8f7ba2b18440fd9e3049320e24155f1964f8562c19ffd4e30137d0df78c914369c6cfa7fb3a34500ce9169074953563f9312b4c3fe4415159d65210cd379a5bfc6fd2af934b41367886cb30988aceb17be1331db76c60f96c2844989fb22047a619fca5d9434d25d70a1670d197f70c2c89684a98d3381a81123cfa247f4a35bd976852cd73d43a4d02e5a18af2db1a2374dee122147b825440736b4ba20e8d3d680dc8650ee5a9a8a9a301c2b17a1147e43fb585c32e2cda06ce3d54af93d022a4635cf25a4fb78249f0b25bc8ba2e8fb929885b9a19cb9fbd12a676313fd3edf4066b01a779190f4e648118ad0da745bd19017cc131305257f322f323b1f92aa8155829695dc9afe423a0c988765a8719d6f25df1571bd2543f6ba16b19311483a74c784b90b27ddb3b22d6064e4447182baf8dc307320f3029b20cbb8c8896c54226e0e85d4fd70067b0d854dfd5d25f82aeee8aef6e967b52e77caf4e2d93623c85cf63996d182bf5404d4a6ad89410e41775d0876a535c834f85ade195d0b00b462293316a9df7ee12dfc932fa7fc97f276ee49631067d06ccb97b2a260417a009b500958558bbbca05fb66776dc7d15293db5eb8d19df4f3373a6a17a6c3106652fe96751eaf492509f36c9658c35b2ccdad5886ee631cd2e58412a5e503fccdf4bb71771c0947f70db6388d35cb0038e98fe8b78edf81b51a6bacfcb40b93f8636cf07adc589f0f147a7446ff1d2022274ce3b89baf6df657de69aa0cd1c957d8c9f9de2f15ec2e0f7ff502368270a30276308c2f09d0f35de5d0c784c8c45c9482a1f789d021e325c3c8a18dae526ca06a6e6558c6c41fc8af0bdb17fc360cf744c4cd891805a92fe989e097d5ad743ddf07094129c0d1e503511d4f81190723f7956335c2d9110d24f22584b4c727560b83aabdcf961b690ba845788039718a4506dcd048e8dc2490ff6a88b9671d9398eebc8319797bda55d642bcba47f139a231d650101aad27b12f3c069358e6b82333bcac1dded6c23d8900930f2c5fc7be3edf64874de1141fcd391a2b917da0165ab0fef51d6730ae7cd9b9b1f3d0b55fcc72eb3e17b62debe56fe2e10127f3b046cfe373456b3360509b8328fc04d54606829576c5250462738984185b20a0b7f88023f3e7777c7ea62d1a41d364c533bfb2d12fa1cd0db92d5464ba8a38133367f515e4de7d424c586306d9ce22987b7247386b01022757f4648500f17e96149cf652c6c6a28fe9f85e045be8d9d66f92ff74229299049344cc223c6f1bd7d67761c9b93ea2d8c912d34ce9af9be5aae395f497c90a0af3b013a82b622b4942d4c5e76acb383740009874450f496f32cd7517be45ca289cf4b127c67cf0155168cdbad6fdad969ed7f1c8162ba8f5f89e3886b812f91e21f02ca64205417c15bdd1379eeb814083a3c32dc715c0747dbcef6dbdd7531d4deccac77bf29d1628280a89c4848c94eaddc3b36312fe2505b37a6d75fe81045025949fbc93a3326af3fd369d39fa6c009ca3471f1113847a3919b116bdb9077a09781a3a637599df7fcc98839e11c07e695d311bc51e6b8d64b55d2f170400e634e4979be229ad38ea5e2f128d1572a85cce10f271c414c04a306c6b92002a00e00825eb99906a26d1945eda3910b84502cd3482d0d84f5847932dcc4faf0bfb0c9f3bbbefce5991057908c42d2d5920d1757da51a12d9bd5d99790f76652c4307b7d0f927786d9e6cb6c57ebb44fc5d2b04c3359d3f4e3735a45861a3ca2859d4f4306d1843f79a332294a638cb1f76622e57d50558c1f22abd370503c903caa3f08dd93e5f82833de8e6d46a3341e7a8913f2a7e22e6643bc7c6538c8e0cbbf6fbf36164fe1b6f1145dcee45960273b2891250ed461e1ae1f23b19863c0ffe0810499d5b5be47ab8bc81ed7a2e004439eb823da19d539f8e7ac1659a92096441c33583ac9c5603ccb0d44c51fed6308f069da81382b1a1d74262f89cf328243fb2580e1a1abbbe2bed12ac80e361ca6a4123461a6d8efc5eb8672dddd22320ac7c5a087b21dd48e32e8ebdb4da050b93dd294e91d28a238b59d41d6265221ceddff0fc2a28de353b6c14fc5163ef26aaf67bc153eade50130c49c682e91851b297fb64d9d792b9c9c44a8a8bd2311db7cfad7090e8d1badfa6ac6a58a207f955c456cea50f9ebc0d7f95b4bd3347b211234a55c5c4bf20a183ac9b683719f208fc6b8cc67ecc372b325a4901678b2fb9288b4ff6601097abdc14df17010ca0147edd325f460457fb6ecccae55494c61cc30f5c29cf57a424147feb0b26195c0e3e739d3b3669af537c778a151926b774187ef6000f4d7349c6d5a248352efaab21ace4fcb78b5226827b068bcdda804f14b7fd86bdafd02c95fb60def714b6962ebdb37972973f9cac5db0d6bb9793fa68f19129a098bf9919df1f9f382df39520119d0fa7c8b262361a51fef9e5c0418b4af5c082b50dd95af82039f6049c751ab056b6ca7b13a1c1fbe61d36341c4df78ef722bc37a0635e42af44201d7951639b2fc9037432aff590c41fecc465cf82a10c7385f05e4ec18243106408c4fa61fa0ee08ccae97a0f104cc9c331fd87b786a8aaf813c05d187b3e30dc240b88f66c0b8d5c82efb9952183e37131290dac7ccd34bdf015214f933e275e03583c09916c1c6ca5a79acd3042fc82c1880dafdd9c00e1ff3ad410d8547c400d58dd99c637a8087117e36ea91e6812c6742e2d7250bf9ffedc435e6f79c9ee00de2aae6f0d19c82b5c99cdeac09f23d4e9e1dc20c1aa7c40a19b175c04ed182bf3b47f5dcdea54be39082d106621c59df843109a6883e4ca3949acc4e9754f103077d98bc264134bbbaf7e90d8d842a33578a7ad26a061c9ca6b77b3587dc826b783db0e3f346007f66f31f8612359a1aa251a23fb875f7d529bcf9223978716c7f5b8879fff558c3799d234346f05d7e80789d437b4cdd55c2be81353abec17abd7d2ecd9e1450ce944d03c9e6e517075a82ce5e4193844eac41f54abbef00f86aa9bd96eebbc4a7b67067fb9de593364457f94ffbdc8776b908b68b73c9c0850cc0dbd973ba25d515ee139f15fbfc0f125e1682f8f4d42b47f7c3281c2251f2eef4b2d676d4791b21a53a281ed28902f731d256e5edca72933b79053311513bb354296f2cc4c225fed68e505bf1430b1e5350b29049107ed15530da30d8a26863fadc7374c10adba56cfce0212cf3ef17d9021f63ffcd3de6b55b89f72a22c2b59e3d3a06970bb738b602390f6695fa876d376d9c0b845fe711a85e77afc2ba278b527ee921508d815f640ec09bc8d963a6aa450b1bda744f420a23e669d2df4d35f90eb8bba6771984c28fb5575cc5628cd6437a9172bf671d6197b224726dd1157e09bafb93f5e8daad3e37eac638fe47897bb1b8f476268e2f4783096133455ec390141a1bed6103851ed452c5969ef4765c5a24f4d17d1b3676e80dd2315c58cc3c2018a9e4dfa28d965895a1eb055c7fe41eabf03d3036be840abb61301d966663a812629391084a6b445fede42b562e60e0b74bd7b7f424474f87d02f3686c606b1a96da46917a8cb070f6867b4672311e248492072364ee5e70842f52ad47f0cbc0b018fb41ef8694d08f6f604f4ca40f578a7d0c561021ee8dd62b4605620eeef24fae8d03b5ab8ff013f7181b8db77f1fb03565bd5c9d896f66285ac0f3bf9b155ce499a793df6bb993d5aa821773b92854d96b59e91f212fee2c60be3b197bcf457faa4932500e94ed760070c26e49789a33186f5ffc99447f1676d9956e30b06c28f150456073c06cd17380311cdd6e542cfe862e3a00d27017b5827b442d3af40df6449ed4c04be82015ddc6ad04112ef5f062edda022e8909cedae081e8db20856c23c6baaeb42c2c5e7b0fe8abe6ec3980efb76912aa4309f135514e65c16895796e9b278a31a747ed20eb572ab82e1a49fd8ca60a98f823cf3344f17db432a8c2f9baa00be40038c98f7c11a1b2c414e67686b77720d8137f3272f6de98b68ca04b28d2396f5a2b6d894113b7f7af32aa77200688a6952583043ef8ff22e4c1e417c68648a3380691e1d9bf55db4533703448b331fc4b1e6dc67cd32bb0f26b5cc312fbc5a8eaefb7b10ae7cd03402aa9ac3825b597d62e10e39cd2a8fd4bf1517d37255560dc77db0ea2db7edfe9cc564d0fa22ced9d2d80ee077547db7160f90ee4e7fe9f1c3235acb8323abf43e2fcfc741d5f9a9819cca25bf68ec3235595d7f0d759d661253e9ef535ef4d8e4b0096e814e013921f749227303bc67bf6cefdf344692198576b1bc4356c73ccdfaabeedbf69abde2c462f80f1980015305e52b10707bad1889f5c39f736800aa51f1501d405b3732af595b49c48b4333f160b58b87ca84c910977c93aeea98a2362e4daef3ef63f08bc094cb1019eec6c1e9f2feb2bef068c5fc563a013950433c25e7e218b66051d5a44837375c1b83c9489efe3099f427c67bf0fefb25dfd8b626c48d00c7a4b1070504657a3b7ccf42af9dfa40e93afc0e3a5e2aa92e250f2145ea915abdb6a0b78fd055839c44b13e2fd7782d67e7a0ff4e1181b4bb64124543f5438702ee42d8d8dec996a95e84c8c9f1419c5bc66b34aef3700a67786714b6aad4147643c172c4a70c0e363781f8956e374b01f88f397750c374cd7d163919d877889bd5629aa9a70dac88464aeac5a0cd4906d60979ffc1e4626b0af9aa0a22e9d3966ac2609ada8891286e5fe76227c8b5b50a267171e1d256d6468ae45360978054ab41625cffa58eae964ada1e6369b9c8b2491d372aac40aff7443366aaf6679274f26d13c1d1fd13e2ebc731975b57be4c9eee4b6dc88445d8ffb0d6de2e69b8463129087d86aea27ccefc304326063c7972ba3e80553fac7c5c488ac4545f8ead0169bf87f01acf9353d0ed6fa6a55db96bd9e41ef8fb4f1c2628e86504987acd21b9af044c092f91ead0db66966546169c32b670bfeeba5746860f83ee005d0da01bda136cef67dd3e66a111bc90cd88056b1619d90c701fcb20a7a4ac33342950f6188bb0e7d4a788e1a24808954084e37d8377cef483a9a84490b46c95d10a82c27ec6acd7128da9cd8250a45fa24b5678e94a0eead4f51b62881505463237502442e915e71adedfb9f97115ac5d150170b2d572e067a92010f51c48168fa8005fd3192e9b838c58f31b3ecfbbb078e8639ee2f3a5dbeb8dfc5ffe1175b448c00e213d2ddcead739b4563a90f47b5fdfd45eefaf5dcec0768df8490020e69282377fb10343b5a8a221bb1fea3bf8fe84a790c1adeab68779614f29c283810200156b08e06521c126199dbb9ea2f2a6af5f5b7552e40ae1555c760930577969e22c7b04ea4e95901c650a73c988c618bead593d17d5007146ea9c47dc77d14ce0e03ee7b11ce3448fdbc534f42ef81bac3bb78c15b1b3a83d56b3f36d21b62d92510252201ab1927d4ba5dbaef0f3e1c095e8c52a019da94e3560e11a83205e4276ec3235751505050679851506af768f0cabdbd6571d0995bcad6e3f6c10f6a1e09368c3547f9ad262f12a9adf34939cea2d1154acf2aec479352ded626aaef25982e7552e667fc7e4e9e6fe330dfaa6ec83fca6b2604281666f3f99c32262905e6a7d5c87d6ccbf80260ab790e02fe7f51dc8071a5fe80eebdfa76a7c258961c401120d9f12b68c977423df5af18e93b2193e9b74fe53bbcda7468f342863e08310cbff5ea6c0ff558bb83aa2bc23e8df39b3383c6ae5f86c22845edb39b2a2953297894e3c2ad4e253dca273b043ab725f81833d327159207177c0b0ec96a2a9d9dd5834c42b493856edf49a3cbe2be99b4711f6bc83e57cd41137641847a04d4127ee7420f4b77460152b4d7aefd72c105f3b834dededbdecb89a1c4d2d22831a4928e242757e1f30360cb8c0501aa4642cf791ad9246a4a49bc712086c50cf0c0067bfc80c788d426bcfa946f8830771998880594658acedbd416087f731c2d9a1f721e273a548daa7078371b7f6196244479f11b24ebaa395631e9ef1f0ae2ef0548e857f2df929518a18b8a95717f00257f6c5f133ee95ca28b76febc122ab204fe89476d434759f23f70fb44b03b5ef93011c0c147acc417dbff7800172bee75bd52030baa9d42c0be98620037f763ea2b51bbf861b8f03a03eb2d030793cc0c782cd860d2e212b7de317c1687b3a7c3338926cce04b4a79562d77ad232eca3a2901fa6cd0fff130d3e55735b134c8022dcb25f8dd068d5d1874e3572012f7a4df16d20451fc0d48ffb0b844c34d578893abe54f5da62af0c4b597b51f8f652fb2d9440c9641bf27dda51477b9d902fe04f5be88f852c3558cb1a5fb03ae2d0635da9de9c58fed8a406dd3b2d99445a575fa3864f1d4c4351617617e1ed2bb4f656f1113aca5094ec20d755d1287fededfbec38fda5c26660a292656", + "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a00000000000000000000000000000000ae6a85768f71c83f114b20d8a933586300000000000000000000000000000000ebd03ad97202d4bf5bf80bfeb5239fba1f8e48fdae937d71edfb5a4d694a7bb5a16a0c2ed1ab32e08dd664615f32513e0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } diff --git a/packages/interfold-sdk/README.md b/packages/interfold-sdk/README.md index 280b2b83f4..6ea74a1eff 100644 --- a/packages/interfold-sdk/README.md +++ b/packages/interfold-sdk/README.md @@ -321,7 +321,7 @@ await sdk.requestE3({ }); // Publish ciphertext output -await sdk.publishCiphertextOutput(e3Id: bigint, ciphertextOutput: `0x${string}`, proof: `0x${string}`, gasLimit?: bigint); +await sdk.publishCiphertextOutput(e3Id: bigint, ciphertextOutput: `0x${string}`, ciphertextCommitment: `0x${string}`, proof: `0x${string}`, gasLimit?: bigint); // Read operations const e3Data = await sdk.getE3(e3Id: bigint); diff --git a/packages/interfold-sdk/src/contracts/contract-client.ts b/packages/interfold-sdk/src/contracts/contract-client.ts index 62737d4f13..81f87c3cfd 100644 --- a/packages/interfold-sdk/src/contracts/contract-client.ts +++ b/packages/interfold-sdk/src/contracts/contract-client.ts @@ -173,6 +173,7 @@ export class ContractClient { public async publishCiphertextOutput( e3Id: bigint, ciphertextOutput: `0x${string}`, + ciphertextCommitment: `0x${string}`, proof: `0x${string}`, gasLimit?: bigint, ): Promise { @@ -190,7 +191,7 @@ export class ContractClient { address: this.contracts.interfold, abi: Interfold__factory.abi, functionName: 'publishCiphertextOutput', - args: [e3Id, ciphertextOutput, proof], + args: [e3Id, ciphertextOutput, ciphertextCommitment, proof], account, gas: gasLimit, }) diff --git a/packages/interfold-sdk/src/contracts/types.ts b/packages/interfold-sdk/src/contracts/types.ts index 36162b15ea..aeb7c8032b 100644 --- a/packages/interfold-sdk/src/contracts/types.ts +++ b/packages/interfold-sdk/src/contracts/types.ts @@ -46,6 +46,7 @@ export interface E3 { decryptionVerifier: string committeePublicKey: string ciphertextOutput: string + ciphertextCommitment: string plaintextOutput: string } diff --git a/packages/interfold-sdk/src/events/types.ts b/packages/interfold-sdk/src/events/types.ts index b1583615f0..3b49079043 100644 --- a/packages/interfold-sdk/src/events/types.ts +++ b/packages/interfold-sdk/src/events/types.ts @@ -44,6 +44,7 @@ export interface E3RequestedData { decryptionVerifier: string committeePublicKey: string ciphertextOutput: string + ciphertextCommitment: string plaintextOutput: string } filter: string @@ -59,6 +60,7 @@ export interface E3ActivatedData { export interface CiphertextOutputPublishedData { e3Id: bigint ciphertextOutput: string + ciphertextCommitment: string } export interface PlaintextOutputPublishedData { diff --git a/packages/interfold-sdk/src/interfold-sdk.ts b/packages/interfold-sdk/src/interfold-sdk.ts index 6ade6fd766..e4c3dc2e71 100644 --- a/packages/interfold-sdk/src/interfold-sdk.ts +++ b/packages/interfold-sdk/src/interfold-sdk.ts @@ -170,10 +170,11 @@ export class InterfoldSDK { public async publishCiphertextOutput( e3Id: bigint, ciphertextOutput: `0x${string}`, + ciphertextCommitment: `0x${string}`, proof: `0x${string}`, gasLimit?: bigint, ): Promise { - return this.contractClient.publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit) + return this.contractClient.publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof, gasLimit) } public async getE3(e3Id: bigint): Promise { diff --git a/templates/default/server/index.ts b/templates/default/server/index.ts index b5c0a4554d..1281496d75 100644 --- a/templates/default/server/index.ts +++ b/templates/default/server/index.ts @@ -174,23 +174,23 @@ async function handleWebhookRequest(req: Request, res: Response) { try { console.log('📨 Webhook received:') - const { e3_id, ciphertext, proof } = req.body - if (e3_id === undefined || !ciphertext || !proof) { - console.error('Missing required fields: e3_id, ciphertext, proof') - res.status(400).json({ error: 'Missing required fields: e3_id, ciphertext, proof' }) + const { e3_id, ciphertext, ciphertext_commitment, proof } = req.body + if (e3_id === undefined || !ciphertext || !ciphertext_commitment || !proof) { + console.error('Missing required fields: e3_id, ciphertext, ciphertext_commitment, proof') + res.status(400).json({ error: 'Missing required fields: e3_id, ciphertext, ciphertext_commitment, proof' }) return } - if (!isValidHexString(ciphertext) || !isValidHexString(proof)) { - console.error('ciphertext and proof must be valid hex strings') - res.status(400).json({ error: 'ciphertext and proof must be valid hex strings' }) + if (!isValidHexString(ciphertext) || !isValidHexString(ciphertext_commitment) || !isValidHexString(proof)) { + console.error('ciphertext, ciphertext_commitment, and proof must be valid hex strings') + res.status(400).json({ error: 'ciphertext, ciphertext_commitment, and proof must be valid hex strings' }) return } console.log(`🔄 Publishing output for E3 ${e3_id}...`) const sdk = await createPrivateSDK() - await sdk.publishCiphertextOutput(BigInt(e3_id), ciphertext, proof) + await sdk.publishCiphertextOutput(BigInt(e3_id), ciphertext, ciphertext_commitment, proof) inFlight.delete(e3_id.toString()) console.log(`✅ Successfully completed E3 ${e3_id}`) From 1319788d87a174af8cf863035f000fd3a41d818f Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 00:35:32 +0200 Subject: [PATCH 02/11] fmt --- .../crisp_verify_gas.json | 74 ++++- .../integration_summary.json | 20 +- .../results_insecure_minimum/report.md | 281 +++++++++--------- 3 files changed, 229 insertions(+), 146 deletions(-) diff --git a/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json b/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json index 55c2acc233..4d942dcb40 100644 --- a/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json +++ b/circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json @@ -27,7 +27,79 @@ "total": 188436 } }, - "integration_summary": {"integration_test":"test_trbfv_actor","benchmark_config":{"mode":"insecure","bfv_preset_subdir":"insecure-512","bfv_preset":"InsecureThreshold512","lambda":2,"proof_aggregation_enabled":true,"multithread_concurrent_jobs":13,"committee_h":2,"committee_n":3,"committee_t":1,"nodes_spawned":7,"network_model":"in_process_bus","testmode_harness":true},"proof_aggregation_enabled":true,"dkg_fold_attestation_verifier":"0x7969c5eD335650692Bc04293B07F5BF2e7A673C0","multithread":{"rayon_threads":13,"max_simultaneous_rayon_tasks":13,"cores_available":14},"operation_timings":[{"name":"CalculateDecryptionKey","avg_seconds":0.004105569,"runs":3,"total_seconds":0.012316708},{"name":"CalculateDecryptionShare","avg_seconds":0.021735208,"runs":3,"total_seconds":0.065205626},{"name":"CalculateThresholdDecryption","avg_seconds":0.021883708,"runs":1,"total_seconds":0.021883708},{"name":"GenEsiSss","avg_seconds":0.006303152,"runs":3,"total_seconds":0.018909457},{"name":"GenPkShareAndSkSss","avg_seconds":0.011035416,"runs":3,"total_seconds":0.033106250},{"name":"NodeDkgFold/c2ab_fold","avg_seconds":19.281920111,"runs":3,"total_seconds":57.845760334},{"name":"NodeDkgFold/c3a_fold","avg_seconds":72.091054403,"runs":3,"total_seconds":216.273163209},{"name":"NodeDkgFold/c3ab_fold","avg_seconds":7.793962458,"runs":3,"total_seconds":23.381887375},{"name":"NodeDkgFold/c3b_fold","avg_seconds":72.635186750,"runs":3,"total_seconds":217.905560250},{"name":"NodeDkgFold/c4ab_fold","avg_seconds":8.064746388,"runs":3,"total_seconds":24.194239166},{"name":"NodeDkgFold/node_fold","avg_seconds":18.460723180,"runs":3,"total_seconds":55.382169542},{"name":"ZkDecryptedSharesAggregation","avg_seconds":1.575791792,"runs":1,"total_seconds":1.575791792},{"name":"ZkDecryptionAggregation","avg_seconds":48.474341959,"runs":1,"total_seconds":48.474341959},{"name":"ZkDkgAggregation","avg_seconds":5.560166834,"runs":1,"total_seconds":5.560166834},{"name":"ZkDkgShareDecryption","avg_seconds":0.766792666,"runs":6,"total_seconds":4.600756000},{"name":"ZkNodeDkgFold","avg_seconds":107.170507639,"runs":3,"total_seconds":321.511522917},{"name":"ZkNodesFoldStep","avg_seconds":5.213900541,"runs":2,"total_seconds":10.427801083},{"name":"ZkPkAggregation","avg_seconds":0.397447291,"runs":1,"total_seconds":0.397447291},{"name":"ZkPkBfv","avg_seconds":0.221726250,"runs":3,"total_seconds":0.665178752},{"name":"ZkPkGeneration","avg_seconds":2.248425542,"runs":3,"total_seconds":6.745276626},{"name":"ZkShareComputation","avg_seconds":2.503326757,"runs":6,"total_seconds":15.019960542},{"name":"ZkShareEncryption","avg_seconds":3.921781749,"runs":24,"total_seconds":94.122761998},{"name":"ZkThresholdShareDecryption","avg_seconds":3.427196402,"runs":3,"total_seconds":10.281589208},{"name":"ZkVerifyShareDecryptionProofs","avg_seconds":0.154358833,"runs":3,"total_seconds":0.463076501},{"name":"ZkVerifyShareProofs","avg_seconds":0.253084125,"runs":5,"total_seconds":1.265420625}],"operation_timings_total_seconds":1116.245293753,"operation_timings_metric":"tracked_job_wall","phase_timings":[{"label":"Starting trbfv actor test","seconds":0E-9,"metric":"wall_clock"},{"label":"Setup completed","seconds":0.968119167,"metric":"wall_clock"},{"label":"Committee Setup Completed","seconds":7.026030458,"metric":"wall_clock"},{"label":"Committee Finalization Complete","seconds":0.005051750,"metric":"wall_clock"},{"label":"Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)","seconds":122.805809000,"metric":"wall_clock"},{"label":"ThresholdShares -> PublicKeyAggregated","seconds":135.105291709,"metric":"wall_clock"},{"label":"E3Request -> PublicKeyAggregated","seconds":135.613361792,"metric":"wall_clock"},{"label":"Application CT Gen","seconds":0.009316167,"metric":"wall_clock"},{"label":"Running FHE Application","seconds":0.000052625,"metric":"wall_clock"},{"label":"Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)","seconds":50.063420000,"metric":"wall_clock"},{"label":"Ciphertext published -> PlaintextAggregated","seconds":53.769554292,"metric":"wall_clock"},{"label":"Entire Test","seconds":197.387759916,"metric":"wall_clock"}],"folded_artifacts":{"dkg_aggregator":{"proof_hex":"0x0000000000000000000000000000000000000000000000050171e1c76882125000000000000000000000000000000000000000000000000cfdf1f1b488062f1e00000000000000000000000000000000000000000000000f962e434261b37a730000000000000000000000000000000000000000000000000002e0e72e3a7169000000000000000000000000000000000000000000000003632118af1fd3861600000000000000000000000000000000000000000000000f3be15fa21507e979000000000000000000000000000000000000000000000006da62c16a519156a00000000000000000000000000000000000000000000000000000ae34beccc39c00000000000000000000000000000000000000000000000c2d6c29afc67b101c000000000000000000000000000000000000000000000009cb8711b402b7afca00000000000000000000000000000000000000000000000433d081100331cf9900000000000000000000000000000000000000000000000000019240d6a5f208000000000000000000000000000000000000000000000007b680e3643ee08d4d00000000000000000000000000000000000000000000000db2f02967a31b6d1800000000000000000000000000000000000000000000000d8224e1aaf3cd44a90000000000000000000000000000000000000000000000000001e3e986df6e472a988fa1b94e96b9bcc842e1ec09ad2835ec6539b20a216d94832710f34e12a11bbedba09154d4bdb6ca8a864ed19ed0dab77199001fae75d996691767ea956b04a0389bce5a23d5fd869aaf9c5e5c443b43b84c5b41d4b2a0d90188989c511a145d2197e8a1f835404ae133ba729ff0f9e5db0e78f86e967e89a28eecd299702170e094855e18faf9b08036a4ab8cc8451b9e96d4a3e4ddb294ec58068c86cb28b5a272fe283333c466d2b063e406c9b5d5898942d5c60fcbf13a28f333c0172e75ee97db99d23fccf0100b7e768b832f63913b02f762a179772a656dd7f3eb102bf5c1f9a9bd5ca2c2ee9241a4d4088f679221c0288326ed6fb9262962ed1b10bae9d0f25b5935e7684a6e3749e9cab8e2c12d53e6d1d284267887e58c05da28603176d9f1ea891e633934fa4fca7ffc9161f5a3838dd02afd160b0233cc2f1985db340cca8b06e4ce20fb357bdb4ee18bd32fd75c0c529e114987992e62c31533f35e6e095dc8e36fd57bb8046002ae0471ec3fcde36bef53e375cd0f3e4f191a2188d3e9a6fb82792a50d4ff1360640275046de2c21d4f4a3577e8f79a8519b47cd6be30649c380eb4d735707b1c664f98421938cd63d5f656c6eef8048b3001073f0fb231803649f60355fc757e41658a95c817594e1dafd8c2691d24f00bf99821e74780d315f5c5ad75d8e983e6d5085993e102017a72b2fa266960920a8e7e77a2ee6d59d798f12d92b424782833dbc7d235ec3e43373ad3e404f1cb1e08a2bd553428c3accdeb393846323c7c78adaa32f740afcc9ac4d264b3ed09297b45a3413e22cc62390354d759b264a96544e1662be66950fd42c67f2dc79c046b48d8eaf419dd29c1de1171719708091ab038efedbcab7ce18f60d73cf851144e9914268e22dbed233813cbb531e7cc338776a52b34c5b445336a93a82a3505ee10cb945134e955f56c92798fcfacec8ab4312b370d08ba9e13c6822f7b2b251218642289c021af15cc46ee027d7b415eec7ac6d8701d066c7ea7fbad0fff1f44ed8fbfd3209ca7c67443b852e7eb2153ead095fca5a334f74adb331a85071d37e4d8fef5c820bebfb6f8ef7cbbe9e595b09b923eaa754d813eecb8b431b6252e189fa9fd09540008f1a366d44aec26b5f3d6b88219b8acc0132af1175d1303948e2483093e739c7657de30ffc650be6016e8b7b644f1706af4f10794917723b79318a87138a13ddb9ee54f5a386fd236ec981a583a22c69f30ddd9d7684e2cdd842c10629c9b803f04e709db227ac8c2618b2ab90b7e272e60602fea839906c91883e1ba386f54311b5f8dc3e654a0d4ec89e0e84c28bc6de587d46fcda612aa42f202b2336dee7da1bb663559552831351bd8506a5e95299a7305b38f87141a1d53d730ea5f7e8327f36f8046b96f06be138f225d542397e91de2db853c118243d8072071c8c2b6c9b8319b2364cf2058d3ae62883cd328faed3808687d1e6bcd832417a660a93375eb3b6949753531fbcaf3e9dfda64319654db11377d0d30a54dc8104f72b9ada7db131094a3d563bda7a350f045ba02572b53152c9f0b81b3d85c069c07f10b478b5e43103026fe9054094913d3939a7dfede87684e2ccd8b577e3eef430358e620b504e70597c6fdef4fafcba52e4ecb198fdd7d7e2ded4feaa5e0f4e46f5928eb7cbef54804310bb28444bdd8db0c2aba73c31c7019870268b2c4ef8557b3adea63df71d1ab57662ef45b9340068707f834268fe72215eb567a317d10a1184f97b55c41dedcb2b3fde60bf5b36f8db7ae9a86679e033d6ab5ae65925449813af86b5ddc4e84247246cc5979716414f6543895abac01e65a1745a512cfa85259e0704601b4e96f4fa2acb1810d93f6f5f7c3c3facd28d37db2dda672619c9a74af9fc8590f1e019816aed3efd4f2431c42aa49707f2bc202af6e47cd30525b3176d9f656c8f38188e47b4010e170a5c9540e8d446907662106b2f16ebaa6d3b31f76676b63b88f6b5f201fc55b64fd485a05dc54e82ea332f1cf2a5e4a3ba0fb92db8a4e2582d696f0e3e9544f1df54d2a150928a21c64166a1eee5a7acf0ca354f1ef2c597a915abf5eb1f2f17f4444a14ab73d25291fd606842f6d46c423a3d5002ad5d1d85e8f2d5aa6facf93d277e8ada5be2d281e1d086b9900f04949511c28d3e5e5c042336a9c38d499e0d9d4a0e22a011c2c1d46ab3419b71c538300bf07222fac1ee50f30f59fd1606b7a733cb89d47c01f240b094462a58c6a48f2f22ea0c311cf71059da4b6eccec988af99298b19851a03b84a54289cd63995596220af919f2ace0b6855f018780539198fa2b546722a38ca2bcc9ef20fe97d16857bc21184cb8c26ca77dd0a48d21e63a4d2e309941336a5aaf3f8d884fb066e1be202f0a5824698aedc16b097163316f2e9637c3e0b20b792a3ce06ffaccc8c01feb75db6c1a8a5f691fd6f0457b21d6f96014d97181c7e28a5e38a313ba81781b44d944fa5180921b4e3a685c67e7b5ba54522b12067ea024995c2b4d39a4378e235bc9617cd45226b0b462acc8268376f09ded9148ae0c2c54cb0572c7ceb489276b6f9865480d1328e52c20b2a87bb25f8f8fe19c2f1f9253a2f9d91ce5f306a71365388975e901501ed2061722b40b39cc5e126be39f84c67f5d309093a230fd41635b221b3a842bffc6c82b439bb4f30c82a0e455c77499e96fca527260c2387b5b33a342fb731983cf4493ce8616a7a53c020b4cc0c3be0b632c8ec769378bb66387a1f5aef060a93837742564a44d13f722b3c33c50977596828429b4d9cfd84efdebb1716ad8865c2bb0b7a428dbb76a510b3144751ed6f56f3e4a1725894ae0491db526f33ff61610340d0ae06c3c2090a090850b2deca290112c8c9ee587277a28c6783c18de6edb089175f09c0cba60ceb6596411449d0e45ac2e45a96fbccd16876400fe6be3abe02546874f1bb2c02ee37e4891c999df82ab2e71bdc4b8565e904d46de6572a8e13bbd57bbc7666076ab48a848eb008f5d150b8f34e2950e07418dcd2ae4d4618bbc20d3ef16d280e138a7bdbc01702cb05e90d7216c66cb9f4ddb7036ba9a8e490c2d6706f6ac61e64503d935535e808a69eaf53e3c6529734aaf10bf83f868f942f8532031fea1b8462e093707d67a47944a349411088c6642cd6a7686fef5a7e239b0697054c11236b5d3764b83f9a409821ce9b4b87bedd5ceb3f4fe6afe7a7c894738d1c35296c66c8d85376b5a864281a54897b64e90cc5bbf2778ab3edf83387c80734661b77c4e4eebdbefd15d57a22abfa5662ad616b857f09acc5f7c03503dd36f569035c3c9ff43a306932b0c6921ec3ab08210793ff101a1cdb4d52ada493df83561c674eaca29b3732bfeb35648633817b65654639049f14ed8eab71d7cadc6a472d72dedc4c511dfe6eec2d6f780d3cda952417d70927de7c890c822180b751cb22efb494f2c65804b31df2d6fc8b2e02b1c3da3f32183ebcab8662f9dec0b9db27970150805f57492628d4f2e5cefeca33c80f49d769038ecea2193dcf848bf626721a1fc9537290fccd8957f41fea37a04af789d5a699ec186f0c5195b9da3a0d289910128a71cc047bb54a1a2348c809d62257a294655ff515866421c786c31b60373c7229263449b97139a1e73d1632c5c655a5298e01e0d93090bd458b562571a3466918118d55c7653f72fabdbd090983f3d374b657938439592f27e63519b3836279b0887e21105c5b699c6402bf9926c8774566b8696178ca6e6019d60fa85a2daf85687adf80a426ac4b3280a35fa0a03fdf7caa03453744d3c95876267ae5a2ec7cd9bea56c9f4791aabb88c44f77aeb2be859b01c3e657343a1fbc0301584b569bb2677bfe761033251f642a36db5fe7a900eda00a899c6436b3552257ba5af5060156dc3cf16a744e6bb61f304c2e8b882dc5d920a2eae4e5d8930a12791bbc837f109d715e94b6f43c0ea0f912edfa65b296b79fd2fafb4eb80d294d411f94f57fa6561c81af4590e4f64e246346c585b9b1825e260618666d790d3976646b3eaed0b62adcf8ca1eaedaafa642b99b0c668fb2ca646cf83ac831284183eaf859b2dde29a5bc4ed0fe1ed9f3b3e4b66b5b1b1b8e2ccaceff284570e94b8e30962aa3f7834b8ba1ea36a8ae66af7c05c9f26ece5af36d3e62503790341dd82ae3f277043cdf576765127e8b1ef261938dad94d9253166b12e3012a098cd13cac7440a796ab7cdd143141d75646524728a119a9b8b7a6bad74992b229f1da3b792912490932d69dcda2f002679624dea63b05b8a626d29cf0a21e281008deaebe2011441e2251c4163f566316b754bd68de1e29d872314f14c98acf06c65072574039e59a4be896da9457287d943daa8124c8112cfd53d8416b5dbe2389f9b0e142bf22bb249b8a65aea8678c3f8e337d8d01cb053da0865c48b95c2a98cf96bf95776f89fe16e6e735b6ff6d77d65b19c713ad94b2d833e274b28a1d83ecb08d14c57a21c6fc084500a03f20d2f2f4e113c6234631c4a4c862c8452d8619e2fb00d51f4660d7eebe5d0b485331281e6e4fecab05ee5b39fd5a576007a02effe3276eb44bc256394bb45df037d31b8a03d4dbff274b7d4dff96796329900a5f0ddf1afc22b52b45204173e66c015f00c263df12c81244e6aa531df60424de20721c938a170a8ecae4ca005937a20beb47b21d5114dc6acf93ea1612242dc85ca47576a18571f7ac8619b4ed0fab62fbc14c988ea251c175ecbaba5a2120eaef75b4a23de5516c4409c15984f80e7a2754be08f8d8a586921d36da642bde79fe59910f9c9dd77ea3043601e017b911b2bf632d7638bfa2a0df8dc4a4158571fa1f23328c3780dbed7d136816beccfc88d346a328a9b5bfbeef4bc0ce04edc95d456661d0eb8b84b5f49bd166423dfe4e44d292b5c221b1a9249bcb09094fc663b9b1a33ac12f371616bc82907844262a4257f3b0f30494ec53318e4208e1927d77cae51515142b0379df332b1a69430dc6b1faac64d7d5c4ea9b87a71af3ad9c2c137e8f0720aa216af2f0869467dbaab2593db8e98a43a77e2c688e0f4ee2b6e37d294f473cd9933f3ddf4a6ed9b6c32bbc46c95db64abdc2c665b60f30f0494c32e794f78d06cc07204763c577e6ea2807cd9129ef13c0c63d564026df11741e1c38e336332e811beaf01a8336ce345ac7558d23ced7c63d4f7a6109116d2f26b10687f2fec3bdc80ab96f9d6cd940dbba2096f69f4cc07cf9b05007073bfce2438fdc73e5d2187e676f286fbee1c9ce169d1ca1bcc3a71d5b515a2cea999f3f4b8b2000e1944945a0ec5719f2ff71908c8903f2ab1ebf811139bc1ace82e5ed82e865146a52e18acc699d0583a4b0b8469387b04045acffcc9b8a1faaac1d47dbf656c92156fa8b864b34d75e6ef4e7dc75b031b2a6f48e9eaa2d2fb3c68e3adbb2caaf732d6f6ea726b8904a855196a864e5a2f835935b51efd00bcf1ff872cb1b4135fcdbd5d1e96a7a58df82a1a2ecfcbf69f5c0a9c093333417d3dd49754668e48b033d2dec98fa0a2adcffa47985e039acc5e49d12377a9f0271e8ebd87fb374d9f854def3b254c1495cd5722b58cb04b6da4484293adc012b3ba3498c119faaebc4d3d3e7b54bc4ed8b68415797a813ae76c4fc43a7818008ad9f53cb63132d925fc1f285b75966339371c9447b2c45f9610fab11b15598273da77731e94ebda44ee2fb236383a0a0deeaaa0ed802dad3b9cbf991474c9f012afcdb34fa6eddc42fb1d2599c2b38fc70c4baabf6d787bdea3ff8bc2cf9631517c0ddbdb7ee2e008622cbeddf715fdceff1bd1aa94a5a280b1308b9751304250c62c27c3989eac079c11f437c3414111356ea1d7987befc81438ae97b6b632e61faec19757d01bb5c31c78b0c90d26a3b71709ea3626198c5562241b226cb1157ee972eb53a12fb593b473df72aa843e1450832cfc721fd2fd7f037c1b6d4263a464d40a4302aa2495b9d9be79915f656fc201bfb43f1e6c11fe7acbaccf803259bcebde2dcc3056bcc63c53d6b292095447edfc39d783edaad8a5e798f1728c64ab0b1c0489089ea5b8ebc7b53209ca084d722795ba667a77ce7f6b45aaa17c68ebda1440c7545e684bbf9e648ce2fb4c2429968a2204695e3e28b1b6ae90b2837fddfb5e70cf62e75c6a0b446125f793cbfd4bdf28d9f6b99da1e276ec12f63b8210c9faaeaabff24bff05d89539e3d6753a5d63ac9c8d6a05482bfb13e0fc8f6a95809478289e225f918f6baf43748868b25d45f846e604fef59e5d00b109fbc8e63307141368905dc9d3d0d0cb3028d7f778215822a3fe943c1f746711fbd74bfe4b4189f88173b2223c3c0266b82b6ecdaba2542723592c530aaf2301a76a882bd71dff78c2d22603790c9650b2e1e1170d05125af5d0a319d745b2e149f60779eca2908fab92f744af749856fe553d3c6a29651aa82d2f1dc8743a8171861bca3e373e295d7ad740a458d2e648c1d0172b1fc6466fc2e6a67abb97712a837b4085cd6a5c5447ba344c977d514eec63dae387e57bbea863222aeae2f17c9f83f0915c8437b28107dd00705f2dcccbc6b5b86c6cf65e7b67229bf72ae1ab5db1316dd37ddc470c48ee9c01f73f4eb0a5a661939aababee0eb10cceb7f259142020f2f2c2cfdcf7e1a73a9788ed61dfc804d1be7e5d2a6c4697a5b1d8a0c647fe72135aebf86f18b0db90bb6bd0ccc896829725c28651d7e1307fcfcee2f4cf4809ab83585d0bdfcc0b7f11245df7eb373b7639e41cd6947e49dc05d1d24e93ae6b006bede35d521db286ea335822967251ca8b1e75fe98c6d323a52810912269918429ae971037503f97fc1930fbba65055167a1142c4029bbd13815d298a459d0d17f83607b8e553b645b928e12a5ba47c3a29411d4660bfd27b522d2238834c52fd7d29853a9e34abfb12528f33fb3d27618e6da73288e1a0ae3b9c011810f73a0e7f5e4a53700d0486e2c7b89210ee348db7ef440502b39a6cf72e127e0a7f12d0b42ebd927e5f3c91f306c2755a4d4870e0fd4145c4a868afae772138c4188bcc47eabb5c045ad1a6d677212baae9ef7ead5989fa664cf1afd35e2a0f79fecdbe7b8023c60ae6f6daea7891ca68e8e995afca7c1ef6a39f24711e02416e6b298dc891eb5a6f85afdd0a44d8a071b576fa14236debe858125378cf160831e632c434b386866c9f6ee7c589a9b181956360d998d1e2ee3cf4d79e832ea36e916003c90f97ff0487542b33d0332cf34ae74a654da9e4e5a40e8e9bdf1651b3d3197f8097eee61ed1d6425eb1975712095712a5c7038285ee4fd16be228d77c66915e9524b9b0cdcfaf9ecd26b4b3f10a4e425f44480cebd3003b70290bbc5398f1229c4a19810868a35504068ac01326812b8a0e9f665d9195d64bd42397b246030c014d748e4be99065f8ea3c72c983aab168cbb76a70e6a8760bda15d4d22844d77f4323526f30c54d604c493f223f4a341675b2696e4ed812bbd81516245b2e5c3879275d6e7a6cdbc6b978064be19dbbb1f656d4c803aab83786302a6b5a5a43a22f99887ea0a812fa8b51aa8637e5df1d7ed5cd318fc5d00766082bcc1def74470c7a872302bed39e8e051ebe2ff94c45217cf79b2a4615a41c126eae2b56037c4399d124d085ebb06d53917a7bd73c1413756a8a78125a64c4227444263469b7b5edb028c7b98d313831c93cbff689080d1bdb6f166644284b25e9704af7c3ad31b34253207d2064f36eb67cefe487b6fae26969b8289ca5290953c82bcd3454e8ba7bde204b4f5be3e8b5afeb15bd8e20986fcccb93d08e8825e988859679b51fa0f938c7476f55dc3929998d1761c7aa25e390caf801f8ff0fe2d77cd8755a04a4671dfb8d0ae1d2e917a66802e786425e13cd695a631705284bd012acd166ef99c75099b6f603dfde93e2623cf6e47753c76e2f3d8ce507298f3e71c7340938679cbfe5e5bc22a969f08c3372c9c084c2636a1cd76fb2e906095782c9c1a9643c968d0b146233a57ad730d77332c10c8167cb180dd3512c24a02e872ca9f98fbba84d23141cf5d66207f879a928bfcd22e5692396ddc80c2b9b1b8b50b8de8cece0a17d3c8ca30c36e9cdf045e4924494d6c99b29e929bc2d117ff452edfd85f7c4adcd9cbbc8a3ff76011351aecd157070ff978a6048dc08412b512073bb2152f681f316f1f0625fba865a9acdb19f3992e9fdca4189d520b9f5aa6e222057b464a80a4d04b2fc7b9f92a5a8667eab1faa27945e0081d61fdd29f1a7d5444f74f09a2f30044d16ef1bf6531a0ed6d1151cd35a1b6283c222185f0aff47c7e7a37a6fa0846c983103871dd1870824b8d18f2163da9bf2a70038b0facf58a67165abd01d21cf2429ec7153fac53e2b6e335142fd2cb3aaa02423e67047c73fc811b4ad3c8b452fe327d594d9e7e1d51417edef03990949db1f7e274080f76644ec70b2b6c05267ddb2d6c806e0966303c77105a1ff0aeba72558dac392c66ef60efd29a6357cc644348b8b9ce3c39243e41d3a107355ca050109fab6c07380c8ca191e908c144271b2b55a8490d28296b0bdaa34911268801aba316c2967dac2ada95da9e41c72427c498ea387de3d234e5d728959fcddec1d48b05c86337c38dc83ee23caa8079d5f809ab2d1f30dbfeaed4ea7e4b87fec0424d66e7ef425245355ba9994876e17000b875b53053eaf8f38e6937aa4f0ea2e8d25d8a5e2087be8f9392bd56e9d95520efbfecbe8d312e374bd8fb10a6dba08de8a096af917c4affc0b27e093ae6d1ed63b70b0b88dae467bcac39f7fc88c1a08ba9b1d4db0dc16e2df05e265019349f8c250b2966754bd3aee8abfc280bf03c7dcb8d5c003eb7afa191842ddffbbb7e624da7f397fe89f90b12d349826d807a2e3f357a0912d5af5b2273b32ec9974f43f163f2aff433cd805f30e26edf12f3a6d67ead33ad272e4908cf00568cfbc7ca9b12e9b15631814e547d6569d910866261e817e204b0410ba0fa7511d7878dbddd4e456b5aed444d8f730b5ced605209c97a9c9b775e9679c3664e2dd37ef7618fdac726bb36ac97ec093ce3a85241b49b290fee4fd53ecc38866dda42ad9e89d81512cd5482f6feba6b84d099f1e0d9d2544c2462149b6304394161e678132031158b1bd24066fd2e943adcb202d4136b5fce7facbab01cbdc9352aa2e773c8a40fa8fb735facfd70c685cb4941818959346ef51c68ebff31f6886fff418c58b64d22b17c70ede38ee5048c06e1c47d7159575e4b31acdf5e1132543dc1a394dde58683bf6839e222d0da5303e1eaf022ed8ff621c383856539f24839aa597a53329b6153c1c663d94558289991e0efd67c8971dfeeb6f36e712e835ca6d6b12cb8deb7a39e5686d0b7105d0f00aff977aaf69f9d045f19a01d2aeaa20d181dcf04f46f5557e34205686f4ef090aa0dc2f18d59f049b313b135c52f2a6276928cc0f11ab4948bb463b12ea9e3e2aacb661846247a5c3e3d349e822594b61dc48cdd93e68f559cf6d834acc90e728dd3288e94b99740ce069be51320defa30e03fb5799a33d7440673bb536d34817b1ded0cd3003019ab911bdf5d0384d48152312612aad122f8975d4b358bd2900dfb7e65ca31b2f7be187ef465777c278f670ddbd71deca7d5598a7b734913a13762531d2b2add16d5e37c92e7a1544011be58bca9f05750b4d86c9fd2abac413244404d2e8247dfab02c91ce8f4e6e0c9731cc82cded1c6527a844df0d6da324a192aeebcdd9f6bbe1db18a50813421271ed0678a8595c0bff9393ff84db4702f02eca84f25ca461eb06c310e1ecb75863860e47be4117884f075626c716af125b03ca92208379f81dcc34e4f41a414ab8b5edde232f8fc280ab049fd082fb2a8973bbc3e8fa46937704993202d184e17f80c74d3d66fdf28510fb1b1916ed1bc7414792af8f0bb1c5029dc468e3931fdcba416def99099cb00e85e695b28903636b366320015aeda121084dfb493171d0f84cc3708bb15a827b9f4f8af6782cf047a876096716594c6042e2c62770c37c86a6992e26561b4937be8deddf762235bd98c8a4abe96acd8f44943988932da6622c996564e8e4bd6d86044becb1005c7014222588fced532f040d85f21b694a4e940b7292545c9d7cc033b6ad4c1508dc7da02701d8d5c819deef613ac4d2f6170cab35ebbde63859a3f1a4397e24c51253418723f2a37e50d1cec94e0a1ea1e3f4b9ab19bcbb1fe320081e89f122d5592111cd83b86ca5d74db8aa45644280938af94f30c246de5a9e42a4e7c806aa4f6bbc0b40b66650fae09f068980329ee6ded77e255033c84f9fbe734bcd2bc175d335b3549a3567f0a5a242cee45c1d37f0dc7c0e091404b766ca4e37d40a3520a2538997773fad1285b4da877cff9e302bf838ba0dcef08c346bba42cf17e1addce3b129357a52ca15e1847649deb1725b35a6f92cb599de7ae5bfe1312cbc1e5327770be0eff878e8f1bde2a21467e5fbecab7290a1ede10b9df07eaf0b04d69ffbdaa12b51d1fa9522f982c4d89239d47f4b56ffbb8fd630b3e6636d257e22d3f31fd1f59eae4428b42fc9ccfac6cec11aff3ea7d88d37f45b013c340faf832ca6f3044dc026011db9172ebd8a50ab81f86db195239097ad5226b5fb07ae137250b94a651e40711a345ac56fdd076f56f9d2edad70356c1647853a562df655a338313805345bdc388451870364269856156ba27dbf9f013a86580a58275c3a0c96db3c6bd69e69c6627e8b37c77000cae86f388c855d88138a1d540510b7590554caf3b3ee1c4de0004826ded89c3c2d886255eb6c352df92ef402d404b008751a6219cea7831bbe590fb7484973247e7eed62a41fda7fe1b4c517852f9c46a3caa152a6ba19ed81d68060ab7de2ce648f2e959149627345df0af88013a778e50256572cd0f0db53e6bfbd0b265226056157d842adf904d66f68f5e82ffaf7d267bc206cf126453fbf97aadc413e8bfd0980f6d2e51fd12c6b8c450d22a7632ff78cda0c94ec01807bba33e809a36bf6d5c3e15a65d0380bfb5738f20fe99bcc5c24df1f7dfaaed12790f48d695d10fc94448aaa6483cfc44c668d2823977f80ca02bb04aa050e297c39a336ba8ab7392f3f0ea13924ba2e4cfe4c5320f0a6ad82e7eccc5de9b85d68ae340c4d1340b64fc691e2f6d976db379468c80f1a2f8ca7bd84540963fadc8241efac5f7808f44d7f7b65c84a9e597b4a8f820a8643ddc0b3bdc9b3ad0bb1c3af39bd93187e37b6adfc8acb7985898f3f7f08076f5a84e1f44007572f1cab6721c2d2e5ba74f0237b384b3d2f801cb2adacd71e00f0c0d1e7c25ef230bb81a52cfa718ab44ecaf68ae3cb224ccb24b78ab3f60e445b67fc38fb2b395346370197aaaac7517d2b2aeef97769479d46358d8b5f0737c3304ef4cb623a9edf6f53b433d4ba88f2a71de5a9560c0494de2cdb2be50b0b228b1051a2708fdc673fa6df41fbea855fac8594d675b7782b86d3fbe2d010a001a81c82e8de37b026d989c382b2a463ae5855553d2a2fd4fc239307dc2006cffd98ea7ea19c1ab6f29976568c0180742ceb1389f2b787525d75964aaacc03b7945f1be91dbe8b9671553c5390fc4e6b504216f535c8898e54e8343676c61faa9650f3b1ac01af6629a87cf78d157ebf2576dfd4035a5c94876d5c46051919c6574b57939fd6ae2fd2128fbcccaa43675804486b48088d076b167a6932c10094d9cd0a0d704ce50bf44c160e3a4dd947e18398f8951353bd2f7d10901fcc1e467e5ed14b5ff29adf1db4fa4c1ff120a9b6e96b2d96267b24de93e5b58a730355b647a71f8c66bcd9f005eae5f2621d4e95a0e8f0040dea08c5dabb08af7e06e3e7e082a4cd093c840486db4b508ee370979ec8e7556050b81517a42b7f5428e3e929a0b36862db159a17b53ed64e3b19824f29a4690b403e1a06aeccbfe523887a99b8bb389be92479bf4a88bad4e9fa0765e38cabe9b4cb0f8359ac291513e1ab0cbe99a58ba6fb01277bb092f76bf72ff69b056c808302a73c303dc03422672236fc9f0e0e3584834fb3e666af49172fccf5e62e37a5d8ef3c30eb7598053a03524e50e3629e114de48ff812d3ac27f69fab79374e24008af2c22ab922189f58e73e3e2d433cb8691dc28d394416c53adad6433b24c756158e5183a4c72b6217027bb06d3abac3724ff8f65085c9c274f4361f4ffa696c196a5ce5c06d015a4869aa4894f7f23c2c9b723dc88b32d23c7f7b17fe0d960e75d43247e3122149af32b83259e273124e2b7fbba33da026be409cd308e87b99fbd4dc4e3b1e2f82b41ef4d94c4833b737775282fd5879f57b19f814322fe572a1e83eff8e7c211aedfc9ad3826d4fd63e00ad3f6f5d7846c028f58bd97fcf048a65858a6f8d29d245380da910de6a206c761b8f6d9adff7ab770385fb81143e96c8b1b1b50d3038cb42e6627becb2b3f0e88797ec28531752945b90c789487c5d82b46de770143ddef2bd48fd0e0b784ce88b32b93672ff466514e73d0058366d015eec42d82ac2416739bc1d07425ff2cc7b40ca139ac01509eba5b9202e7e721a4e4d372e1e98d84308869f428f96548f633864a57b7eba50b38e021a6226e28072096f713051f0b0f6ccf473d4b76cd400ec3d2fde6d77af2fdbd7e813730995deb9066629002d655f6405da3e09e52f70fde13e5a8002f9984148df1c0ff041ce4a51150e7a76c3cd5eade0672438a5ea1d1dd22bf7a77b23ef9faf91d032eb18c6ccc507582531d1d7879ab921faf19cb135501352150dcaefcd82dc1ffef26d41ef2228297b04cc49e099ea7290257eb1683b9bdcd3bd34921f0ddc415d4e79498d580f340704eeb78eb63816c3bbcf6482e4c2ffeeb356cf808367622288839785f02da91875ebd91f8271b60ced8088c8c10e1591c64dc26baea11805b46580dd9f10a9102266062bee1e3e475b80079c900faf306e1eaf8f1aaf4484f0000ea75d17a0b8d9ac1d396615d1aca3af0b0a9f6a3d86f798679c129e6022522ac7785f06b97e54dda22274b7f6b28c57df7695ccba1d1edb1ae386e8167bd352b49b54168f0b01c77ef1e91baa5223e002ad97d1a77aa9c249dddda1aa025b72ed49a10ecd92d4b1ec8011ae096e6eef733c7e305304d9a68d74a7d8abbfbd3d41ab9d05d1fdf5080883cafe6fbbcc97a843626a9541efce71c8bb4a6b50323193a2002562b7a415d4de5baa9d5c72068d1442d7498990f218fc03b5ca506e154ef325120dab908552da646fc5d6c2d2978fb3cd67bbccc28980114d084481383b60ac18d9cf5316730c0a9d02e46596426e88c854b9898b7cf798420776e779e9c51a084aa19f2c753f3de4ac67e558a6427a04705884c183295ec6c48b9b6ffa67a4258ba74b690d12381bd1a4a887e0b231ee84077fe2797b23ea41290dedfbe00a2446b17ad57771abe27f3e448bb01b17f69e74a063a253c91ffd93726a7644b12442d70b8753689a11eb6de126041730be57e8f71dfb56179d1507ae113d480827bbebcc7ace9d7ad5a46ef018734d393e98333e8b9fd0f77317ea5bb2d594722e3e43c556d5088a6b27ff4adfc0c1384a87676bb2aa30217d642bd6dd2add260d88f99572949c86c1fa4a1332bcd3728986c45ab37c9ff6db79b662323341b9013fd43f11c15eca886b4d13c8500dc1d8df937dfb49156262a412654347dcf80afc2b5ad6847a049569a52d91a93b047a0cd0836e6c165a3337adcee9620a1f19a5d392987cbf44ed846c39e36581056a5bbce8d26af5f81f9f2cb1bd58b17501e80853d15b8f735eae9ab20741f04b36654b4eb0e485b28bf7786d4ca494872c8abeae9a358850bc62b4e248201f315885a1b3007d4ab32ce52b3f4fec9968137edcec321b6f4a62112e4787b2bfbd7602cc6005b7eb482de4aac41f4f3403042c688454034386ee1aab7ef75896beaef9e6d178f650dc211a4ec50aac20e43008a659f19ff1b3b52ba2a53e0d258633e091137c025085850a13db466755fd1a387fb0b270186e001651fb51e422f31710dfce6f3a56e94cde2e9290d0cd3d1aae40949d1b7cd01599182d3a7dcdb3ae8cc005e2a14e1b39df73084f84db292aff9b4cd5373cb5a58def79c64f8f9b124ded447ca83e959ddc955e02f5786c1257a84c5697dda550ad7c7fa446840f9c52aa3673788a425a8f39898b64223b03433f14358f511051ebef163691391a110b6b9f7700ea415e2fdfaae627af710e8fed12c0e416b4c0b58b67b6de9c7aa4f5f22177786fedf9f06ce3a94d21f5221bd8961a7e292e9cf231f57117b134f0a0760a6748d626834b1e96296635c430371dbdd772bc5fd6a3a8cc16a23a23ad590243e746fee1506a882c081eeb2d1806ec3878562fd5539690873f380628c189aabae6ecef7a59a33f069aaed9dd117596a9f33de6768546b01bf20b4caf6713d148cbad539fee2b5d69c7299e5c172c53a7974407ed9212b8abdc2f9137fb7c459806fabccb825f75c3c08c0dae23d223d74d5b5890fb1e84340b3916a7cdd466379302100aa313e76ad493093d1ea729f88743430d4b9de0c070ac5e69875be9fb9302edc0b8d623750b727137108494ca5bbe9dc5605496df7869a75af39b8003e759e2c02f8463f46e93ca04","public_inputs_hex":"0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f70a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510fd2e0c74ac08efb87cf1059f1e30dcc9468113293de905e1b6098606e2dbcc3"},"decryption_aggregator":{"proof_hex":"0x0000000000000000000000000000000000000000000000032f917b0fd3ba7a530000000000000000000000000000000000000000000000035e7eee9919cfc781000000000000000000000000000000000000000000000004d01f8760c8703bfd00000000000000000000000000000000000000000000000000004d94ca153b600000000000000000000000000000000000000000000000061836908fc3b8f2a500000000000000000000000000000000000000000000000f58c698fe27f1c7ab00000000000000000000000000000000000000000000000c83238a843749bc86000000000000000000000000000000000000000000000000000212d3d108ebd200000000000000000000000000000000000000000000000ef8085780c77757ba00000000000000000000000000000000000000000000000c3c61f9d2347a2f550000000000000000000000000000000000000000000000019c6e6ab16a366da50000000000000000000000000000000000000000000000000000d7fc69b4d7cb000000000000000000000000000000000000000000000007eab1b3dcf475109c00000000000000000000000000000000000000000000000f3b81a7652ce16d66000000000000000000000000000000000000000000000000b7fbd961c0c8033300000000000000000000000000000000000000000000000000005047797e138f27e2b49d2890a1a1d7d9e9f9d5f8de1c723e2432ee10ddddd854082841a60a190d1e262fcb062cd02b7fd2f59f3a9a5270c713891c8e81a49fe088806914debc146279040a63dd82eb4ce9221aebb89787e802ddaa082e654c975d695db28095217de830d6428843cc068ed10d043596da999068b91711995406145a857879f61aac072ef64f542798bdbbbec186c9ddea949792d717af3f861c541f6d3329c8139a72a4c39e91ed9cc57640eda4f794c250d137a8490b015a87034b26243a7e2ec7f12931d3c8474fc12656898b4e3bf422912bdd4db5374ee12c8f096d74f824c025e27442c76ed1b51d39e2cf7034a4479893de172eb8b7294dc4e8d271a3231e7500f202e19d8877a126052f950431368cef6f95f062ced311b8ff6ea4a4149a4952e3d78ce456f6fe14a68b1e90adddacbbf08765d209dc70609ca6400a22b52ded226eb2c9968f70cc9e8d3ae84650a167b9c9f15c26049d55e1f4c1fa028ebcd480f734412ce5f3a2d710a6e77762d349254e59ea37ecb81347b5626e298a12385b87048dc8debad8f5b2908e0723855959723a666f21eca85d3bc8b00cd22a77a7e4e84a2b36db98f02f0eb833246fd103ab30983c6efd381068b8d71f3fbf5f01e7009b84cf9eb866f583ad0c6e4c1f1b9f457acbec88e87f5ad7642c0a219b76dbcfcdc79d797d9e36eb98bc85294d4e80f324c41aeb5d5c7e7a0024cb722fa8c2f51ebde20d08f7808d710737ca258f5d5a92b3502d21cf54b5a00f101276cd0fa6746fd15fb69b4c0e9c468793c3d9de7683305d1ac0139b3ab0101732e6eb2a8c4a782d8a4de7eec90b02a5c2d018de75c066c2494e6f51c6df134d8f766efbcf3ed54ecb62a51e4ceec128d2059759359397b487769861435d07dd738c9bfd93cdafc20a2bbfbff80b293523f1504d9eb4772de3a8799748ef0bcacec57d8ae3fc978ab8ffd64c15a20b4773db561a5a6bd51fb91ad9226911231fc9128b34c554eaf02080253b584e58ebd1cc6e6c976bd0ef8f993282680c187b610790b86b8eb17f5f46cc044b3bd1ff9adb80ca51ede5b36f46a9f62f1b1a89849470515f82eae676e8f251c869872d45d6aed4f38f7d2d0858bf1a4d93058186322e7ee8b79de71f366c9855390b46d2e6c5a6e3cf63fde1e851e03fb10b5b2399701861f4fd31c8bfd664c4c928f3413f55049a1d90c671e9a1614ee127e412345224047f85d7049836cfc6c9a331c14c1c0857dd0199a233c2d6392e1bc381eb283dd577441c23d64f5878e6d627ce803cca051052a1c74c8b66aa69162662c26b7c6664b363e0727e1e9844ce3d2662ab8fb678d1b192fef266bb0b1dfcc5caee4ca0fd5c615ed966245a26131a576c846c2475ba08597e43b5902e103e051dec1ac8f79d07c157ce88a7b2411788658e0df6dd5c23266a513e8b7a0db93f7d5689d0ca3b5c090b9258bd3a8cd939ceac84c1c2f61915d50904a9de29d376f9dd4674ed7e648efe0ce4c0e5634d8d90b6d1e569955fd105ff2751070c70d8bfc9e75ff4894afd01cc06dabca071edf803c9e8e1ce9637e0825ff5fb0305b5ca6feb8d9c1b0fe37be80ac5be9cdeef33956bdeee9d489a5e18f31b83265c9780c4ac8f0c6460997b3e829684c20823762e4850c2156c80ad47db73440f3887deb40f6d3eb415e4cf5a468ad78053028f2d41fa55af530a305d496a1902183d1853eaaa7e4d7470a5520f2142865d8575bb4d1116da36cad00fce14e000315b8a500a1a46059103ee9b2aa0d9a3a9deaaf941369b4b9d8b08ea36cd12179d921c8ffa4d2f47b68b438df65c265dcc076c2777f8611d75cbd6b1aca59119d3221631736761f87dc3fad1d9f71a4ea8ecfb742b1376c06cec1d524858892e1429670e288a4b876c12b4079cebe718f43fc9acf25e76662faba622d990ff214913406b10cd7b24a94127550adeded67a6d29e5600363f247650fa3bbf1650d9dc9af7da683071fd81e8950edec9bebdabe1f7cfe0195e098339f5bdf2a021d02d26abe670315342dd239fb6bf77024da51b7fe27526e111afa16b312bc0f009f4f13105af83dd8e15a51a81d2ead3d76f67962073d80ad460517b6444342298f836107bd20a98b029f5cdaadcd3918c2d9f1d2596d121dde8456565ec01b1db9eb5e4e16f246568c72c64a8ff78927b7ba1d22a89dc0415f084bf1a5c5e307d2fefe8c7c73dc9ca90b4fd975943518f3f9c1dfe083278ba5064e5ffb805d2bf413130a56e5a4a3eab4bad0dc4a5fdd4611ece922af711f0b99815012b2862d53fba4d59d04810bfda4945dd3c93229b1a143e5db3749c6fa8eb30ca3c6a313d74b0604a7f3fd97373f21d8235ce46c550cfa3c02f082ea381467461261022f035b91ad4e1fa0a244b68d9f81e6c2883473f7317cbc990ab7bb71f52630930b4f7231da195bd1bd644b5b2fe16173e5738fc7b368ba6f1014c055cafeefa21e4f186454ff08d1b64548b75dc5c7febb1c27ec3fc5bb59f5efdc25633386cd2fbd6acc0ce26ea7c11e8f2ff5c03cc27e6dde633edb6703664d9b25ede6297308b872b62066969fe13dffad85fb79b12a7f2ee224c2fd4e4cce55b45e4170c7125ed83804f3316f5c17470b160dde071c81d0e9d5e50f766fdf519bf945bd5921b8d4a8af0f1ee513b5d173b3b1ead3c348bd0038ed7b159be86de0109eb8082ad018b9f99c8d7eff3c28494bed4179c43636eb858bbb17987308b52bece0c10589dd01c8d6c6bce012ec221617cb673e673b8052e7e2254e9e08d84190c6c6258ee080fc0fbf163d24a91a2fc4208add9b98bef160bce94b7f6ea671407c150a42dad24823acbe16ab2537442d072a3f6c339581fd33a1749608fcba9193cd0339b24b250972378b10b92cc76c073072924728ee1f9c112abb15ad1e00396d060b30b0d3b8f3b09d8be157157e00d9bb6de1e8c4e899b78212151aaab332b504383516b0755074c07c61d550b5a354fd1204decf0b6d123acb7442f4925d18041a45eb9aec1f8a6edd6969bb0eaf06b2857963547d0ffd277173ee6a2ea831182263aa5773b19ea5cf9b871bc36a39ae544d732858f70057aa6ad36967f4613041fd1eca6bc20777d0a2e58598b67dc69eebb72d472c989d7604004de653ed0cd21ea34fd34c069dd87215a779a6a01d40d7b7333b8be940d34e3889bf96dc07149af5cbeb8494c5a7cceecdfa9ab4b9a7dc5101745b0876706a9f0fb1d05f16ebca6656b0a546606866f3493164c7c7d2617947d68e2c21c89df9e02b5e821c16f98ffb550e9eb98a1a926a7955b91366fa057df7a701e6b22becba0d5ee20388cdaeeeb6ce41b68cfe8b3d1c0d18948490c8f65bd028e3f8ac92f43f99001a8585ea21888777e6f4b0c393b95f64228971149dcd8ed62ac2245ec2453ec809a4c281ede4c0f8fead07d9c33e8fad95f36e6d71aadc7c2fcd88fcedf2c2780816bccb4df8d7a8a6b0a323a72954c8f469031663d7d150619ef3fe21ceb5de2793216c0e79a32438808983c1cceec67fc5b86965315828795a44245f82de0a1cccb11d340ed2183ead2c424b3fd032fdbdaf9e93b314d7de104100b508ef8b07f682297ad47f5a43693b375e85d181090fa4cbba644ab99bdb3aeee7cbe0a123b1680007468d2376fa4b087198a880b7d943122c64e2739285cb197ad6d87c0f8410a1295bff339df55e97c9e2869a3ad39ebee71f0442026725e13c7894701294e42521fbff09cc72bca14c6ee12055e93eb6a36c3dead6bae7ff69e214e5157a8f7b3ee1cc9a630892352325cdfe7f4673bf9b250f74b0d53a9ec62275ed08fa47c06229ee7065a4200e5d2de129180e4a3e2d896d322166a0dd71bc8ab00cae7d08c8e4ce746faa6ef6b7cedb1987db5a46bb1a78d01235dccf1967f4ce133d4a0e336c78fde09b78763813bfe420d501fa1bb77fd59dfb7e9a5df034a30286ebeffc596cc19e89ccedfa81795a7aebbcc9aba21dffc3e0245246f1099d1aaaa6598a814cd0d504a677008cb789c2eaf178e159f5c20aafb301b4f0e8df2479de0f3717d4e4ef7dc83d738610d2f9bcd50d73dbb619b8074f392837dae12bb62b06a460bc9beae70d089fc01a43d5b6c01d6ca2e3037adaf61eb04dc2ae27c47045ac7caf828a562ae12da800e7732b3bc8c550cf584f515f680fbb2b2f28fe7a9e126ac1e7262fc0c4c15a8524ffec6e26abdb450e445cb62a54df6120269fefb17a52977bc955fed6ffa537a1b1d8194c864fcf06ec5d6b129a2e319227a8fadd3a40dfa0d6819498951b4867672fc74428d26c7d490f3a2718ff46a029357e4d83809324bad732e822805a0136e3765feba528bceb2317fa20879da32961662f7a785dce16e500991e0b9c32f5e1a9b80300876499c96b3d3369232e22522f6faa2ef3d05f5fd66d54f0ff085ffff1777b5eedc80bd244a8247be09d299994111e6aa8d0b60c75a68fa4aec522abeaa11c977b175e7c7ccf154c0bcc19ac59eb945f924d1936e318d57d6418989e411ca5870b79984a5a54e32c1d18128c3ae13bf6ae39462c274431cfafdf4b5901872c1e7277a5f9e9833618290e0e06311671aa5e3416015247a0e2bac183c27dc687571b0b581dd3f6adb8962415c7097dc3d0f19f6ee891547d6a619bb3e3f1cf9bbaf99060d8556daef9b16b05416869515e72d011820ff51de020a7c702c7a7942be41bd5efd5e3e96dc3181c682616910eb09cedaee661f46ceb5918d74d23a760d7555a14bd4d012e90d713fb7320d715910b14bbe9439e621e34a1496e8b60e628c9dd5b7bc1115588c107eebb6e62f46011149032423e6ba742d8f8c8a0cf39605e7539f0f809646a3b25db17eaf635e9d1217fd85dfede27881235abe9479fb8ff0bd5be4af87059ae0b42476793bd6e018178fe9a74b84718d5bbbca46087842120e036b0bd3c578f1e76504ad8ef04a719ed739a9583fc3a4b9563d1904c92849a4be6c57f7d596729fd36cbe2dc3855351d29dc4a90ed15ff56fd6fea033728b792ab1183f256f4304280a6041459cf3e6f67b86373d6e4bec24c6484c623721f39814f7ab9b41b0ce2a10a6bdbc16d0f6603a4b0c15b492dd147edbbb3cd16b9d461c2556cd4302dff6cd7ba49ab4c5f3e468b5569adbe825f835d9290467ca676e8e2ea39f1dc294d245771466cdc3546c0624a2d325be31fd9b5d6cdfee83414c334812883b50b6e68e3c8623d0fe6aa870ef8cc6015754b26cf8e215aca15de566a1cf0e9ac0f017fc5385f6873161c7cdaa3b77538dbb5ae5b74f28dfc76d6e0076523c91312b14d00e6c72ab2a16d0c46f6b5739a3b177cea1aac83de18861d4b1bafe05a11f1cd72972a8db708107cfeb0af3487cdf6528735cd20472c1d59d4d8f1ff4209165bd6a83a3819b94428cfbbfb80252a5891c75da8dd740dd53b8badf933662994154da3d0032bdcebaef3cfa3733ffa311dd21b7f7f2e207797deb1a884a1205c698d5ae5b8290c9471ceed6e6c079e0b4f85e98da71f0456a72fca9bd9d628d04e9af4a48f36345b40e585e0aa98d56c46e59612d8e54c397a06850c45c3051be842965eb9f23840f18ee68e27147a5efedbb04efe0937418da83cc0567a079b805d9b638d171a7c59843997ff23b71ea76ea6d6800eaff14d3f79b4165a22c6451ad1775fd4d26d722bf23f89fee41e312ea67679b1fb12ce5369b497262a1f271bcda2d8b84b17c57de10e2721dc36bac0cbd65b5f9376644d05d110561a00dc9f73a118f8b7bc5ae3c6536bae7ae50f220221c018eb59ac638ea67d7313fe05a2c460ec78ec1fca5b0daf64d4c4bb9a72cbf6be833a3b0b2668bb512c23aa5a8cb69c355e5e0e8d5d0f56bb3868029a33963f3bd54a22cddfecb7953d149acfcdf891b6b5515802e2b341d5b058e0e24d56549defc46bf686bc6fe41e1293f7dea651f9c7024bdebfd07b25b7fe9d1433c0c93188c4d56635d75a808a0e8896aab641b65ecad603341135b0b2f3a3b442e05e7a63befedb318467b2ca253f5bd3a72ac1fe96d7a8399e8e5f5baaaa2daf8798e7652e9e11f8f0f524a8161953d5721896c1806a2e245581dd941fd36674ac0beb499d3531155ff4fe0d20f461de9d964337cf3d6dfa698cbd8d731c91741b16f0a7b018a8f3f85a2d842d1caa900206db1de437e9925ee8ea5a0b63cd2d7fb16f358decba50a96160b52b37ef68a5ef127e7f7226d854dd9a6834d2346ce42b3214bf811823183f3bce29a0742bc573a50a950f17d924fa0152192d75027aea786510faa92fa84aa6d722a2230b297f3225a520b30a9c719a1ed90f1c41e0b857c79671d1c8e86d639517505a2d38d3d6ccfdb9cf0be4243edcf0bd9d9919ff3c1e1423587b86902b6b1b76e4c6801996135d3a5b12325a996971feb683407d29c778a0503df7ddca671ea0fb59d11d0cc0307fa4de218be33e88dec7f09231ad19bbef47a9968884db2b9269ac913dcedd940b1c3c556243184680339d304710414288abdc275f5d331dc0edf3ab16f486919ed31e9edb034ea7548d0093cbc255136f2bda7da0439f1392cc549dfe75586cdb78594cef6290c938aa07916c0312b51733f6f03b1c7d1068ba9fb6d003144f42d11f81618c601f6dbd903082b3aa57ad3ae70e32095f171b7135ac8b3add2620cf85c589fb513c4f0d0778ac8b895180ab9088eb270a2ddb28186c6a7715a004da3c73bba9b0301d0627a70229eb9322cd1bc705f54a1f7a778414f4b7510dddfa983a039e1f35e44611da8d5e362f94a8c5b1eb74360ae4f7a7fa0af058f75ee1fdf6844c43e374bdae0a0326d2996c735914cb999504b98ae3afeeca586dc66712fb5cacdedfc84b5fc2cd440e0e98a9b43807a67128bd8c4f473fcbc4b3515924e638d31db8368b06a1ac274ff1d88cd782337c8d13c3e4a706650ee60fda16e68ad2f012a56639ff3bee948229a4ed8d9c386e222223e4f32c02efd03009b0fbf87f63d798094ddb110f9471180732ed2a461cdc2647fd700c40446c1c60e2ad89da7a5df1917822b47b358092a2bb74628d0b251d52d41534aa1ad6e94ebb146fd01ccb98bf7185bfd8b03cdebc5a337cf813450cae2b75fe2cf53bea9b36071ff4b9fa31e1f24038fc7608ea85c6c3b82a84472fc0fcf682228465a07c7d32e8472ec21e0753539adf4885e88b1bdc3350138118c811a01ad8b224bf573095db46b4647dd23ac9030691f2930b097d8ec5dd100760d78d282354c618343787d24bdec98d94bcaf21ccd2983f1bcd16552c2a50253f8802ddc74ea576d7394758ac7217b42c46c076d68bfd316bef99b75e06a416efaa9597b1f085ac6f74cc6334f4708200c4cf3591d47f0f2349d4fea8e2e406987be467dcbe38ddc69127225d20957a15c981020fd96407f2768b2f03688b1c913d9f79fbd9f2886304da7654a180fed16df5011cf9667271813f73a4688b027f9e524698c2cbaa6a88f6e3e76a6c148bc06930fbcccb6782a2a4791242600950c371942d8bd2dc889606dd9515fdd31e146aa7c8ca5eb676717c58ef26112c127d36931d54ecbf4bef7a2f12aea92d47f98cc0dc4d281ede2170413a7898293f5eae5485ee18bac0fa0adf41e3dbafdefb9d9baea98cb05ecc6b633fbcf9282bb4dffe6f83c61655df8b489fb4c01db5f7e2690b255adf3c6e885599084b07c2514a723274817c1f43a9eea8d89e5770c75dba6e113b6eb2938e772ae5011007ac68d590074f3dcd0dcd7d66607dc6105f65dc98c974e07e388029e132231ba3ca3c3929ef1200454504e844c1967fd6c5fea75f01ef3bc5d64b2b8c1f2217bf3df18b7f0e5c4b29ff22f236f48e9bc20443cc75495e3011b66033d753970e28c4adae4607318ab0569c6ddfcbfbea5ee2322832b980bfef0a1db53fb02a2b0eb14c6176a62015852a72640d1bf6f6c542f7ee40ecdefa5d3acb97cddb170f1db88477068182e6be7206269247888df636da9b456f70590c09149bcbf46a19a9d3bc40996abe93b1d5f3dcb11b526ea1d2e959d5bd5437fa4cf91969adae1b0a097d4b17e7b98449f2a90cf905e3eeaa21426ef43224e1adfa70397b968b086613a03251962c98a0ee883329f02c7e859472dde1b90b17c0ff876213a2b02a8cc443ffea3b98cbdf501f3e3e065a2c5d024e7deac62f86af4be112e0c2e41977a2a34885d25ab9a930ceac1a8be6976d64d16d8f7ba2b18440fd9e3049320e24155f1964f8562c19ffd4e30137d0df78c914369c6cfa7fb3a34500ce9169074953563f9312b4c3fe4415159d65210cd379a5bfc6fd2af934b41367886cb30988aceb17be1331db76c60f96c2844989fb22047a619fca5d9434d25d70a1670d197f70c2c89684a98d3381a81123cfa247f4a35bd976852cd73d43a4d02e5a18af2db1a2374dee122147b825440736b4ba20e8d3d680dc8650ee5a9a8a9a301c2b17a1147e43fb585c32e2cda06ce3d54af93d022a4635cf25a4fb78249f0b25bc8ba2e8fb929885b9a19cb9fbd12a676313fd3edf4066b01a779190f4e648118ad0da745bd19017cc131305257f322f323b1f92aa8155829695dc9afe423a0c988765a8719d6f25df1571bd2543f6ba16b19311483a74c784b90b27ddb3b22d6064e4447182baf8dc307320f3029b20cbb8c8896c54226e0e85d4fd70067b0d854dfd5d25f82aeee8aef6e967b52e77caf4e2d93623c85cf63996d182bf5404d4a6ad89410e41775d0876a535c834f85ade195d0b00b462293316a9df7ee12dfc932fa7fc97f276ee49631067d06ccb97b2a260417a009b500958558bbbca05fb66776dc7d15293db5eb8d19df4f3373a6a17a6c3106652fe96751eaf492509f36c9658c35b2ccdad5886ee631cd2e58412a5e503fccdf4bb71771c0947f70db6388d35cb0038e98fe8b78edf81b51a6bacfcb40b93f8636cf07adc589f0f147a7446ff1d2022274ce3b89baf6df657de69aa0cd1c957d8c9f9de2f15ec2e0f7ff502368270a30276308c2f09d0f35de5d0c784c8c45c9482a1f789d021e325c3c8a18dae526ca06a6e6558c6c41fc8af0bdb17fc360cf744c4cd891805a92fe989e097d5ad743ddf07094129c0d1e503511d4f81190723f7956335c2d9110d24f22584b4c727560b83aabdcf961b690ba845788039718a4506dcd048e8dc2490ff6a88b9671d9398eebc8319797bda55d642bcba47f139a231d650101aad27b12f3c069358e6b82333bcac1dded6c23d8900930f2c5fc7be3edf64874de1141fcd391a2b917da0165ab0fef51d6730ae7cd9b9b1f3d0b55fcc72eb3e17b62debe56fe2e10127f3b046cfe373456b3360509b8328fc04d54606829576c5250462738984185b20a0b7f88023f3e7777c7ea62d1a41d364c533bfb2d12fa1cd0db92d5464ba8a38133367f515e4de7d424c586306d9ce22987b7247386b01022757f4648500f17e96149cf652c6c6a28fe9f85e045be8d9d66f92ff74229299049344cc223c6f1bd7d67761c9b93ea2d8c912d34ce9af9be5aae395f497c90a0af3b013a82b622b4942d4c5e76acb383740009874450f496f32cd7517be45ca289cf4b127c67cf0155168cdbad6fdad969ed7f1c8162ba8f5f89e3886b812f91e21f02ca64205417c15bdd1379eeb814083a3c32dc715c0747dbcef6dbdd7531d4deccac77bf29d1628280a89c4848c94eaddc3b36312fe2505b37a6d75fe81045025949fbc93a3326af3fd369d39fa6c009ca3471f1113847a3919b116bdb9077a09781a3a637599df7fcc98839e11c07e695d311bc51e6b8d64b55d2f170400e634e4979be229ad38ea5e2f128d1572a85cce10f271c414c04a306c6b92002a00e00825eb99906a26d1945eda3910b84502cd3482d0d84f5847932dcc4faf0bfb0c9f3bbbefce5991057908c42d2d5920d1757da51a12d9bd5d99790f76652c4307b7d0f927786d9e6cb6c57ebb44fc5d2b04c3359d3f4e3735a45861a3ca2859d4f4306d1843f79a332294a638cb1f76622e57d50558c1f22abd370503c903caa3f08dd93e5f82833de8e6d46a3341e7a8913f2a7e22e6643bc7c6538c8e0cbbf6fbf36164fe1b6f1145dcee45960273b2891250ed461e1ae1f23b19863c0ffe0810499d5b5be47ab8bc81ed7a2e004439eb823da19d539f8e7ac1659a92096441c33583ac9c5603ccb0d44c51fed6308f069da81382b1a1d74262f89cf328243fb2580e1a1abbbe2bed12ac80e361ca6a4123461a6d8efc5eb8672dddd22320ac7c5a087b21dd48e32e8ebdb4da050b93dd294e91d28a238b59d41d6265221ceddff0fc2a28de353b6c14fc5163ef26aaf67bc153eade50130c49c682e91851b297fb64d9d792b9c9c44a8a8bd2311db7cfad7090e8d1badfa6ac6a58a207f955c456cea50f9ebc0d7f95b4bd3347b211234a55c5c4bf20a183ac9b683719f208fc6b8cc67ecc372b325a4901678b2fb9288b4ff6601097abdc14df17010ca0147edd325f460457fb6ecccae55494c61cc30f5c29cf57a424147feb0b26195c0e3e739d3b3669af537c778a151926b774187ef6000f4d7349c6d5a248352efaab21ace4fcb78b5226827b068bcdda804f14b7fd86bdafd02c95fb60def714b6962ebdb37972973f9cac5db0d6bb9793fa68f19129a098bf9919df1f9f382df39520119d0fa7c8b262361a51fef9e5c0418b4af5c082b50dd95af82039f6049c751ab056b6ca7b13a1c1fbe61d36341c4df78ef722bc37a0635e42af44201d7951639b2fc9037432aff590c41fecc465cf82a10c7385f05e4ec18243106408c4fa61fa0ee08ccae97a0f104cc9c331fd87b786a8aaf813c05d187b3e30dc240b88f66c0b8d5c82efb9952183e37131290dac7ccd34bdf015214f933e275e03583c09916c1c6ca5a79acd3042fc82c1880dafdd9c00e1ff3ad410d8547c400d58dd99c637a8087117e36ea91e6812c6742e2d7250bf9ffedc435e6f79c9ee00de2aae6f0d19c82b5c99cdeac09f23d4e9e1dc20c1aa7c40a19b175c04ed182bf3b47f5dcdea54be39082d106621c59df843109a6883e4ca3949acc4e9754f103077d98bc264134bbbaf7e90d8d842a33578a7ad26a061c9ca6b77b3587dc826b783db0e3f346007f66f31f8612359a1aa251a23fb875f7d529bcf9223978716c7f5b8879fff558c3799d234346f05d7e80789d437b4cdd55c2be81353abec17abd7d2ecd9e1450ce944d03c9e6e517075a82ce5e4193844eac41f54abbef00f86aa9bd96eebbc4a7b67067fb9de593364457f94ffbdc8776b908b68b73c9c0850cc0dbd973ba25d515ee139f15fbfc0f125e1682f8f4d42b47f7c3281c2251f2eef4b2d676d4791b21a53a281ed28902f731d256e5edca72933b79053311513bb354296f2cc4c225fed68e505bf1430b1e5350b29049107ed15530da30d8a26863fadc7374c10adba56cfce0212cf3ef17d9021f63ffcd3de6b55b89f72a22c2b59e3d3a06970bb738b602390f6695fa876d376d9c0b845fe711a85e77afc2ba278b527ee921508d815f640ec09bc8d963a6aa450b1bda744f420a23e669d2df4d35f90eb8bba6771984c28fb5575cc5628cd6437a9172bf671d6197b224726dd1157e09bafb93f5e8daad3e37eac638fe47897bb1b8f476268e2f4783096133455ec390141a1bed6103851ed452c5969ef4765c5a24f4d17d1b3676e80dd2315c58cc3c2018a9e4dfa28d965895a1eb055c7fe41eabf03d3036be840abb61301d966663a812629391084a6b445fede42b562e60e0b74bd7b7f424474f87d02f3686c606b1a96da46917a8cb070f6867b4672311e248492072364ee5e70842f52ad47f0cbc0b018fb41ef8694d08f6f604f4ca40f578a7d0c561021ee8dd62b4605620eeef24fae8d03b5ab8ff013f7181b8db77f1fb03565bd5c9d896f66285ac0f3bf9b155ce499a793df6bb993d5aa821773b92854d96b59e91f212fee2c60be3b197bcf457faa4932500e94ed760070c26e49789a33186f5ffc99447f1676d9956e30b06c28f150456073c06cd17380311cdd6e542cfe862e3a00d27017b5827b442d3af40df6449ed4c04be82015ddc6ad04112ef5f062edda022e8909cedae081e8db20856c23c6baaeb42c2c5e7b0fe8abe6ec3980efb76912aa4309f135514e65c16895796e9b278a31a747ed20eb572ab82e1a49fd8ca60a98f823cf3344f17db432a8c2f9baa00be40038c98f7c11a1b2c414e67686b77720d8137f3272f6de98b68ca04b28d2396f5a2b6d894113b7f7af32aa77200688a6952583043ef8ff22e4c1e417c68648a3380691e1d9bf55db4533703448b331fc4b1e6dc67cd32bb0f26b5cc312fbc5a8eaefb7b10ae7cd03402aa9ac3825b597d62e10e39cd2a8fd4bf1517d37255560dc77db0ea2db7edfe9cc564d0fa22ced9d2d80ee077547db7160f90ee4e7fe9f1c3235acb8323abf43e2fcfc741d5f9a9819cca25bf68ec3235595d7f0d759d661253e9ef535ef4d8e4b0096e814e013921f749227303bc67bf6cefdf344692198576b1bc4356c73ccdfaabeedbf69abde2c462f80f1980015305e52b10707bad1889f5c39f736800aa51f1501d405b3732af595b49c48b4333f160b58b87ca84c910977c93aeea98a2362e4daef3ef63f08bc094cb1019eec6c1e9f2feb2bef068c5fc563a013950433c25e7e218b66051d5a44837375c1b83c9489efe3099f427c67bf0fefb25dfd8b626c48d00c7a4b1070504657a3b7ccf42af9dfa40e93afc0e3a5e2aa92e250f2145ea915abdb6a0b78fd055839c44b13e2fd7782d67e7a0ff4e1181b4bb64124543f5438702ee42d8d8dec996a95e84c8c9f1419c5bc66b34aef3700a67786714b6aad4147643c172c4a70c0e363781f8956e374b01f88f397750c374cd7d163919d877889bd5629aa9a70dac88464aeac5a0cd4906d60979ffc1e4626b0af9aa0a22e9d3966ac2609ada8891286e5fe76227c8b5b50a267171e1d256d6468ae45360978054ab41625cffa58eae964ada1e6369b9c8b2491d372aac40aff7443366aaf6679274f26d13c1d1fd13e2ebc731975b57be4c9eee4b6dc88445d8ffb0d6de2e69b8463129087d86aea27ccefc304326063c7972ba3e80553fac7c5c488ac4545f8ead0169bf87f01acf9353d0ed6fa6a55db96bd9e41ef8fb4f1c2628e86504987acd21b9af044c092f91ead0db66966546169c32b670bfeeba5746860f83ee005d0da01bda136cef67dd3e66a111bc90cd88056b1619d90c701fcb20a7a4ac33342950f6188bb0e7d4a788e1a24808954084e37d8377cef483a9a84490b46c95d10a82c27ec6acd7128da9cd8250a45fa24b5678e94a0eead4f51b62881505463237502442e915e71adedfb9f97115ac5d150170b2d572e067a92010f51c48168fa8005fd3192e9b838c58f31b3ecfbbb078e8639ee2f3a5dbeb8dfc5ffe1175b448c00e213d2ddcead739b4563a90f47b5fdfd45eefaf5dcec0768df8490020e69282377fb10343b5a8a221bb1fea3bf8fe84a790c1adeab68779614f29c283810200156b08e06521c126199dbb9ea2f2a6af5f5b7552e40ae1555c760930577969e22c7b04ea4e95901c650a73c988c618bead593d17d5007146ea9c47dc77d14ce0e03ee7b11ce3448fdbc534f42ef81bac3bb78c15b1b3a83d56b3f36d21b62d92510252201ab1927d4ba5dbaef0f3e1c095e8c52a019da94e3560e11a83205e4276ec3235751505050679851506af768f0cabdbd6571d0995bcad6e3f6c10f6a1e09368c3547f9ad262f12a9adf34939cea2d1154acf2aec479352ded626aaef25982e7552e667fc7e4e9e6fe330dfaa6ec83fca6b2604281666f3f99c32262905e6a7d5c87d6ccbf80260ab790e02fe7f51dc8071a5fe80eebdfa76a7c258961c401120d9f12b68c977423df5af18e93b2193e9b74fe53bbcda7468f342863e08310cbff5ea6c0ff558bb83aa2bc23e8df39b3383c6ae5f86c22845edb39b2a2953297894e3c2ad4e253dca273b043ab725f81833d327159207177c0b0ec96a2a9d9dd5834c42b493856edf49a3cbe2be99b4711f6bc83e57cd41137641847a04d4127ee7420f4b77460152b4d7aefd72c105f3b834dededbdecb89a1c4d2d22831a4928e242757e1f30360cb8c0501aa4642cf791ad9246a4a49bc712086c50cf0c0067bfc80c788d426bcfa946f8830771998880594658acedbd416087f731c2d9a1f721e273a548daa7078371b7f6196244479f11b24ebaa395631e9ef1f0ae2ef0548e857f2df929518a18b8a95717f00257f6c5f133ee95ca28b76febc122ab204fe89476d434759f23f70fb44b03b5ef93011c0c147acc417dbff7800172bee75bd52030baa9d42c0be98620037f763ea2b51bbf861b8f03a03eb2d030793cc0c782cd860d2e212b7de317c1687b3a7c3338926cce04b4a79562d77ad232eca3a2901fa6cd0fff130d3e55735b134c8022dcb25f8dd068d5d1874e3572012f7a4df16d20451fc0d48ffb0b844c34d578893abe54f5da62af0c4b597b51f8f652fb2d9440c9641bf27dda51477b9d902fe04f5be88f852c3558cb1a5fb03ae2d0635da9de9c58fed8a406dd3b2d99445a575fa3864f1d4c4351617617e1ed2bb4f656f1113aca5094ec20d755d1287fededfbec38fda5c26660a292656","public_inputs_hex":"0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a00000000000000000000000000000000ae6a85768f71c83f114b20d8a933586300000000000000000000000000000000ebd03ad97202d4bf5bf80bfeb5239fba1f8e48fdae937d71edfb5a4d694a7bb5a16a0c2ed1ab32e08dd664615f32513e0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}}}, + "integration_summary": { + "integration_test": "test_trbfv_actor", + "benchmark_config": { + "mode": "insecure", + "bfv_preset_subdir": "insecure-512", + "bfv_preset": "InsecureThreshold512", + "lambda": 2, + "proof_aggregation_enabled": true, + "multithread_concurrent_jobs": 13, + "committee_h": 2, + "committee_n": 3, + "committee_t": 1, + "nodes_spawned": 7, + "network_model": "in_process_bus", + "testmode_harness": true + }, + "proof_aggregation_enabled": true, + "dkg_fold_attestation_verifier": "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0", + "multithread": { "rayon_threads": 13, "max_simultaneous_rayon_tasks": 13, "cores_available": 14 }, + "operation_timings": [ + { "name": "CalculateDecryptionKey", "avg_seconds": 0.004105569, "runs": 3, "total_seconds": 0.012316708 }, + { "name": "CalculateDecryptionShare", "avg_seconds": 0.021735208, "runs": 3, "total_seconds": 0.065205626 }, + { "name": "CalculateThresholdDecryption", "avg_seconds": 0.021883708, "runs": 1, "total_seconds": 0.021883708 }, + { "name": "GenEsiSss", "avg_seconds": 0.006303152, "runs": 3, "total_seconds": 0.018909457 }, + { "name": "GenPkShareAndSkSss", "avg_seconds": 0.011035416, "runs": 3, "total_seconds": 0.03310625 }, + { "name": "NodeDkgFold/c2ab_fold", "avg_seconds": 19.281920111, "runs": 3, "total_seconds": 57.845760334 }, + { "name": "NodeDkgFold/c3a_fold", "avg_seconds": 72.091054403, "runs": 3, "total_seconds": 216.273163209 }, + { "name": "NodeDkgFold/c3ab_fold", "avg_seconds": 7.793962458, "runs": 3, "total_seconds": 23.381887375 }, + { "name": "NodeDkgFold/c3b_fold", "avg_seconds": 72.63518675, "runs": 3, "total_seconds": 217.90556025 }, + { "name": "NodeDkgFold/c4ab_fold", "avg_seconds": 8.064746388, "runs": 3, "total_seconds": 24.194239166 }, + { "name": "NodeDkgFold/node_fold", "avg_seconds": 18.46072318, "runs": 3, "total_seconds": 55.382169542 }, + { "name": "ZkDecryptedSharesAggregation", "avg_seconds": 1.575791792, "runs": 1, "total_seconds": 1.575791792 }, + { "name": "ZkDecryptionAggregation", "avg_seconds": 48.474341959, "runs": 1, "total_seconds": 48.474341959 }, + { "name": "ZkDkgAggregation", "avg_seconds": 5.560166834, "runs": 1, "total_seconds": 5.560166834 }, + { "name": "ZkDkgShareDecryption", "avg_seconds": 0.766792666, "runs": 6, "total_seconds": 4.600756 }, + { "name": "ZkNodeDkgFold", "avg_seconds": 107.170507639, "runs": 3, "total_seconds": 321.511522917 }, + { "name": "ZkNodesFoldStep", "avg_seconds": 5.213900541, "runs": 2, "total_seconds": 10.427801083 }, + { "name": "ZkPkAggregation", "avg_seconds": 0.397447291, "runs": 1, "total_seconds": 0.397447291 }, + { "name": "ZkPkBfv", "avg_seconds": 0.22172625, "runs": 3, "total_seconds": 0.665178752 }, + { "name": "ZkPkGeneration", "avg_seconds": 2.248425542, "runs": 3, "total_seconds": 6.745276626 }, + { "name": "ZkShareComputation", "avg_seconds": 2.503326757, "runs": 6, "total_seconds": 15.019960542 }, + { "name": "ZkShareEncryption", "avg_seconds": 3.921781749, "runs": 24, "total_seconds": 94.122761998 }, + { "name": "ZkThresholdShareDecryption", "avg_seconds": 3.427196402, "runs": 3, "total_seconds": 10.281589208 }, + { "name": "ZkVerifyShareDecryptionProofs", "avg_seconds": 0.154358833, "runs": 3, "total_seconds": 0.463076501 }, + { "name": "ZkVerifyShareProofs", "avg_seconds": 0.253084125, "runs": 5, "total_seconds": 1.265420625 } + ], + "operation_timings_total_seconds": 1116.245293753, + "operation_timings_metric": "tracked_job_wall", + "phase_timings": [ + { "label": "Starting trbfv actor test", "seconds": 0e-9, "metric": "wall_clock" }, + { "label": "Setup completed", "seconds": 0.968119167, "metric": "wall_clock" }, + { "label": "Committee Setup Completed", "seconds": 7.026030458, "metric": "wall_clock" }, + { "label": "Committee Finalization Complete", "seconds": 0.00505175, "metric": "wall_clock" }, + { "label": "Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)", "seconds": 122.805809, "metric": "wall_clock" }, + { "label": "ThresholdShares -> PublicKeyAggregated", "seconds": 135.105291709, "metric": "wall_clock" }, + { "label": "E3Request -> PublicKeyAggregated", "seconds": 135.613361792, "metric": "wall_clock" }, + { "label": "Application CT Gen", "seconds": 0.009316167, "metric": "wall_clock" }, + { "label": "Running FHE Application", "seconds": 0.000052625, "metric": "wall_clock" }, + { "label": "Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)", "seconds": 50.06342, "metric": "wall_clock" }, + { "label": "Ciphertext published -> PlaintextAggregated", "seconds": 53.769554292, "metric": "wall_clock" }, + { "label": "Entire Test", "seconds": 197.387759916, "metric": "wall_clock" } + ], + "folded_artifacts": { + "dkg_aggregator": { + "proof_hex": "0x0000000000000000000000000000000000000000000000050171e1c76882125000000000000000000000000000000000000000000000000cfdf1f1b488062f1e00000000000000000000000000000000000000000000000f962e434261b37a730000000000000000000000000000000000000000000000000002e0e72e3a7169000000000000000000000000000000000000000000000003632118af1fd3861600000000000000000000000000000000000000000000000f3be15fa21507e979000000000000000000000000000000000000000000000006da62c16a519156a00000000000000000000000000000000000000000000000000000ae34beccc39c00000000000000000000000000000000000000000000000c2d6c29afc67b101c000000000000000000000000000000000000000000000009cb8711b402b7afca00000000000000000000000000000000000000000000000433d081100331cf9900000000000000000000000000000000000000000000000000019240d6a5f208000000000000000000000000000000000000000000000007b680e3643ee08d4d00000000000000000000000000000000000000000000000db2f02967a31b6d1800000000000000000000000000000000000000000000000d8224e1aaf3cd44a90000000000000000000000000000000000000000000000000001e3e986df6e472a988fa1b94e96b9bcc842e1ec09ad2835ec6539b20a216d94832710f34e12a11bbedba09154d4bdb6ca8a864ed19ed0dab77199001fae75d996691767ea956b04a0389bce5a23d5fd869aaf9c5e5c443b43b84c5b41d4b2a0d90188989c511a145d2197e8a1f835404ae133ba729ff0f9e5db0e78f86e967e89a28eecd299702170e094855e18faf9b08036a4ab8cc8451b9e96d4a3e4ddb294ec58068c86cb28b5a272fe283333c466d2b063e406c9b5d5898942d5c60fcbf13a28f333c0172e75ee97db99d23fccf0100b7e768b832f63913b02f762a179772a656dd7f3eb102bf5c1f9a9bd5ca2c2ee9241a4d4088f679221c0288326ed6fb9262962ed1b10bae9d0f25b5935e7684a6e3749e9cab8e2c12d53e6d1d284267887e58c05da28603176d9f1ea891e633934fa4fca7ffc9161f5a3838dd02afd160b0233cc2f1985db340cca8b06e4ce20fb357bdb4ee18bd32fd75c0c529e114987992e62c31533f35e6e095dc8e36fd57bb8046002ae0471ec3fcde36bef53e375cd0f3e4f191a2188d3e9a6fb82792a50d4ff1360640275046de2c21d4f4a3577e8f79a8519b47cd6be30649c380eb4d735707b1c664f98421938cd63d5f656c6eef8048b3001073f0fb231803649f60355fc757e41658a95c817594e1dafd8c2691d24f00bf99821e74780d315f5c5ad75d8e983e6d5085993e102017a72b2fa266960920a8e7e77a2ee6d59d798f12d92b424782833dbc7d235ec3e43373ad3e404f1cb1e08a2bd553428c3accdeb393846323c7c78adaa32f740afcc9ac4d264b3ed09297b45a3413e22cc62390354d759b264a96544e1662be66950fd42c67f2dc79c046b48d8eaf419dd29c1de1171719708091ab038efedbcab7ce18f60d73cf851144e9914268e22dbed233813cbb531e7cc338776a52b34c5b445336a93a82a3505ee10cb945134e955f56c92798fcfacec8ab4312b370d08ba9e13c6822f7b2b251218642289c021af15cc46ee027d7b415eec7ac6d8701d066c7ea7fbad0fff1f44ed8fbfd3209ca7c67443b852e7eb2153ead095fca5a334f74adb331a85071d37e4d8fef5c820bebfb6f8ef7cbbe9e595b09b923eaa754d813eecb8b431b6252e189fa9fd09540008f1a366d44aec26b5f3d6b88219b8acc0132af1175d1303948e2483093e739c7657de30ffc650be6016e8b7b644f1706af4f10794917723b79318a87138a13ddb9ee54f5a386fd236ec981a583a22c69f30ddd9d7684e2cdd842c10629c9b803f04e709db227ac8c2618b2ab90b7e272e60602fea839906c91883e1ba386f54311b5f8dc3e654a0d4ec89e0e84c28bc6de587d46fcda612aa42f202b2336dee7da1bb663559552831351bd8506a5e95299a7305b38f87141a1d53d730ea5f7e8327f36f8046b96f06be138f225d542397e91de2db853c118243d8072071c8c2b6c9b8319b2364cf2058d3ae62883cd328faed3808687d1e6bcd832417a660a93375eb3b6949753531fbcaf3e9dfda64319654db11377d0d30a54dc8104f72b9ada7db131094a3d563bda7a350f045ba02572b53152c9f0b81b3d85c069c07f10b478b5e43103026fe9054094913d3939a7dfede87684e2ccd8b577e3eef430358e620b504e70597c6fdef4fafcba52e4ecb198fdd7d7e2ded4feaa5e0f4e46f5928eb7cbef54804310bb28444bdd8db0c2aba73c31c7019870268b2c4ef8557b3adea63df71d1ab57662ef45b9340068707f834268fe72215eb567a317d10a1184f97b55c41dedcb2b3fde60bf5b36f8db7ae9a86679e033d6ab5ae65925449813af86b5ddc4e84247246cc5979716414f6543895abac01e65a1745a512cfa85259e0704601b4e96f4fa2acb1810d93f6f5f7c3c3facd28d37db2dda672619c9a74af9fc8590f1e019816aed3efd4f2431c42aa49707f2bc202af6e47cd30525b3176d9f656c8f38188e47b4010e170a5c9540e8d446907662106b2f16ebaa6d3b31f76676b63b88f6b5f201fc55b64fd485a05dc54e82ea332f1cf2a5e4a3ba0fb92db8a4e2582d696f0e3e9544f1df54d2a150928a21c64166a1eee5a7acf0ca354f1ef2c597a915abf5eb1f2f17f4444a14ab73d25291fd606842f6d46c423a3d5002ad5d1d85e8f2d5aa6facf93d277e8ada5be2d281e1d086b9900f04949511c28d3e5e5c042336a9c38d499e0d9d4a0e22a011c2c1d46ab3419b71c538300bf07222fac1ee50f30f59fd1606b7a733cb89d47c01f240b094462a58c6a48f2f22ea0c311cf71059da4b6eccec988af99298b19851a03b84a54289cd63995596220af919f2ace0b6855f018780539198fa2b546722a38ca2bcc9ef20fe97d16857bc21184cb8c26ca77dd0a48d21e63a4d2e309941336a5aaf3f8d884fb066e1be202f0a5824698aedc16b097163316f2e9637c3e0b20b792a3ce06ffaccc8c01feb75db6c1a8a5f691fd6f0457b21d6f96014d97181c7e28a5e38a313ba81781b44d944fa5180921b4e3a685c67e7b5ba54522b12067ea024995c2b4d39a4378e235bc9617cd45226b0b462acc8268376f09ded9148ae0c2c54cb0572c7ceb489276b6f9865480d1328e52c20b2a87bb25f8f8fe19c2f1f9253a2f9d91ce5f306a71365388975e901501ed2061722b40b39cc5e126be39f84c67f5d309093a230fd41635b221b3a842bffc6c82b439bb4f30c82a0e455c77499e96fca527260c2387b5b33a342fb731983cf4493ce8616a7a53c020b4cc0c3be0b632c8ec769378bb66387a1f5aef060a93837742564a44d13f722b3c33c50977596828429b4d9cfd84efdebb1716ad8865c2bb0b7a428dbb76a510b3144751ed6f56f3e4a1725894ae0491db526f33ff61610340d0ae06c3c2090a090850b2deca290112c8c9ee587277a28c6783c18de6edb089175f09c0cba60ceb6596411449d0e45ac2e45a96fbccd16876400fe6be3abe02546874f1bb2c02ee37e4891c999df82ab2e71bdc4b8565e904d46de6572a8e13bbd57bbc7666076ab48a848eb008f5d150b8f34e2950e07418dcd2ae4d4618bbc20d3ef16d280e138a7bdbc01702cb05e90d7216c66cb9f4ddb7036ba9a8e490c2d6706f6ac61e64503d935535e808a69eaf53e3c6529734aaf10bf83f868f942f8532031fea1b8462e093707d67a47944a349411088c6642cd6a7686fef5a7e239b0697054c11236b5d3764b83f9a409821ce9b4b87bedd5ceb3f4fe6afe7a7c894738d1c35296c66c8d85376b5a864281a54897b64e90cc5bbf2778ab3edf83387c80734661b77c4e4eebdbefd15d57a22abfa5662ad616b857f09acc5f7c03503dd36f569035c3c9ff43a306932b0c6921ec3ab08210793ff101a1cdb4d52ada493df83561c674eaca29b3732bfeb35648633817b65654639049f14ed8eab71d7cadc6a472d72dedc4c511dfe6eec2d6f780d3cda952417d70927de7c890c822180b751cb22efb494f2c65804b31df2d6fc8b2e02b1c3da3f32183ebcab8662f9dec0b9db27970150805f57492628d4f2e5cefeca33c80f49d769038ecea2193dcf848bf626721a1fc9537290fccd8957f41fea37a04af789d5a699ec186f0c5195b9da3a0d289910128a71cc047bb54a1a2348c809d62257a294655ff515866421c786c31b60373c7229263449b97139a1e73d1632c5c655a5298e01e0d93090bd458b562571a3466918118d55c7653f72fabdbd090983f3d374b657938439592f27e63519b3836279b0887e21105c5b699c6402bf9926c8774566b8696178ca6e6019d60fa85a2daf85687adf80a426ac4b3280a35fa0a03fdf7caa03453744d3c95876267ae5a2ec7cd9bea56c9f4791aabb88c44f77aeb2be859b01c3e657343a1fbc0301584b569bb2677bfe761033251f642a36db5fe7a900eda00a899c6436b3552257ba5af5060156dc3cf16a744e6bb61f304c2e8b882dc5d920a2eae4e5d8930a12791bbc837f109d715e94b6f43c0ea0f912edfa65b296b79fd2fafb4eb80d294d411f94f57fa6561c81af4590e4f64e246346c585b9b1825e260618666d790d3976646b3eaed0b62adcf8ca1eaedaafa642b99b0c668fb2ca646cf83ac831284183eaf859b2dde29a5bc4ed0fe1ed9f3b3e4b66b5b1b1b8e2ccaceff284570e94b8e30962aa3f7834b8ba1ea36a8ae66af7c05c9f26ece5af36d3e62503790341dd82ae3f277043cdf576765127e8b1ef261938dad94d9253166b12e3012a098cd13cac7440a796ab7cdd143141d75646524728a119a9b8b7a6bad74992b229f1da3b792912490932d69dcda2f002679624dea63b05b8a626d29cf0a21e281008deaebe2011441e2251c4163f566316b754bd68de1e29d872314f14c98acf06c65072574039e59a4be896da9457287d943daa8124c8112cfd53d8416b5dbe2389f9b0e142bf22bb249b8a65aea8678c3f8e337d8d01cb053da0865c48b95c2a98cf96bf95776f89fe16e6e735b6ff6d77d65b19c713ad94b2d833e274b28a1d83ecb08d14c57a21c6fc084500a03f20d2f2f4e113c6234631c4a4c862c8452d8619e2fb00d51f4660d7eebe5d0b485331281e6e4fecab05ee5b39fd5a576007a02effe3276eb44bc256394bb45df037d31b8a03d4dbff274b7d4dff96796329900a5f0ddf1afc22b52b45204173e66c015f00c263df12c81244e6aa531df60424de20721c938a170a8ecae4ca005937a20beb47b21d5114dc6acf93ea1612242dc85ca47576a18571f7ac8619b4ed0fab62fbc14c988ea251c175ecbaba5a2120eaef75b4a23de5516c4409c15984f80e7a2754be08f8d8a586921d36da642bde79fe59910f9c9dd77ea3043601e017b911b2bf632d7638bfa2a0df8dc4a4158571fa1f23328c3780dbed7d136816beccfc88d346a328a9b5bfbeef4bc0ce04edc95d456661d0eb8b84b5f49bd166423dfe4e44d292b5c221b1a9249bcb09094fc663b9b1a33ac12f371616bc82907844262a4257f3b0f30494ec53318e4208e1927d77cae51515142b0379df332b1a69430dc6b1faac64d7d5c4ea9b87a71af3ad9c2c137e8f0720aa216af2f0869467dbaab2593db8e98a43a77e2c688e0f4ee2b6e37d294f473cd9933f3ddf4a6ed9b6c32bbc46c95db64abdc2c665b60f30f0494c32e794f78d06cc07204763c577e6ea2807cd9129ef13c0c63d564026df11741e1c38e336332e811beaf01a8336ce345ac7558d23ced7c63d4f7a6109116d2f26b10687f2fec3bdc80ab96f9d6cd940dbba2096f69f4cc07cf9b05007073bfce2438fdc73e5d2187e676f286fbee1c9ce169d1ca1bcc3a71d5b515a2cea999f3f4b8b2000e1944945a0ec5719f2ff71908c8903f2ab1ebf811139bc1ace82e5ed82e865146a52e18acc699d0583a4b0b8469387b04045acffcc9b8a1faaac1d47dbf656c92156fa8b864b34d75e6ef4e7dc75b031b2a6f48e9eaa2d2fb3c68e3adbb2caaf732d6f6ea726b8904a855196a864e5a2f835935b51efd00bcf1ff872cb1b4135fcdbd5d1e96a7a58df82a1a2ecfcbf69f5c0a9c093333417d3dd49754668e48b033d2dec98fa0a2adcffa47985e039acc5e49d12377a9f0271e8ebd87fb374d9f854def3b254c1495cd5722b58cb04b6da4484293adc012b3ba3498c119faaebc4d3d3e7b54bc4ed8b68415797a813ae76c4fc43a7818008ad9f53cb63132d925fc1f285b75966339371c9447b2c45f9610fab11b15598273da77731e94ebda44ee2fb236383a0a0deeaaa0ed802dad3b9cbf991474c9f012afcdb34fa6eddc42fb1d2599c2b38fc70c4baabf6d787bdea3ff8bc2cf9631517c0ddbdb7ee2e008622cbeddf715fdceff1bd1aa94a5a280b1308b9751304250c62c27c3989eac079c11f437c3414111356ea1d7987befc81438ae97b6b632e61faec19757d01bb5c31c78b0c90d26a3b71709ea3626198c5562241b226cb1157ee972eb53a12fb593b473df72aa843e1450832cfc721fd2fd7f037c1b6d4263a464d40a4302aa2495b9d9be79915f656fc201bfb43f1e6c11fe7acbaccf803259bcebde2dcc3056bcc63c53d6b292095447edfc39d783edaad8a5e798f1728c64ab0b1c0489089ea5b8ebc7b53209ca084d722795ba667a77ce7f6b45aaa17c68ebda1440c7545e684bbf9e648ce2fb4c2429968a2204695e3e28b1b6ae90b2837fddfb5e70cf62e75c6a0b446125f793cbfd4bdf28d9f6b99da1e276ec12f63b8210c9faaeaabff24bff05d89539e3d6753a5d63ac9c8d6a05482bfb13e0fc8f6a95809478289e225f918f6baf43748868b25d45f846e604fef59e5d00b109fbc8e63307141368905dc9d3d0d0cb3028d7f778215822a3fe943c1f746711fbd74bfe4b4189f88173b2223c3c0266b82b6ecdaba2542723592c530aaf2301a76a882bd71dff78c2d22603790c9650b2e1e1170d05125af5d0a319d745b2e149f60779eca2908fab92f744af749856fe553d3c6a29651aa82d2f1dc8743a8171861bca3e373e295d7ad740a458d2e648c1d0172b1fc6466fc2e6a67abb97712a837b4085cd6a5c5447ba344c977d514eec63dae387e57bbea863222aeae2f17c9f83f0915c8437b28107dd00705f2dcccbc6b5b86c6cf65e7b67229bf72ae1ab5db1316dd37ddc470c48ee9c01f73f4eb0a5a661939aababee0eb10cceb7f259142020f2f2c2cfdcf7e1a73a9788ed61dfc804d1be7e5d2a6c4697a5b1d8a0c647fe72135aebf86f18b0db90bb6bd0ccc896829725c28651d7e1307fcfcee2f4cf4809ab83585d0bdfcc0b7f11245df7eb373b7639e41cd6947e49dc05d1d24e93ae6b006bede35d521db286ea335822967251ca8b1e75fe98c6d323a52810912269918429ae971037503f97fc1930fbba65055167a1142c4029bbd13815d298a459d0d17f83607b8e553b645b928e12a5ba47c3a29411d4660bfd27b522d2238834c52fd7d29853a9e34abfb12528f33fb3d27618e6da73288e1a0ae3b9c011810f73a0e7f5e4a53700d0486e2c7b89210ee348db7ef440502b39a6cf72e127e0a7f12d0b42ebd927e5f3c91f306c2755a4d4870e0fd4145c4a868afae772138c4188bcc47eabb5c045ad1a6d677212baae9ef7ead5989fa664cf1afd35e2a0f79fecdbe7b8023c60ae6f6daea7891ca68e8e995afca7c1ef6a39f24711e02416e6b298dc891eb5a6f85afdd0a44d8a071b576fa14236debe858125378cf160831e632c434b386866c9f6ee7c589a9b181956360d998d1e2ee3cf4d79e832ea36e916003c90f97ff0487542b33d0332cf34ae74a654da9e4e5a40e8e9bdf1651b3d3197f8097eee61ed1d6425eb1975712095712a5c7038285ee4fd16be228d77c66915e9524b9b0cdcfaf9ecd26b4b3f10a4e425f44480cebd3003b70290bbc5398f1229c4a19810868a35504068ac01326812b8a0e9f665d9195d64bd42397b246030c014d748e4be99065f8ea3c72c983aab168cbb76a70e6a8760bda15d4d22844d77f4323526f30c54d604c493f223f4a341675b2696e4ed812bbd81516245b2e5c3879275d6e7a6cdbc6b978064be19dbbb1f656d4c803aab83786302a6b5a5a43a22f99887ea0a812fa8b51aa8637e5df1d7ed5cd318fc5d00766082bcc1def74470c7a872302bed39e8e051ebe2ff94c45217cf79b2a4615a41c126eae2b56037c4399d124d085ebb06d53917a7bd73c1413756a8a78125a64c4227444263469b7b5edb028c7b98d313831c93cbff689080d1bdb6f166644284b25e9704af7c3ad31b34253207d2064f36eb67cefe487b6fae26969b8289ca5290953c82bcd3454e8ba7bde204b4f5be3e8b5afeb15bd8e20986fcccb93d08e8825e988859679b51fa0f938c7476f55dc3929998d1761c7aa25e390caf801f8ff0fe2d77cd8755a04a4671dfb8d0ae1d2e917a66802e786425e13cd695a631705284bd012acd166ef99c75099b6f603dfde93e2623cf6e47753c76e2f3d8ce507298f3e71c7340938679cbfe5e5bc22a969f08c3372c9c084c2636a1cd76fb2e906095782c9c1a9643c968d0b146233a57ad730d77332c10c8167cb180dd3512c24a02e872ca9f98fbba84d23141cf5d66207f879a928bfcd22e5692396ddc80c2b9b1b8b50b8de8cece0a17d3c8ca30c36e9cdf045e4924494d6c99b29e929bc2d117ff452edfd85f7c4adcd9cbbc8a3ff76011351aecd157070ff978a6048dc08412b512073bb2152f681f316f1f0625fba865a9acdb19f3992e9fdca4189d520b9f5aa6e222057b464a80a4d04b2fc7b9f92a5a8667eab1faa27945e0081d61fdd29f1a7d5444f74f09a2f30044d16ef1bf6531a0ed6d1151cd35a1b6283c222185f0aff47c7e7a37a6fa0846c983103871dd1870824b8d18f2163da9bf2a70038b0facf58a67165abd01d21cf2429ec7153fac53e2b6e335142fd2cb3aaa02423e67047c73fc811b4ad3c8b452fe327d594d9e7e1d51417edef03990949db1f7e274080f76644ec70b2b6c05267ddb2d6c806e0966303c77105a1ff0aeba72558dac392c66ef60efd29a6357cc644348b8b9ce3c39243e41d3a107355ca050109fab6c07380c8ca191e908c144271b2b55a8490d28296b0bdaa34911268801aba316c2967dac2ada95da9e41c72427c498ea387de3d234e5d728959fcddec1d48b05c86337c38dc83ee23caa8079d5f809ab2d1f30dbfeaed4ea7e4b87fec0424d66e7ef425245355ba9994876e17000b875b53053eaf8f38e6937aa4f0ea2e8d25d8a5e2087be8f9392bd56e9d95520efbfecbe8d312e374bd8fb10a6dba08de8a096af917c4affc0b27e093ae6d1ed63b70b0b88dae467bcac39f7fc88c1a08ba9b1d4db0dc16e2df05e265019349f8c250b2966754bd3aee8abfc280bf03c7dcb8d5c003eb7afa191842ddffbbb7e624da7f397fe89f90b12d349826d807a2e3f357a0912d5af5b2273b32ec9974f43f163f2aff433cd805f30e26edf12f3a6d67ead33ad272e4908cf00568cfbc7ca9b12e9b15631814e547d6569d910866261e817e204b0410ba0fa7511d7878dbddd4e456b5aed444d8f730b5ced605209c97a9c9b775e9679c3664e2dd37ef7618fdac726bb36ac97ec093ce3a85241b49b290fee4fd53ecc38866dda42ad9e89d81512cd5482f6feba6b84d099f1e0d9d2544c2462149b6304394161e678132031158b1bd24066fd2e943adcb202d4136b5fce7facbab01cbdc9352aa2e773c8a40fa8fb735facfd70c685cb4941818959346ef51c68ebff31f6886fff418c58b64d22b17c70ede38ee5048c06e1c47d7159575e4b31acdf5e1132543dc1a394dde58683bf6839e222d0da5303e1eaf022ed8ff621c383856539f24839aa597a53329b6153c1c663d94558289991e0efd67c8971dfeeb6f36e712e835ca6d6b12cb8deb7a39e5686d0b7105d0f00aff977aaf69f9d045f19a01d2aeaa20d181dcf04f46f5557e34205686f4ef090aa0dc2f18d59f049b313b135c52f2a6276928cc0f11ab4948bb463b12ea9e3e2aacb661846247a5c3e3d349e822594b61dc48cdd93e68f559cf6d834acc90e728dd3288e94b99740ce069be51320defa30e03fb5799a33d7440673bb536d34817b1ded0cd3003019ab911bdf5d0384d48152312612aad122f8975d4b358bd2900dfb7e65ca31b2f7be187ef465777c278f670ddbd71deca7d5598a7b734913a13762531d2b2add16d5e37c92e7a1544011be58bca9f05750b4d86c9fd2abac413244404d2e8247dfab02c91ce8f4e6e0c9731cc82cded1c6527a844df0d6da324a192aeebcdd9f6bbe1db18a50813421271ed0678a8595c0bff9393ff84db4702f02eca84f25ca461eb06c310e1ecb75863860e47be4117884f075626c716af125b03ca92208379f81dcc34e4f41a414ab8b5edde232f8fc280ab049fd082fb2a8973bbc3e8fa46937704993202d184e17f80c74d3d66fdf28510fb1b1916ed1bc7414792af8f0bb1c5029dc468e3931fdcba416def99099cb00e85e695b28903636b366320015aeda121084dfb493171d0f84cc3708bb15a827b9f4f8af6782cf047a876096716594c6042e2c62770c37c86a6992e26561b4937be8deddf762235bd98c8a4abe96acd8f44943988932da6622c996564e8e4bd6d86044becb1005c7014222588fced532f040d85f21b694a4e940b7292545c9d7cc033b6ad4c1508dc7da02701d8d5c819deef613ac4d2f6170cab35ebbde63859a3f1a4397e24c51253418723f2a37e50d1cec94e0a1ea1e3f4b9ab19bcbb1fe320081e89f122d5592111cd83b86ca5d74db8aa45644280938af94f30c246de5a9e42a4e7c806aa4f6bbc0b40b66650fae09f068980329ee6ded77e255033c84f9fbe734bcd2bc175d335b3549a3567f0a5a242cee45c1d37f0dc7c0e091404b766ca4e37d40a3520a2538997773fad1285b4da877cff9e302bf838ba0dcef08c346bba42cf17e1addce3b129357a52ca15e1847649deb1725b35a6f92cb599de7ae5bfe1312cbc1e5327770be0eff878e8f1bde2a21467e5fbecab7290a1ede10b9df07eaf0b04d69ffbdaa12b51d1fa9522f982c4d89239d47f4b56ffbb8fd630b3e6636d257e22d3f31fd1f59eae4428b42fc9ccfac6cec11aff3ea7d88d37f45b013c340faf832ca6f3044dc026011db9172ebd8a50ab81f86db195239097ad5226b5fb07ae137250b94a651e40711a345ac56fdd076f56f9d2edad70356c1647853a562df655a338313805345bdc388451870364269856156ba27dbf9f013a86580a58275c3a0c96db3c6bd69e69c6627e8b37c77000cae86f388c855d88138a1d540510b7590554caf3b3ee1c4de0004826ded89c3c2d886255eb6c352df92ef402d404b008751a6219cea7831bbe590fb7484973247e7eed62a41fda7fe1b4c517852f9c46a3caa152a6ba19ed81d68060ab7de2ce648f2e959149627345df0af88013a778e50256572cd0f0db53e6bfbd0b265226056157d842adf904d66f68f5e82ffaf7d267bc206cf126453fbf97aadc413e8bfd0980f6d2e51fd12c6b8c450d22a7632ff78cda0c94ec01807bba33e809a36bf6d5c3e15a65d0380bfb5738f20fe99bcc5c24df1f7dfaaed12790f48d695d10fc94448aaa6483cfc44c668d2823977f80ca02bb04aa050e297c39a336ba8ab7392f3f0ea13924ba2e4cfe4c5320f0a6ad82e7eccc5de9b85d68ae340c4d1340b64fc691e2f6d976db379468c80f1a2f8ca7bd84540963fadc8241efac5f7808f44d7f7b65c84a9e597b4a8f820a8643ddc0b3bdc9b3ad0bb1c3af39bd93187e37b6adfc8acb7985898f3f7f08076f5a84e1f44007572f1cab6721c2d2e5ba74f0237b384b3d2f801cb2adacd71e00f0c0d1e7c25ef230bb81a52cfa718ab44ecaf68ae3cb224ccb24b78ab3f60e445b67fc38fb2b395346370197aaaac7517d2b2aeef97769479d46358d8b5f0737c3304ef4cb623a9edf6f53b433d4ba88f2a71de5a9560c0494de2cdb2be50b0b228b1051a2708fdc673fa6df41fbea855fac8594d675b7782b86d3fbe2d010a001a81c82e8de37b026d989c382b2a463ae5855553d2a2fd4fc239307dc2006cffd98ea7ea19c1ab6f29976568c0180742ceb1389f2b787525d75964aaacc03b7945f1be91dbe8b9671553c5390fc4e6b504216f535c8898e54e8343676c61faa9650f3b1ac01af6629a87cf78d157ebf2576dfd4035a5c94876d5c46051919c6574b57939fd6ae2fd2128fbcccaa43675804486b48088d076b167a6932c10094d9cd0a0d704ce50bf44c160e3a4dd947e18398f8951353bd2f7d10901fcc1e467e5ed14b5ff29adf1db4fa4c1ff120a9b6e96b2d96267b24de93e5b58a730355b647a71f8c66bcd9f005eae5f2621d4e95a0e8f0040dea08c5dabb08af7e06e3e7e082a4cd093c840486db4b508ee370979ec8e7556050b81517a42b7f5428e3e929a0b36862db159a17b53ed64e3b19824f29a4690b403e1a06aeccbfe523887a99b8bb389be92479bf4a88bad4e9fa0765e38cabe9b4cb0f8359ac291513e1ab0cbe99a58ba6fb01277bb092f76bf72ff69b056c808302a73c303dc03422672236fc9f0e0e3584834fb3e666af49172fccf5e62e37a5d8ef3c30eb7598053a03524e50e3629e114de48ff812d3ac27f69fab79374e24008af2c22ab922189f58e73e3e2d433cb8691dc28d394416c53adad6433b24c756158e5183a4c72b6217027bb06d3abac3724ff8f65085c9c274f4361f4ffa696c196a5ce5c06d015a4869aa4894f7f23c2c9b723dc88b32d23c7f7b17fe0d960e75d43247e3122149af32b83259e273124e2b7fbba33da026be409cd308e87b99fbd4dc4e3b1e2f82b41ef4d94c4833b737775282fd5879f57b19f814322fe572a1e83eff8e7c211aedfc9ad3826d4fd63e00ad3f6f5d7846c028f58bd97fcf048a65858a6f8d29d245380da910de6a206c761b8f6d9adff7ab770385fb81143e96c8b1b1b50d3038cb42e6627becb2b3f0e88797ec28531752945b90c789487c5d82b46de770143ddef2bd48fd0e0b784ce88b32b93672ff466514e73d0058366d015eec42d82ac2416739bc1d07425ff2cc7b40ca139ac01509eba5b9202e7e721a4e4d372e1e98d84308869f428f96548f633864a57b7eba50b38e021a6226e28072096f713051f0b0f6ccf473d4b76cd400ec3d2fde6d77af2fdbd7e813730995deb9066629002d655f6405da3e09e52f70fde13e5a8002f9984148df1c0ff041ce4a51150e7a76c3cd5eade0672438a5ea1d1dd22bf7a77b23ef9faf91d032eb18c6ccc507582531d1d7879ab921faf19cb135501352150dcaefcd82dc1ffef26d41ef2228297b04cc49e099ea7290257eb1683b9bdcd3bd34921f0ddc415d4e79498d580f340704eeb78eb63816c3bbcf6482e4c2ffeeb356cf808367622288839785f02da91875ebd91f8271b60ced8088c8c10e1591c64dc26baea11805b46580dd9f10a9102266062bee1e3e475b80079c900faf306e1eaf8f1aaf4484f0000ea75d17a0b8d9ac1d396615d1aca3af0b0a9f6a3d86f798679c129e6022522ac7785f06b97e54dda22274b7f6b28c57df7695ccba1d1edb1ae386e8167bd352b49b54168f0b01c77ef1e91baa5223e002ad97d1a77aa9c249dddda1aa025b72ed49a10ecd92d4b1ec8011ae096e6eef733c7e305304d9a68d74a7d8abbfbd3d41ab9d05d1fdf5080883cafe6fbbcc97a843626a9541efce71c8bb4a6b50323193a2002562b7a415d4de5baa9d5c72068d1442d7498990f218fc03b5ca506e154ef325120dab908552da646fc5d6c2d2978fb3cd67bbccc28980114d084481383b60ac18d9cf5316730c0a9d02e46596426e88c854b9898b7cf798420776e779e9c51a084aa19f2c753f3de4ac67e558a6427a04705884c183295ec6c48b9b6ffa67a4258ba74b690d12381bd1a4a887e0b231ee84077fe2797b23ea41290dedfbe00a2446b17ad57771abe27f3e448bb01b17f69e74a063a253c91ffd93726a7644b12442d70b8753689a11eb6de126041730be57e8f71dfb56179d1507ae113d480827bbebcc7ace9d7ad5a46ef018734d393e98333e8b9fd0f77317ea5bb2d594722e3e43c556d5088a6b27ff4adfc0c1384a87676bb2aa30217d642bd6dd2add260d88f99572949c86c1fa4a1332bcd3728986c45ab37c9ff6db79b662323341b9013fd43f11c15eca886b4d13c8500dc1d8df937dfb49156262a412654347dcf80afc2b5ad6847a049569a52d91a93b047a0cd0836e6c165a3337adcee9620a1f19a5d392987cbf44ed846c39e36581056a5bbce8d26af5f81f9f2cb1bd58b17501e80853d15b8f735eae9ab20741f04b36654b4eb0e485b28bf7786d4ca494872c8abeae9a358850bc62b4e248201f315885a1b3007d4ab32ce52b3f4fec9968137edcec321b6f4a62112e4787b2bfbd7602cc6005b7eb482de4aac41f4f3403042c688454034386ee1aab7ef75896beaef9e6d178f650dc211a4ec50aac20e43008a659f19ff1b3b52ba2a53e0d258633e091137c025085850a13db466755fd1a387fb0b270186e001651fb51e422f31710dfce6f3a56e94cde2e9290d0cd3d1aae40949d1b7cd01599182d3a7dcdb3ae8cc005e2a14e1b39df73084f84db292aff9b4cd5373cb5a58def79c64f8f9b124ded447ca83e959ddc955e02f5786c1257a84c5697dda550ad7c7fa446840f9c52aa3673788a425a8f39898b64223b03433f14358f511051ebef163691391a110b6b9f7700ea415e2fdfaae627af710e8fed12c0e416b4c0b58b67b6de9c7aa4f5f22177786fedf9f06ce3a94d21f5221bd8961a7e292e9cf231f57117b134f0a0760a6748d626834b1e96296635c430371dbdd772bc5fd6a3a8cc16a23a23ad590243e746fee1506a882c081eeb2d1806ec3878562fd5539690873f380628c189aabae6ecef7a59a33f069aaed9dd117596a9f33de6768546b01bf20b4caf6713d148cbad539fee2b5d69c7299e5c172c53a7974407ed9212b8abdc2f9137fb7c459806fabccb825f75c3c08c0dae23d223d74d5b5890fb1e84340b3916a7cdd466379302100aa313e76ad493093d1ea729f88743430d4b9de0c070ac5e69875be9fb9302edc0b8d623750b727137108494ca5bbe9dc5605496df7869a75af39b8003e759e2c02f8463f46e93ca04", + "public_inputs_hex": "0x25832c071d6d99ad42c7b885e48b10100726dc0de03c0a779b282c519ccf538a25fc312a5f0009edd084811b739bcbd529987df1cea36f5a2451538666257396000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a2208484402633db0cfcb2af11d3b66ff07cd7b6b12c3a35e9581183e399d53f70a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510fd2e0c74ac08efb87cf1059f1e30dcc9468113293de905e1b6098606e2dbcc3" + }, + "decryption_aggregator": { + "proof_hex": "0x0000000000000000000000000000000000000000000000032f917b0fd3ba7a530000000000000000000000000000000000000000000000035e7eee9919cfc781000000000000000000000000000000000000000000000004d01f8760c8703bfd00000000000000000000000000000000000000000000000000004d94ca153b600000000000000000000000000000000000000000000000061836908fc3b8f2a500000000000000000000000000000000000000000000000f58c698fe27f1c7ab00000000000000000000000000000000000000000000000c83238a843749bc86000000000000000000000000000000000000000000000000000212d3d108ebd200000000000000000000000000000000000000000000000ef8085780c77757ba00000000000000000000000000000000000000000000000c3c61f9d2347a2f550000000000000000000000000000000000000000000000019c6e6ab16a366da50000000000000000000000000000000000000000000000000000d7fc69b4d7cb000000000000000000000000000000000000000000000007eab1b3dcf475109c00000000000000000000000000000000000000000000000f3b81a7652ce16d66000000000000000000000000000000000000000000000000b7fbd961c0c8033300000000000000000000000000000000000000000000000000005047797e138f27e2b49d2890a1a1d7d9e9f9d5f8de1c723e2432ee10ddddd854082841a60a190d1e262fcb062cd02b7fd2f59f3a9a5270c713891c8e81a49fe088806914debc146279040a63dd82eb4ce9221aebb89787e802ddaa082e654c975d695db28095217de830d6428843cc068ed10d043596da999068b91711995406145a857879f61aac072ef64f542798bdbbbec186c9ddea949792d717af3f861c541f6d3329c8139a72a4c39e91ed9cc57640eda4f794c250d137a8490b015a87034b26243a7e2ec7f12931d3c8474fc12656898b4e3bf422912bdd4db5374ee12c8f096d74f824c025e27442c76ed1b51d39e2cf7034a4479893de172eb8b7294dc4e8d271a3231e7500f202e19d8877a126052f950431368cef6f95f062ced311b8ff6ea4a4149a4952e3d78ce456f6fe14a68b1e90adddacbbf08765d209dc70609ca6400a22b52ded226eb2c9968f70cc9e8d3ae84650a167b9c9f15c26049d55e1f4c1fa028ebcd480f734412ce5f3a2d710a6e77762d349254e59ea37ecb81347b5626e298a12385b87048dc8debad8f5b2908e0723855959723a666f21eca85d3bc8b00cd22a77a7e4e84a2b36db98f02f0eb833246fd103ab30983c6efd381068b8d71f3fbf5f01e7009b84cf9eb866f583ad0c6e4c1f1b9f457acbec88e87f5ad7642c0a219b76dbcfcdc79d797d9e36eb98bc85294d4e80f324c41aeb5d5c7e7a0024cb722fa8c2f51ebde20d08f7808d710737ca258f5d5a92b3502d21cf54b5a00f101276cd0fa6746fd15fb69b4c0e9c468793c3d9de7683305d1ac0139b3ab0101732e6eb2a8c4a782d8a4de7eec90b02a5c2d018de75c066c2494e6f51c6df134d8f766efbcf3ed54ecb62a51e4ceec128d2059759359397b487769861435d07dd738c9bfd93cdafc20a2bbfbff80b293523f1504d9eb4772de3a8799748ef0bcacec57d8ae3fc978ab8ffd64c15a20b4773db561a5a6bd51fb91ad9226911231fc9128b34c554eaf02080253b584e58ebd1cc6e6c976bd0ef8f993282680c187b610790b86b8eb17f5f46cc044b3bd1ff9adb80ca51ede5b36f46a9f62f1b1a89849470515f82eae676e8f251c869872d45d6aed4f38f7d2d0858bf1a4d93058186322e7ee8b79de71f366c9855390b46d2e6c5a6e3cf63fde1e851e03fb10b5b2399701861f4fd31c8bfd664c4c928f3413f55049a1d90c671e9a1614ee127e412345224047f85d7049836cfc6c9a331c14c1c0857dd0199a233c2d6392e1bc381eb283dd577441c23d64f5878e6d627ce803cca051052a1c74c8b66aa69162662c26b7c6664b363e0727e1e9844ce3d2662ab8fb678d1b192fef266bb0b1dfcc5caee4ca0fd5c615ed966245a26131a576c846c2475ba08597e43b5902e103e051dec1ac8f79d07c157ce88a7b2411788658e0df6dd5c23266a513e8b7a0db93f7d5689d0ca3b5c090b9258bd3a8cd939ceac84c1c2f61915d50904a9de29d376f9dd4674ed7e648efe0ce4c0e5634d8d90b6d1e569955fd105ff2751070c70d8bfc9e75ff4894afd01cc06dabca071edf803c9e8e1ce9637e0825ff5fb0305b5ca6feb8d9c1b0fe37be80ac5be9cdeef33956bdeee9d489a5e18f31b83265c9780c4ac8f0c6460997b3e829684c20823762e4850c2156c80ad47db73440f3887deb40f6d3eb415e4cf5a468ad78053028f2d41fa55af530a305d496a1902183d1853eaaa7e4d7470a5520f2142865d8575bb4d1116da36cad00fce14e000315b8a500a1a46059103ee9b2aa0d9a3a9deaaf941369b4b9d8b08ea36cd12179d921c8ffa4d2f47b68b438df65c265dcc076c2777f8611d75cbd6b1aca59119d3221631736761f87dc3fad1d9f71a4ea8ecfb742b1376c06cec1d524858892e1429670e288a4b876c12b4079cebe718f43fc9acf25e76662faba622d990ff214913406b10cd7b24a94127550adeded67a6d29e5600363f247650fa3bbf1650d9dc9af7da683071fd81e8950edec9bebdabe1f7cfe0195e098339f5bdf2a021d02d26abe670315342dd239fb6bf77024da51b7fe27526e111afa16b312bc0f009f4f13105af83dd8e15a51a81d2ead3d76f67962073d80ad460517b6444342298f836107bd20a98b029f5cdaadcd3918c2d9f1d2596d121dde8456565ec01b1db9eb5e4e16f246568c72c64a8ff78927b7ba1d22a89dc0415f084bf1a5c5e307d2fefe8c7c73dc9ca90b4fd975943518f3f9c1dfe083278ba5064e5ffb805d2bf413130a56e5a4a3eab4bad0dc4a5fdd4611ece922af711f0b99815012b2862d53fba4d59d04810bfda4945dd3c93229b1a143e5db3749c6fa8eb30ca3c6a313d74b0604a7f3fd97373f21d8235ce46c550cfa3c02f082ea381467461261022f035b91ad4e1fa0a244b68d9f81e6c2883473f7317cbc990ab7bb71f52630930b4f7231da195bd1bd644b5b2fe16173e5738fc7b368ba6f1014c055cafeefa21e4f186454ff08d1b64548b75dc5c7febb1c27ec3fc5bb59f5efdc25633386cd2fbd6acc0ce26ea7c11e8f2ff5c03cc27e6dde633edb6703664d9b25ede6297308b872b62066969fe13dffad85fb79b12a7f2ee224c2fd4e4cce55b45e4170c7125ed83804f3316f5c17470b160dde071c81d0e9d5e50f766fdf519bf945bd5921b8d4a8af0f1ee513b5d173b3b1ead3c348bd0038ed7b159be86de0109eb8082ad018b9f99c8d7eff3c28494bed4179c43636eb858bbb17987308b52bece0c10589dd01c8d6c6bce012ec221617cb673e673b8052e7e2254e9e08d84190c6c6258ee080fc0fbf163d24a91a2fc4208add9b98bef160bce94b7f6ea671407c150a42dad24823acbe16ab2537442d072a3f6c339581fd33a1749608fcba9193cd0339b24b250972378b10b92cc76c073072924728ee1f9c112abb15ad1e00396d060b30b0d3b8f3b09d8be157157e00d9bb6de1e8c4e899b78212151aaab332b504383516b0755074c07c61d550b5a354fd1204decf0b6d123acb7442f4925d18041a45eb9aec1f8a6edd6969bb0eaf06b2857963547d0ffd277173ee6a2ea831182263aa5773b19ea5cf9b871bc36a39ae544d732858f70057aa6ad36967f4613041fd1eca6bc20777d0a2e58598b67dc69eebb72d472c989d7604004de653ed0cd21ea34fd34c069dd87215a779a6a01d40d7b7333b8be940d34e3889bf96dc07149af5cbeb8494c5a7cceecdfa9ab4b9a7dc5101745b0876706a9f0fb1d05f16ebca6656b0a546606866f3493164c7c7d2617947d68e2c21c89df9e02b5e821c16f98ffb550e9eb98a1a926a7955b91366fa057df7a701e6b22becba0d5ee20388cdaeeeb6ce41b68cfe8b3d1c0d18948490c8f65bd028e3f8ac92f43f99001a8585ea21888777e6f4b0c393b95f64228971149dcd8ed62ac2245ec2453ec809a4c281ede4c0f8fead07d9c33e8fad95f36e6d71aadc7c2fcd88fcedf2c2780816bccb4df8d7a8a6b0a323a72954c8f469031663d7d150619ef3fe21ceb5de2793216c0e79a32438808983c1cceec67fc5b86965315828795a44245f82de0a1cccb11d340ed2183ead2c424b3fd032fdbdaf9e93b314d7de104100b508ef8b07f682297ad47f5a43693b375e85d181090fa4cbba644ab99bdb3aeee7cbe0a123b1680007468d2376fa4b087198a880b7d943122c64e2739285cb197ad6d87c0f8410a1295bff339df55e97c9e2869a3ad39ebee71f0442026725e13c7894701294e42521fbff09cc72bca14c6ee12055e93eb6a36c3dead6bae7ff69e214e5157a8f7b3ee1cc9a630892352325cdfe7f4673bf9b250f74b0d53a9ec62275ed08fa47c06229ee7065a4200e5d2de129180e4a3e2d896d322166a0dd71bc8ab00cae7d08c8e4ce746faa6ef6b7cedb1987db5a46bb1a78d01235dccf1967f4ce133d4a0e336c78fde09b78763813bfe420d501fa1bb77fd59dfb7e9a5df034a30286ebeffc596cc19e89ccedfa81795a7aebbcc9aba21dffc3e0245246f1099d1aaaa6598a814cd0d504a677008cb789c2eaf178e159f5c20aafb301b4f0e8df2479de0f3717d4e4ef7dc83d738610d2f9bcd50d73dbb619b8074f392837dae12bb62b06a460bc9beae70d089fc01a43d5b6c01d6ca2e3037adaf61eb04dc2ae27c47045ac7caf828a562ae12da800e7732b3bc8c550cf584f515f680fbb2b2f28fe7a9e126ac1e7262fc0c4c15a8524ffec6e26abdb450e445cb62a54df6120269fefb17a52977bc955fed6ffa537a1b1d8194c864fcf06ec5d6b129a2e319227a8fadd3a40dfa0d6819498951b4867672fc74428d26c7d490f3a2718ff46a029357e4d83809324bad732e822805a0136e3765feba528bceb2317fa20879da32961662f7a785dce16e500991e0b9c32f5e1a9b80300876499c96b3d3369232e22522f6faa2ef3d05f5fd66d54f0ff085ffff1777b5eedc80bd244a8247be09d299994111e6aa8d0b60c75a68fa4aec522abeaa11c977b175e7c7ccf154c0bcc19ac59eb945f924d1936e318d57d6418989e411ca5870b79984a5a54e32c1d18128c3ae13bf6ae39462c274431cfafdf4b5901872c1e7277a5f9e9833618290e0e06311671aa5e3416015247a0e2bac183c27dc687571b0b581dd3f6adb8962415c7097dc3d0f19f6ee891547d6a619bb3e3f1cf9bbaf99060d8556daef9b16b05416869515e72d011820ff51de020a7c702c7a7942be41bd5efd5e3e96dc3181c682616910eb09cedaee661f46ceb5918d74d23a760d7555a14bd4d012e90d713fb7320d715910b14bbe9439e621e34a1496e8b60e628c9dd5b7bc1115588c107eebb6e62f46011149032423e6ba742d8f8c8a0cf39605e7539f0f809646a3b25db17eaf635e9d1217fd85dfede27881235abe9479fb8ff0bd5be4af87059ae0b42476793bd6e018178fe9a74b84718d5bbbca46087842120e036b0bd3c578f1e76504ad8ef04a719ed739a9583fc3a4b9563d1904c92849a4be6c57f7d596729fd36cbe2dc3855351d29dc4a90ed15ff56fd6fea033728b792ab1183f256f4304280a6041459cf3e6f67b86373d6e4bec24c6484c623721f39814f7ab9b41b0ce2a10a6bdbc16d0f6603a4b0c15b492dd147edbbb3cd16b9d461c2556cd4302dff6cd7ba49ab4c5f3e468b5569adbe825f835d9290467ca676e8e2ea39f1dc294d245771466cdc3546c0624a2d325be31fd9b5d6cdfee83414c334812883b50b6e68e3c8623d0fe6aa870ef8cc6015754b26cf8e215aca15de566a1cf0e9ac0f017fc5385f6873161c7cdaa3b77538dbb5ae5b74f28dfc76d6e0076523c91312b14d00e6c72ab2a16d0c46f6b5739a3b177cea1aac83de18861d4b1bafe05a11f1cd72972a8db708107cfeb0af3487cdf6528735cd20472c1d59d4d8f1ff4209165bd6a83a3819b94428cfbbfb80252a5891c75da8dd740dd53b8badf933662994154da3d0032bdcebaef3cfa3733ffa311dd21b7f7f2e207797deb1a884a1205c698d5ae5b8290c9471ceed6e6c079e0b4f85e98da71f0456a72fca9bd9d628d04e9af4a48f36345b40e585e0aa98d56c46e59612d8e54c397a06850c45c3051be842965eb9f23840f18ee68e27147a5efedbb04efe0937418da83cc0567a079b805d9b638d171a7c59843997ff23b71ea76ea6d6800eaff14d3f79b4165a22c6451ad1775fd4d26d722bf23f89fee41e312ea67679b1fb12ce5369b497262a1f271bcda2d8b84b17c57de10e2721dc36bac0cbd65b5f9376644d05d110561a00dc9f73a118f8b7bc5ae3c6536bae7ae50f220221c018eb59ac638ea67d7313fe05a2c460ec78ec1fca5b0daf64d4c4bb9a72cbf6be833a3b0b2668bb512c23aa5a8cb69c355e5e0e8d5d0f56bb3868029a33963f3bd54a22cddfecb7953d149acfcdf891b6b5515802e2b341d5b058e0e24d56549defc46bf686bc6fe41e1293f7dea651f9c7024bdebfd07b25b7fe9d1433c0c93188c4d56635d75a808a0e8896aab641b65ecad603341135b0b2f3a3b442e05e7a63befedb318467b2ca253f5bd3a72ac1fe96d7a8399e8e5f5baaaa2daf8798e7652e9e11f8f0f524a8161953d5721896c1806a2e245581dd941fd36674ac0beb499d3531155ff4fe0d20f461de9d964337cf3d6dfa698cbd8d731c91741b16f0a7b018a8f3f85a2d842d1caa900206db1de437e9925ee8ea5a0b63cd2d7fb16f358decba50a96160b52b37ef68a5ef127e7f7226d854dd9a6834d2346ce42b3214bf811823183f3bce29a0742bc573a50a950f17d924fa0152192d75027aea786510faa92fa84aa6d722a2230b297f3225a520b30a9c719a1ed90f1c41e0b857c79671d1c8e86d639517505a2d38d3d6ccfdb9cf0be4243edcf0bd9d9919ff3c1e1423587b86902b6b1b76e4c6801996135d3a5b12325a996971feb683407d29c778a0503df7ddca671ea0fb59d11d0cc0307fa4de218be33e88dec7f09231ad19bbef47a9968884db2b9269ac913dcedd940b1c3c556243184680339d304710414288abdc275f5d331dc0edf3ab16f486919ed31e9edb034ea7548d0093cbc255136f2bda7da0439f1392cc549dfe75586cdb78594cef6290c938aa07916c0312b51733f6f03b1c7d1068ba9fb6d003144f42d11f81618c601f6dbd903082b3aa57ad3ae70e32095f171b7135ac8b3add2620cf85c589fb513c4f0d0778ac8b895180ab9088eb270a2ddb28186c6a7715a004da3c73bba9b0301d0627a70229eb9322cd1bc705f54a1f7a778414f4b7510dddfa983a039e1f35e44611da8d5e362f94a8c5b1eb74360ae4f7a7fa0af058f75ee1fdf6844c43e374bdae0a0326d2996c735914cb999504b98ae3afeeca586dc66712fb5cacdedfc84b5fc2cd440e0e98a9b43807a67128bd8c4f473fcbc4b3515924e638d31db8368b06a1ac274ff1d88cd782337c8d13c3e4a706650ee60fda16e68ad2f012a56639ff3bee948229a4ed8d9c386e222223e4f32c02efd03009b0fbf87f63d798094ddb110f9471180732ed2a461cdc2647fd700c40446c1c60e2ad89da7a5df1917822b47b358092a2bb74628d0b251d52d41534aa1ad6e94ebb146fd01ccb98bf7185bfd8b03cdebc5a337cf813450cae2b75fe2cf53bea9b36071ff4b9fa31e1f24038fc7608ea85c6c3b82a84472fc0fcf682228465a07c7d32e8472ec21e0753539adf4885e88b1bdc3350138118c811a01ad8b224bf573095db46b4647dd23ac9030691f2930b097d8ec5dd100760d78d282354c618343787d24bdec98d94bcaf21ccd2983f1bcd16552c2a50253f8802ddc74ea576d7394758ac7217b42c46c076d68bfd316bef99b75e06a416efaa9597b1f085ac6f74cc6334f4708200c4cf3591d47f0f2349d4fea8e2e406987be467dcbe38ddc69127225d20957a15c981020fd96407f2768b2f03688b1c913d9f79fbd9f2886304da7654a180fed16df5011cf9667271813f73a4688b027f9e524698c2cbaa6a88f6e3e76a6c148bc06930fbcccb6782a2a4791242600950c371942d8bd2dc889606dd9515fdd31e146aa7c8ca5eb676717c58ef26112c127d36931d54ecbf4bef7a2f12aea92d47f98cc0dc4d281ede2170413a7898293f5eae5485ee18bac0fa0adf41e3dbafdefb9d9baea98cb05ecc6b633fbcf9282bb4dffe6f83c61655df8b489fb4c01db5f7e2690b255adf3c6e885599084b07c2514a723274817c1f43a9eea8d89e5770c75dba6e113b6eb2938e772ae5011007ac68d590074f3dcd0dcd7d66607dc6105f65dc98c974e07e388029e132231ba3ca3c3929ef1200454504e844c1967fd6c5fea75f01ef3bc5d64b2b8c1f2217bf3df18b7f0e5c4b29ff22f236f48e9bc20443cc75495e3011b66033d753970e28c4adae4607318ab0569c6ddfcbfbea5ee2322832b980bfef0a1db53fb02a2b0eb14c6176a62015852a72640d1bf6f6c542f7ee40ecdefa5d3acb97cddb170f1db88477068182e6be7206269247888df636da9b456f70590c09149bcbf46a19a9d3bc40996abe93b1d5f3dcb11b526ea1d2e959d5bd5437fa4cf91969adae1b0a097d4b17e7b98449f2a90cf905e3eeaa21426ef43224e1adfa70397b968b086613a03251962c98a0ee883329f02c7e859472dde1b90b17c0ff876213a2b02a8cc443ffea3b98cbdf501f3e3e065a2c5d024e7deac62f86af4be112e0c2e41977a2a34885d25ab9a930ceac1a8be6976d64d16d8f7ba2b18440fd9e3049320e24155f1964f8562c19ffd4e30137d0df78c914369c6cfa7fb3a34500ce9169074953563f9312b4c3fe4415159d65210cd379a5bfc6fd2af934b41367886cb30988aceb17be1331db76c60f96c2844989fb22047a619fca5d9434d25d70a1670d197f70c2c89684a98d3381a81123cfa247f4a35bd976852cd73d43a4d02e5a18af2db1a2374dee122147b825440736b4ba20e8d3d680dc8650ee5a9a8a9a301c2b17a1147e43fb585c32e2cda06ce3d54af93d022a4635cf25a4fb78249f0b25bc8ba2e8fb929885b9a19cb9fbd12a676313fd3edf4066b01a779190f4e648118ad0da745bd19017cc131305257f322f323b1f92aa8155829695dc9afe423a0c988765a8719d6f25df1571bd2543f6ba16b19311483a74c784b90b27ddb3b22d6064e4447182baf8dc307320f3029b20cbb8c8896c54226e0e85d4fd70067b0d854dfd5d25f82aeee8aef6e967b52e77caf4e2d93623c85cf63996d182bf5404d4a6ad89410e41775d0876a535c834f85ade195d0b00b462293316a9df7ee12dfc932fa7fc97f276ee49631067d06ccb97b2a260417a009b500958558bbbca05fb66776dc7d15293db5eb8d19df4f3373a6a17a6c3106652fe96751eaf492509f36c9658c35b2ccdad5886ee631cd2e58412a5e503fccdf4bb71771c0947f70db6388d35cb0038e98fe8b78edf81b51a6bacfcb40b93f8636cf07adc589f0f147a7446ff1d2022274ce3b89baf6df657de69aa0cd1c957d8c9f9de2f15ec2e0f7ff502368270a30276308c2f09d0f35de5d0c784c8c45c9482a1f789d021e325c3c8a18dae526ca06a6e6558c6c41fc8af0bdb17fc360cf744c4cd891805a92fe989e097d5ad743ddf07094129c0d1e503511d4f81190723f7956335c2d9110d24f22584b4c727560b83aabdcf961b690ba845788039718a4506dcd048e8dc2490ff6a88b9671d9398eebc8319797bda55d642bcba47f139a231d650101aad27b12f3c069358e6b82333bcac1dded6c23d8900930f2c5fc7be3edf64874de1141fcd391a2b917da0165ab0fef51d6730ae7cd9b9b1f3d0b55fcc72eb3e17b62debe56fe2e10127f3b046cfe373456b3360509b8328fc04d54606829576c5250462738984185b20a0b7f88023f3e7777c7ea62d1a41d364c533bfb2d12fa1cd0db92d5464ba8a38133367f515e4de7d424c586306d9ce22987b7247386b01022757f4648500f17e96149cf652c6c6a28fe9f85e045be8d9d66f92ff74229299049344cc223c6f1bd7d67761c9b93ea2d8c912d34ce9af9be5aae395f497c90a0af3b013a82b622b4942d4c5e76acb383740009874450f496f32cd7517be45ca289cf4b127c67cf0155168cdbad6fdad969ed7f1c8162ba8f5f89e3886b812f91e21f02ca64205417c15bdd1379eeb814083a3c32dc715c0747dbcef6dbdd7531d4deccac77bf29d1628280a89c4848c94eaddc3b36312fe2505b37a6d75fe81045025949fbc93a3326af3fd369d39fa6c009ca3471f1113847a3919b116bdb9077a09781a3a637599df7fcc98839e11c07e695d311bc51e6b8d64b55d2f170400e634e4979be229ad38ea5e2f128d1572a85cce10f271c414c04a306c6b92002a00e00825eb99906a26d1945eda3910b84502cd3482d0d84f5847932dcc4faf0bfb0c9f3bbbefce5991057908c42d2d5920d1757da51a12d9bd5d99790f76652c4307b7d0f927786d9e6cb6c57ebb44fc5d2b04c3359d3f4e3735a45861a3ca2859d4f4306d1843f79a332294a638cb1f76622e57d50558c1f22abd370503c903caa3f08dd93e5f82833de8e6d46a3341e7a8913f2a7e22e6643bc7c6538c8e0cbbf6fbf36164fe1b6f1145dcee45960273b2891250ed461e1ae1f23b19863c0ffe0810499d5b5be47ab8bc81ed7a2e004439eb823da19d539f8e7ac1659a92096441c33583ac9c5603ccb0d44c51fed6308f069da81382b1a1d74262f89cf328243fb2580e1a1abbbe2bed12ac80e361ca6a4123461a6d8efc5eb8672dddd22320ac7c5a087b21dd48e32e8ebdb4da050b93dd294e91d28a238b59d41d6265221ceddff0fc2a28de353b6c14fc5163ef26aaf67bc153eade50130c49c682e91851b297fb64d9d792b9c9c44a8a8bd2311db7cfad7090e8d1badfa6ac6a58a207f955c456cea50f9ebc0d7f95b4bd3347b211234a55c5c4bf20a183ac9b683719f208fc6b8cc67ecc372b325a4901678b2fb9288b4ff6601097abdc14df17010ca0147edd325f460457fb6ecccae55494c61cc30f5c29cf57a424147feb0b26195c0e3e739d3b3669af537c778a151926b774187ef6000f4d7349c6d5a248352efaab21ace4fcb78b5226827b068bcdda804f14b7fd86bdafd02c95fb60def714b6962ebdb37972973f9cac5db0d6bb9793fa68f19129a098bf9919df1f9f382df39520119d0fa7c8b262361a51fef9e5c0418b4af5c082b50dd95af82039f6049c751ab056b6ca7b13a1c1fbe61d36341c4df78ef722bc37a0635e42af44201d7951639b2fc9037432aff590c41fecc465cf82a10c7385f05e4ec18243106408c4fa61fa0ee08ccae97a0f104cc9c331fd87b786a8aaf813c05d187b3e30dc240b88f66c0b8d5c82efb9952183e37131290dac7ccd34bdf015214f933e275e03583c09916c1c6ca5a79acd3042fc82c1880dafdd9c00e1ff3ad410d8547c400d58dd99c637a8087117e36ea91e6812c6742e2d7250bf9ffedc435e6f79c9ee00de2aae6f0d19c82b5c99cdeac09f23d4e9e1dc20c1aa7c40a19b175c04ed182bf3b47f5dcdea54be39082d106621c59df843109a6883e4ca3949acc4e9754f103077d98bc264134bbbaf7e90d8d842a33578a7ad26a061c9ca6b77b3587dc826b783db0e3f346007f66f31f8612359a1aa251a23fb875f7d529bcf9223978716c7f5b8879fff558c3799d234346f05d7e80789d437b4cdd55c2be81353abec17abd7d2ecd9e1450ce944d03c9e6e517075a82ce5e4193844eac41f54abbef00f86aa9bd96eebbc4a7b67067fb9de593364457f94ffbdc8776b908b68b73c9c0850cc0dbd973ba25d515ee139f15fbfc0f125e1682f8f4d42b47f7c3281c2251f2eef4b2d676d4791b21a53a281ed28902f731d256e5edca72933b79053311513bb354296f2cc4c225fed68e505bf1430b1e5350b29049107ed15530da30d8a26863fadc7374c10adba56cfce0212cf3ef17d9021f63ffcd3de6b55b89f72a22c2b59e3d3a06970bb738b602390f6695fa876d376d9c0b845fe711a85e77afc2ba278b527ee921508d815f640ec09bc8d963a6aa450b1bda744f420a23e669d2df4d35f90eb8bba6771984c28fb5575cc5628cd6437a9172bf671d6197b224726dd1157e09bafb93f5e8daad3e37eac638fe47897bb1b8f476268e2f4783096133455ec390141a1bed6103851ed452c5969ef4765c5a24f4d17d1b3676e80dd2315c58cc3c2018a9e4dfa28d965895a1eb055c7fe41eabf03d3036be840abb61301d966663a812629391084a6b445fede42b562e60e0b74bd7b7f424474f87d02f3686c606b1a96da46917a8cb070f6867b4672311e248492072364ee5e70842f52ad47f0cbc0b018fb41ef8694d08f6f604f4ca40f578a7d0c561021ee8dd62b4605620eeef24fae8d03b5ab8ff013f7181b8db77f1fb03565bd5c9d896f66285ac0f3bf9b155ce499a793df6bb993d5aa821773b92854d96b59e91f212fee2c60be3b197bcf457faa4932500e94ed760070c26e49789a33186f5ffc99447f1676d9956e30b06c28f150456073c06cd17380311cdd6e542cfe862e3a00d27017b5827b442d3af40df6449ed4c04be82015ddc6ad04112ef5f062edda022e8909cedae081e8db20856c23c6baaeb42c2c5e7b0fe8abe6ec3980efb76912aa4309f135514e65c16895796e9b278a31a747ed20eb572ab82e1a49fd8ca60a98f823cf3344f17db432a8c2f9baa00be40038c98f7c11a1b2c414e67686b77720d8137f3272f6de98b68ca04b28d2396f5a2b6d894113b7f7af32aa77200688a6952583043ef8ff22e4c1e417c68648a3380691e1d9bf55db4533703448b331fc4b1e6dc67cd32bb0f26b5cc312fbc5a8eaefb7b10ae7cd03402aa9ac3825b597d62e10e39cd2a8fd4bf1517d37255560dc77db0ea2db7edfe9cc564d0fa22ced9d2d80ee077547db7160f90ee4e7fe9f1c3235acb8323abf43e2fcfc741d5f9a9819cca25bf68ec3235595d7f0d759d661253e9ef535ef4d8e4b0096e814e013921f749227303bc67bf6cefdf344692198576b1bc4356c73ccdfaabeedbf69abde2c462f80f1980015305e52b10707bad1889f5c39f736800aa51f1501d405b3732af595b49c48b4333f160b58b87ca84c910977c93aeea98a2362e4daef3ef63f08bc094cb1019eec6c1e9f2feb2bef068c5fc563a013950433c25e7e218b66051d5a44837375c1b83c9489efe3099f427c67bf0fefb25dfd8b626c48d00c7a4b1070504657a3b7ccf42af9dfa40e93afc0e3a5e2aa92e250f2145ea915abdb6a0b78fd055839c44b13e2fd7782d67e7a0ff4e1181b4bb64124543f5438702ee42d8d8dec996a95e84c8c9f1419c5bc66b34aef3700a67786714b6aad4147643c172c4a70c0e363781f8956e374b01f88f397750c374cd7d163919d877889bd5629aa9a70dac88464aeac5a0cd4906d60979ffc1e4626b0af9aa0a22e9d3966ac2609ada8891286e5fe76227c8b5b50a267171e1d256d6468ae45360978054ab41625cffa58eae964ada1e6369b9c8b2491d372aac40aff7443366aaf6679274f26d13c1d1fd13e2ebc731975b57be4c9eee4b6dc88445d8ffb0d6de2e69b8463129087d86aea27ccefc304326063c7972ba3e80553fac7c5c488ac4545f8ead0169bf87f01acf9353d0ed6fa6a55db96bd9e41ef8fb4f1c2628e86504987acd21b9af044c092f91ead0db66966546169c32b670bfeeba5746860f83ee005d0da01bda136cef67dd3e66a111bc90cd88056b1619d90c701fcb20a7a4ac33342950f6188bb0e7d4a788e1a24808954084e37d8377cef483a9a84490b46c95d10a82c27ec6acd7128da9cd8250a45fa24b5678e94a0eead4f51b62881505463237502442e915e71adedfb9f97115ac5d150170b2d572e067a92010f51c48168fa8005fd3192e9b838c58f31b3ecfbbb078e8639ee2f3a5dbeb8dfc5ffe1175b448c00e213d2ddcead739b4563a90f47b5fdfd45eefaf5dcec0768df8490020e69282377fb10343b5a8a221bb1fea3bf8fe84a790c1adeab68779614f29c283810200156b08e06521c126199dbb9ea2f2a6af5f5b7552e40ae1555c760930577969e22c7b04ea4e95901c650a73c988c618bead593d17d5007146ea9c47dc77d14ce0e03ee7b11ce3448fdbc534f42ef81bac3bb78c15b1b3a83d56b3f36d21b62d92510252201ab1927d4ba5dbaef0f3e1c095e8c52a019da94e3560e11a83205e4276ec3235751505050679851506af768f0cabdbd6571d0995bcad6e3f6c10f6a1e09368c3547f9ad262f12a9adf34939cea2d1154acf2aec479352ded626aaef25982e7552e667fc7e4e9e6fe330dfaa6ec83fca6b2604281666f3f99c32262905e6a7d5c87d6ccbf80260ab790e02fe7f51dc8071a5fe80eebdfa76a7c258961c401120d9f12b68c977423df5af18e93b2193e9b74fe53bbcda7468f342863e08310cbff5ea6c0ff558bb83aa2bc23e8df39b3383c6ae5f86c22845edb39b2a2953297894e3c2ad4e253dca273b043ab725f81833d327159207177c0b0ec96a2a9d9dd5834c42b493856edf49a3cbe2be99b4711f6bc83e57cd41137641847a04d4127ee7420f4b77460152b4d7aefd72c105f3b834dededbdecb89a1c4d2d22831a4928e242757e1f30360cb8c0501aa4642cf791ad9246a4a49bc712086c50cf0c0067bfc80c788d426bcfa946f8830771998880594658acedbd416087f731c2d9a1f721e273a548daa7078371b7f6196244479f11b24ebaa395631e9ef1f0ae2ef0548e857f2df929518a18b8a95717f00257f6c5f133ee95ca28b76febc122ab204fe89476d434759f23f70fb44b03b5ef93011c0c147acc417dbff7800172bee75bd52030baa9d42c0be98620037f763ea2b51bbf861b8f03a03eb2d030793cc0c782cd860d2e212b7de317c1687b3a7c3338926cce04b4a79562d77ad232eca3a2901fa6cd0fff130d3e55735b134c8022dcb25f8dd068d5d1874e3572012f7a4df16d20451fc0d48ffb0b844c34d578893abe54f5da62af0c4b597b51f8f652fb2d9440c9641bf27dda51477b9d902fe04f5be88f852c3558cb1a5fb03ae2d0635da9de9c58fed8a406dd3b2d99445a575fa3864f1d4c4351617617e1ed2bb4f656f1113aca5094ec20d755d1287fededfbec38fda5c26660a292656", + "public_inputs_hex": "0x15c9b404c344691839abf638a132bd083b09e98c2fadb268923013737d217ad40488f1f8d24b90d2ff437809f7199eccdee54180e24fbab6e8d07e4dae7c77480000000000000000000000000000000013b99c18c1efae3fcbc5f8b9dcd77ecb000000000000000000000000000000006299bc4e3cf25377465649e9913a757a00000000000000000000000000000000ae6a85768f71c83f114b20d8a933586300000000000000000000000000000000ebd03ad97202d4bf5bf80bfeb5239fba1f8e48fdae937d71edfb5a4d694a7bb5a16a0c2ed1ab32e08dd664615f32513e0b7850853da4f6de0abb227f35ba4fc88c9701f647ee43a716dcd01fdd540f0a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a9dc790b726d4b30e4d8865f33f50004a47a309fa92e169d5ad235f41eb12542c77628973a693c21303168ba71bde796957f944c3a3494bbdb558527b5ba0c6071f98da6c5d2594c5ec88e9d1b4b90759aa7be42eea0aae2489f0b863dfba9b1cfb95c79fb965b14ddeae2ac0ae58e6f2b8af40f21222f9a964c0e33eafa2510000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + }, "test_exit_code": { "crisp": 1, "folded_export": 0, diff --git a/circuits/benchmarks/results_insecure_minimum/integration_summary.json b/circuits/benchmarks/results_insecure_minimum/integration_summary.json index aeb07b29bb..0bcb12e14c 100644 --- a/circuits/benchmarks/results_insecure_minimum/integration_summary.json +++ b/circuits/benchmarks/results_insecure_minimum/integration_summary.json @@ -50,7 +50,7 @@ "name": "GenPkShareAndSkSss", "avg_seconds": 0.011035416, "runs": 3, - "total_seconds": 0.033106250 + "total_seconds": 0.03310625 }, { "name": "NodeDkgFold/c2ab_fold", @@ -72,9 +72,9 @@ }, { "name": "NodeDkgFold/c3b_fold", - "avg_seconds": 72.635186750, + "avg_seconds": 72.63518675, "runs": 3, - "total_seconds": 217.905560250 + "total_seconds": 217.90556025 }, { "name": "NodeDkgFold/c4ab_fold", @@ -84,7 +84,7 @@ }, { "name": "NodeDkgFold/node_fold", - "avg_seconds": 18.460723180, + "avg_seconds": 18.46072318, "runs": 3, "total_seconds": 55.382169542 }, @@ -110,7 +110,7 @@ "name": "ZkDkgShareDecryption", "avg_seconds": 0.766792666, "runs": 6, - "total_seconds": 4.600756000 + "total_seconds": 4.600756 }, { "name": "ZkNodeDkgFold", @@ -132,7 +132,7 @@ }, { "name": "ZkPkBfv", - "avg_seconds": 0.221726250, + "avg_seconds": 0.22172625, "runs": 3, "total_seconds": 0.665178752 }, @@ -178,7 +178,7 @@ "phase_timings": [ { "label": "Starting trbfv actor test", - "seconds": 0E-9, + "seconds": 0e-9, "metric": "wall_clock" }, { @@ -193,12 +193,12 @@ }, { "label": "Committee Finalization Complete", - "seconds": 0.005051750, + "seconds": 0.00505175, "metric": "wall_clock" }, { "label": "Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall)", - "seconds": 122.805809000, + "seconds": 122.805809, "metric": "wall_clock" }, { @@ -223,7 +223,7 @@ }, { "label": "Aggregator P4: Aggregation pending -> PlaintextAggregated (wall)", - "seconds": 50.063420000, + "seconds": 50.06342, "metric": "wall_clock" }, { diff --git a/circuits/benchmarks/results_insecure_minimum/report.md b/circuits/benchmarks/results_insecure_minimum/report.md index d44ad5a4d3..6a141124dc 100644 --- a/circuits/benchmarks/results_insecure_minimum/report.md +++ b/circuits/benchmarks/results_insecure_minimum/report.md @@ -13,194 +13,205 @@ Settings for this benchmark run (integration test + Nargo circuit benches on the ### Integration test (`test_trbfv_actor`) -| Setting | Value | -|---------|-------| -| Benchmark mode | `insecure` | -| BFV preset (artifacts) | `insecure-512` | -| BFV preset (enum) | `InsecureThreshold512` | -| λ (smudging / error) | 2 | -| Nodes spawned (builder) | 7 | -| Network model | `in_process_bus` | -| Testmode harness | true | -| `proof_aggregation_enabled` | true | -| `BENCHMARK_MULTITHREAD_JOBS` (max concurrent ZK jobs) | 13 | -| Rayon worker threads | 13 | -| CPU cores (host) | 14 | -| `dkg_fold_attestation_verifier` (EIP-712) | `0x7969c5eD335650692Bc04293B07F5BF2e7A673C0` | -| Verbose logging (`run_benchmarks.sh --verbose`) | false | +| Setting | Value | +| ----------------------------------------------------- | -------------------------------------------- | +| Benchmark mode | `insecure` | +| BFV preset (artifacts) | `insecure-512` | +| BFV preset (enum) | `InsecureThreshold512` | +| λ (smudging / error) | 2 | +| Nodes spawned (builder) | 7 | +| Network model | `in_process_bus` | +| Testmode harness | true | +| `proof_aggregation_enabled` | true | +| `BENCHMARK_MULTITHREAD_JOBS` (max concurrent ZK jobs) | 13 | +| Rayon worker threads | 13 | +| CPU cores (host) | 14 | +| `dkg_fold_attestation_verifier` (EIP-712) | `0x7969c5eD335650692Bc04293B07F5BF2e7A673C0` | +| Verbose logging (`run_benchmarks.sh --verbose`) | false | ### Hardware & software (Nargo / Barretenberg host) -| | | -|--|--| -| **CPU** | Apple M4 Pro | -| **CPU cores** | 14 | -| **RAM** | 48.00 GB | -| **OS** | Darwin | -| **Architecture** | arm64 | -| **Nargo** | nargo version = 1.0.0-beta.16 noirc version = 1.0.0-beta.16+2d46fca7203545cbbfb31a0d0328de6c10a8db95 (git version hash: 2d46fca7203545cbbfb31a0d0328de6c10a8db95, is dirty: false) | -| **Barretenberg** | 3.0.0-nightly.20260102 | +| | | +| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **CPU** | Apple M4 Pro | +| **CPU cores** | 14 | +| **RAM** | 48.00 GB | +| **OS** | Darwin | +| **Architecture** | arm64 | +| **Nargo** | nargo version = 1.0.0-beta.16 noirc version = 1.0.0-beta.16+2d46fca7203545cbbfb31a0d0328de6c10a8db95 (git version hash: 2d46fca7203545cbbfb31a0d0328de6c10a8db95, is dirty: false) | +| **Barretenberg** | 3.0.0-nightly.20260102 | --- ## Audit status -> **Incomplete on-chain verify gas:** 1 of 3 artifact verify-gas values are **N/A**. Re-run `./run_benchmarks.sh` and ensure `extract_crisp_verify_gas.sh` completes (CRISP test + `test_trbfv_actor` + EVM replay). Calldata gas alone is not sufficient for audit sign-off. +> **Incomplete on-chain verify gas:** 1 of 3 artifact verify-gas values are **N/A**. Re-run +> `./run_benchmarks.sh` and ensure `extract_crisp_verify_gas.sh` completes (CRISP test + +> `test_trbfv_actor` + EVM replay). Calldata gas alone is not sufficient for audit sign-off. --- ## Measurement methodology -| Metric kind | Source | Meaning | Do **not** use for | -|-------------|--------|---------|-------------------| -| **wall_clock** | `test_trbfv_actor` phase timers / HLC event span | End-to-end wait in the in-process test harness | Production WAN latency; per-node deployment cost | -| **isolated_nargo** | `benchmark_circuit.sh` per circuit | Single `bb prove` on oracle witness, one circuit at a time | Full protocol pipeline (different witness path) | -| **tracked_job_wall** | `MultithreadReport` per `ComputeRequest` | Wall time of each job on the shared Rayon pool (≤ `BENCHMARK_MULTITHREAD_JOBS` concurrent) | End-to-end time — **sums exceed wall clock** when jobs overlap | +| Metric kind | Source | Meaning | Do **not** use for | +| -------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | +| **wall_clock** | `test_trbfv_actor` phase timers / HLC event span | End-to-end wait in the in-process test harness | Production WAN latency; per-node deployment cost | +| **isolated_nargo** | `benchmark_circuit.sh` per circuit | Single `bb prove` on oracle witness, one circuit at a time | Full protocol pipeline (different witness path) | +| **tracked_job_wall** | `MultithreadReport` per `ComputeRequest` | Wall time of each job on the shared Rayon pool (≤ `BENCHMARK_MULTITHREAD_JOBS` concurrent) | End-to-end time — **sums exceed wall clock** when jobs overlap | -**Harness limits (integration):** all ciphernodes share one process and bus (`network_model: in_process_bus`); sortition registers extra nodes; `testmode_*` enabled; proof aggregation always enabled. Compare runs only with the same `benchmark_mode`, committee, `BENCHMARK_MULTITHREAD_JOBS`, commit, and hardware. +**Harness limits (integration):** all ciphernodes share one process and bus +(`network_model: in_process_bus`); sortition registers extra nodes; `testmode_*` enabled; proof +aggregation always enabled. Compare runs only with the same `benchmark_mode`, committee, +`BENCHMARK_MULTITHREAD_JOBS`, commit, and hardware. --- + ## Protocol Summary ### Circuit Benchmarks (isolated Nargo + Barretenberg) Single-circuit `bb prove` on the benchmark oracle witness (not the integration actor pipeline). -| Circuit | Constraints | Prove (s) | Verify (ms) | Proof (KB) | -|---------|-------------|-----------|-------------|------------| -| C0 | 6847 | 0.12 | 24.93 | 15.88 | -| C1 | 53485 | 0.33 | 25.36 | 15.88 | -| C2a | 41244 | 0.31 | 26.14 | 15.88 | -| C2b | 79591 | 0.49 | 24.71 | 15.88 | -| C3a | 120114 | 0.56 | 25.48 | 15.88 | -| C3b | 120114 | 0.56 | 25.48 | 15.88 | -| C4a | 62750 | 0.34 | 25.38 | 15.88 | -| C4b | 62750 | 0.34 | 25.38 | 15.88 | -| C5 | 21501 | 0.21 | 25.77 | 15.88 | -| user_data_encryption | 53732 | 0.33 | 24.50 | 15.88 | -| C6 | 86929 | 0.51 | 25.71 | 15.88 | -| C7 | 90889 | 0.48 | 25.61 | 15.88 | +| Circuit | Constraints | Prove (s) | Verify (ms) | Proof (KB) | +| -------------------- | ----------- | --------- | ----------- | ---------- | +| C0 | 6847 | 0.12 | 24.93 | 15.88 | +| C1 | 53485 | 0.33 | 25.36 | 15.88 | +| C2a | 41244 | 0.31 | 26.14 | 15.88 | +| C2b | 79591 | 0.49 | 24.71 | 15.88 | +| C3a | 120114 | 0.56 | 25.48 | 15.88 | +| C3b | 120114 | 0.56 | 25.48 | 15.88 | +| C4a | 62750 | 0.34 | 25.38 | 15.88 | +| C4b | 62750 | 0.34 | 25.38 | 15.88 | +| C5 | 21501 | 0.21 | 25.77 | 15.88 | +| user_data_encryption | 53732 | 0.33 | 24.50 | 15.88 | +| C6 | 86929 | 0.51 | 25.71 | 15.88 | +| C7 | 90889 | 0.48 | 25.61 | 15.88 | ### Artifacts | Artifact | Proof size | Public input size | Verify gas | Calldata gas | Total gas | -|----------|------------|-------------------|------------|--------------|-----------| -| Π_DKG | 10.69 KB | 0.38 KB | 3119663 | 175176 | 3294839 | -| Π_user | 15.88 KB | 0.12 KB | N/A | 170236 | N/A | -| Π_dec | 10.69 KB | 3.56 KB | 3674782 | 188436 | 3863218 | +| -------- | ---------- | ----------------- | ---------- | ------------ | --------- | +| Π_DKG | 10.69 KB | 0.38 KB | 3119663 | 175176 | 3294839 | +| Π_user | 15.88 KB | 0.12 KB | N/A | 170236 | N/A | +| Π_dec | 10.69 KB | 3.56 KB | 3674782 | 188436 | 3863218 | ### Role / Phase / Activity -| Role | Phase | Activity | Metric | Duration | Proof size | Bandwidth | -|------|-------|----------|--------|----------|------------|-----------| -| Each ciphernode | P1 | one-time DKG participation (test harness) | wall_clock | 135.11 s | 127.00 KB | 128.06 KB | -| Aggregator | P2 | C5 + Π_DKG fold (aggregator span) | wall_clock | 122.81 s | 10.69 KB | 11.06 KB | -| User | P3 | per user input | isolated_nargo | 0.66 s | 15.88 KB | 16.00 KB | -| Each ciphernode | P4 | per computation output (C6) | isolated_nargo | 0.51 s | 15.88 KB | 16.06 KB | -| Aggregator | P4 | C7 + Π_dec fold (full publish→aggregate) | wall_clock | 53.77 s | 10.69 KB | 14.25 KB | -| Aggregator | P4 | C7 + fold only (pending→plaintext span) | wall_clock | 50.06 s | 10.69 KB | 14.25 KB | +| Role | Phase | Activity | Metric | Duration | Proof size | Bandwidth | +| --------------- | ----- | ----------------------------------------- | -------------- | -------- | ---------- | --------- | +| Each ciphernode | P1 | one-time DKG participation (test harness) | wall_clock | 135.11 s | 127.00 KB | 128.06 KB | +| Aggregator | P2 | C5 + Π_DKG fold (aggregator span) | wall_clock | 122.81 s | 10.69 KB | 11.06 KB | +| User | P3 | per user input | isolated_nargo | 0.66 s | 15.88 KB | 16.00 KB | +| Each ciphernode | P4 | per computation output (C6) | isolated_nargo | 0.51 s | 15.88 KB | 16.06 KB | +| Aggregator | P4 | C7 + Π_dec fold (full publish→aggregate) | wall_clock | 53.77 s | 10.69 KB | 14.25 KB | +| Aggregator | P4 | C7 + fold only (pending→plaintext span) | wall_clock | 50.06 s | 10.69 KB | 14.25 KB | -_P2 **tracked_job_wall** sum (ZkDkgAggregation + ZkPkAggregation, parallelizable): **5.96 s** — not comparable to P2 wall_clock row above._ +_P2 **tracked_job_wall** sum (ZkDkgAggregation + ZkPkAggregation, parallelizable): **5.96 s** — not +comparable to P2 wall_clock row above._ ## Integration test (`test_trbfv_actor`) ### End-to-end phase timings (integration test) -| Phase | Metric | Duration (s) | -|-------|--------|---------------| -| Starting trbfv actor test | `wall_clock` | 0.00 | -| Setup completed | `wall_clock` | 0.97 | -| Committee Setup Completed | `wall_clock` | 7.03 | -| Committee Finalization Complete | `wall_clock` | 0.01 | -| Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall) | `wall_clock` | 122.81 | -| ThresholdShares -> PublicKeyAggregated | `wall_clock` | 135.11 | -| E3Request -> PublicKeyAggregated | `wall_clock` | 135.61 | -| Application CT Gen | `wall_clock` | 0.01 | -| Running FHE Application | `wall_clock` | 0.00 | -| Aggregator P4: Aggregation pending -> PlaintextAggregated (wall) | `wall_clock` | 50.06 | -| Ciphertext published -> PlaintextAggregated | `wall_clock` | 53.77 | -| Entire Test | `wall_clock` | 197.39 | +| Phase | Metric | Duration (s) | +| ------------------------------------------------------------------ | ------------ | ------------ | +| Starting trbfv actor test | `wall_clock` | 0.00 | +| Setup completed | `wall_clock` | 0.97 | +| Committee Setup Completed | `wall_clock` | 7.03 | +| Committee Finalization Complete | `wall_clock` | 0.01 | +| Aggregator P2: PkAggregation pending -> PublicKeyAggregated (wall) | `wall_clock` | 122.81 | +| ThresholdShares -> PublicKeyAggregated | `wall_clock` | 135.11 | +| E3Request -> PublicKeyAggregated | `wall_clock` | 135.61 | +| Application CT Gen | `wall_clock` | 0.01 | +| Running FHE Application | `wall_clock` | 0.00 | +| Aggregator P4: Aggregation pending -> PlaintextAggregated (wall) | `wall_clock` | 50.06 | +| Ciphertext published -> PlaintextAggregated | `wall_clock` | 53.77 | +| Entire Test | `wall_clock` | 197.39 | ### Multithread job timings (`tracked_job_wall`) -| Name | Avg (s) | Runs | Total (s) | -|------|---------|------|-----------| -| CalculateDecryptionKey | 0.00 | 3 | 0.01 | -| CalculateDecryptionShare | 0.02 | 3 | 0.07 | -| CalculateThresholdDecryption | 0.02 | 1 | 0.02 | -| GenEsiSss | 0.01 | 3 | 0.02 | -| GenPkShareAndSkSss | 0.01 | 3 | 0.03 | -| NodeDkgFold/c2ab_fold | 19.28 | 3 | 57.85 | -| NodeDkgFold/c3a_fold | 72.09 | 3 | 216.27 | -| NodeDkgFold/c3ab_fold | 7.79 | 3 | 23.38 | -| NodeDkgFold/c3b_fold | 72.64 | 3 | 217.91 | -| NodeDkgFold/c4ab_fold | 8.06 | 3 | 24.19 | -| NodeDkgFold/node_fold | 18.46 | 3 | 55.38 | -| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | -| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | -| ZkDkgAggregation | 5.56 | 1 | 5.56 | -| ZkDkgShareDecryption | 0.77 | 6 | 4.60 | -| ZkNodeDkgFold | 107.17 | 3 | 321.51 | -| ZkNodesFoldStep | 5.21 | 2 | 10.43 | -| ZkPkAggregation | 0.40 | 1 | 0.40 | -| ZkPkBfv | 0.22 | 3 | 0.67 | -| ZkPkGeneration | 2.25 | 3 | 6.75 | -| ZkShareComputation | 2.50 | 6 | 15.02 | -| ZkShareEncryption | 3.92 | 24 | 94.12 | -| ZkThresholdShareDecryption | 3.43 | 3 | 10.28 | -| ZkVerifyShareDecryptionProofs | 0.15 | 3 | 0.46 | -| ZkVerifyShareProofs | 0.25 | 5 | 1.27 | - -Sum of tracked job wall time: **1116.25 s** — **not** end-to-end latency (jobs run in parallel up to `BENCHMARK_MULTITHREAD_JOBS`). +| Name | Avg (s) | Runs | Total (s) | +| ----------------------------- | ------- | ---- | --------- | +| CalculateDecryptionKey | 0.00 | 3 | 0.01 | +| CalculateDecryptionShare | 0.02 | 3 | 0.07 | +| CalculateThresholdDecryption | 0.02 | 1 | 0.02 | +| GenEsiSss | 0.01 | 3 | 0.02 | +| GenPkShareAndSkSss | 0.01 | 3 | 0.03 | +| NodeDkgFold/c2ab_fold | 19.28 | 3 | 57.85 | +| NodeDkgFold/c3a_fold | 72.09 | 3 | 216.27 | +| NodeDkgFold/c3ab_fold | 7.79 | 3 | 23.38 | +| NodeDkgFold/c3b_fold | 72.64 | 3 | 217.91 | +| NodeDkgFold/c4ab_fold | 8.06 | 3 | 24.19 | +| NodeDkgFold/node_fold | 18.46 | 3 | 55.38 | +| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | +| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | +| ZkDkgAggregation | 5.56 | 1 | 5.56 | +| ZkDkgShareDecryption | 0.77 | 6 | 4.60 | +| ZkNodeDkgFold | 107.17 | 3 | 321.51 | +| ZkNodesFoldStep | 5.21 | 2 | 10.43 | +| ZkPkAggregation | 0.40 | 1 | 0.40 | +| ZkPkBfv | 0.22 | 3 | 0.67 | +| ZkPkGeneration | 2.25 | 3 | 6.75 | +| ZkShareComputation | 2.50 | 6 | 15.02 | +| ZkShareEncryption | 3.92 | 24 | 94.12 | +| ZkThresholdShareDecryption | 3.43 | 3 | 10.28 | +| ZkVerifyShareDecryptionProofs | 0.15 | 3 | 0.46 | +| ZkVerifyShareProofs | 0.25 | 5 | 1.27 | + +Sum of tracked job wall time: **1116.25 s** — **not** end-to-end latency (jobs run in parallel up to +`BENCHMARK_MULTITHREAD_JOBS`). ### NodeDkgFold sub-steps (`tracked_job_wall`, per fold prove) -| Step | Avg (s) | Runs | Total (s) | -|------|---------|------|-----------| -| c2ab_fold | 19.28 | 3 | 57.85 | -| c3a_fold | 72.09 | 3 | 216.27 | -| c3ab_fold | 7.79 | 3 | 23.38 | -| c3b_fold | 72.64 | 3 | 217.91 | -| c4ab_fold | 8.06 | 3 | 24.19 | -| node_fold | 18.46 | 3 | 55.38 | +| Step | Avg (s) | Runs | Total (s) | +| --------- | ------- | ---- | --------- | +| c2ab_fold | 19.28 | 3 | 57.85 | +| c3a_fold | 72.09 | 3 | 216.27 | +| c3ab_fold | 7.79 | 3 | 23.38 | +| c3b_fold | 72.64 | 3 | 217.91 | +| c4ab_fold | 8.06 | 3 | 24.19 | +| node_fold | 18.46 | 3 | 55.38 | ### Aggregation jobs (`tracked_job_wall`) -| Operation | Avg (s) | Runs | Total (s) | -|-----------|---------|------|-----------| -| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | -| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | -| ZkDkgAggregation | 5.56 | 1 | 5.56 | -| ZkNodeDkgFold | 107.17 | 3 | 321.51 | -| ZkPkAggregation | 0.40 | 1 | 0.40 | +| Operation | Avg (s) | Runs | Total (s) | +| ---------------------------- | ------- | ---- | --------- | +| ZkDecryptedSharesAggregation | 1.58 | 1 | 1.58 | +| ZkDecryptionAggregation | 48.47 | 1 | 48.47 | +| ZkDkgAggregation | 5.56 | 1 | 5.56 | +| ZkNodeDkgFold | 107.17 | 3 | 321.51 | +| ZkPkAggregation | 0.40 | 1 | 0.40 | Sum of aggregation job tracked time: **377.52 s** (parallel CPU work; not P1/P2 wall clock). ### Folded on-chain artifacts (exported for Π_DKG / Π_dec gas) -| Artifact | Proof (bytes) | Public inputs (bytes) | -|----------|---------------|------------------------| -| dkg_aggregator | 10944 | 384 | -| decryption_aggregator | 10944 | 3648 | +| Artifact | Proof (bytes) | Public inputs (bytes) | +| --------------------- | ------------- | --------------------- | +| dkg_aggregator | 10944 | 384 | +| decryption_aggregator | 10944 | 3648 | ## Raw circuit benchmark JSON (Nargo) -Source files for the **Circuit Benchmarks** table. Persist this directory with `crisp_verify_gas.json` (and optional `integration_summary.json`) to regenerate the report without re-running the integration test. - -| File | -|------| -| `dkg_e_sm_share_computation_default.json` | -| `dkg_pk_default.json` | -| `dkg_share_decryption_default.json` | -| `dkg_share_encryption_default.json` | -| `dkg_sk_share_computation_default.json` | +Source files for the **Circuit Benchmarks** table. Persist this directory with +`crisp_verify_gas.json` (and optional `integration_summary.json`) to regenerate the report without +re-running the integration test. + +| File | +| ----------------------------------------------------- | +| `dkg_e_sm_share_computation_default.json` | +| `dkg_pk_default.json` | +| `dkg_share_decryption_default.json` | +| `dkg_share_encryption_default.json` | +| `dkg_sk_share_computation_default.json` | | `threshold_decrypted_shares_aggregation_default.json` | -| `threshold_pk_aggregation_default.json` | -| `threshold_pk_generation_default.json` | -| `threshold_share_decryption_default.json` | -| `threshold_user_data_encryption_ct0_default.json` | -| `threshold_user_data_encryption_ct1_default.json` | +| `threshold_pk_aggregation_default.json` | +| `threshold_pk_generation_default.json` | +| `threshold_share_decryption_default.json` | +| `threshold_user_data_encryption_ct0_default.json` | +| `threshold_user_data_encryption_ct1_default.json` | ## Notes -- All nodes are executed on the same machine in this benchmark run, so inter-node network latency is effectively 0. +- All nodes are executed on the same machine in this benchmark run, so inter-node network latency is + effectively 0. From 3185894d1a7f0a5581627879ada108c95a75e602 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 00:38:10 +0200 Subject: [PATCH 03/11] format decryption_agg --- .../recursive_aggregation/decryption_aggregator/src/main.nr | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr index acc7034277..8b8e93a30e 100644 --- a/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr +++ b/circuits/bin/recursive_aggregation/decryption_aggregator/src/main.nr @@ -96,8 +96,7 @@ fn main( // canonical commitment as a final public input for the EVM wrapper. for i in 0..(T + 1) { assert( - c6_fold_public[C6_FOLD_PREFIX_LEN + C6_FOLD_CT_COL_OFFSET + i] - == ciphertext_commitment, + c6_fold_public[C6_FOLD_PREFIX_LEN + C6_FOLD_CT_COL_OFFSET + i] == ciphertext_commitment, ); } From 7e0a86a34a13e4238c9459829b4b747d8cae69b7 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 10:49:38 +0200 Subject: [PATCH 04/11] modify contracts to stay into the size of EIP-170 --- .../IBondingRegistry.json | 2 +- .../ICiphernodeRegistry.json | 2 +- .../interfaces/IInterfold.sol/IInterfold.json | 2 +- .../ISlashingManager.json | 2 +- .../contracts/Interfold.sol | 24 +++++++------------ .../contracts/lib/InterfoldPricing.sol | 20 ++++++++++++++++ .../scripts/checkContractSize.ts | 4 ++-- 7 files changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json b/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json index b5878d89eb..46401f2ff8 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json @@ -1338,5 +1338,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IBondingRegistry.sol", - "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" + "buildInfoId": "solc-0_8_28-cc17cff9355f9567b3850c6bbe0afb765e5b8687" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json b/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json index e89f2c9031..77a8396a3f 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json @@ -1345,5 +1345,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ICiphernodeRegistry.sol", - "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" + "buildInfoId": "solc-0_8_28-cc17cff9355f9567b3850c6bbe0afb765e5b8687" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json b/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json index 92fb501ec6..411121479d 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/IInterfold.sol/IInterfold.json @@ -2402,5 +2402,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/IInterfold.sol", - "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" + "buildInfoId": "solc-0_8_28-cc17cff9355f9567b3850c6bbe0afb765e5b8687" } \ No newline at end of file diff --git a/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json b/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json index f44acf9268..ea94e7e2c3 100644 --- a/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +++ b/packages/interfold-contracts/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json @@ -1432,5 +1432,5 @@ "deployedLinkReferences": {}, "immutableReferences": {}, "inputSourceName": "project/contracts/interfaces/ISlashingManager.sol", - "buildInfoId": "solc-0_8_28-6e471e557b86aca04671115e397cf68c39af7a00" + "buildInfoId": "solc-0_8_28-cc17cff9355f9567b3850c6bbe0afb765e5b8687" } \ No newline at end of file diff --git a/packages/interfold-contracts/contracts/Interfold.sol b/packages/interfold-contracts/contracts/Interfold.sol index 260d6fa5a8..685fbbc3f3 100644 --- a/packages/interfold-contracts/contracts/Interfold.sol +++ b/packages/interfold-contracts/contracts/Interfold.sol @@ -432,8 +432,6 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { e3s[e3Id].plaintextOutput = plaintextOutput; _e3Stages[e3Id] = E3Stage.Complete; - require(proof.length > 0, ProofRequired()); - _verifyPlaintext(e3Id, keccak256(plaintextOutput), proof); success = true; @@ -857,19 +855,15 @@ contract Interfold is IInterfold, Ownable2StepUpgradeable { (canFail, reason, deadline) = _checkFailureCondition(e3Id, current); if (!canFail) revert FailureConditionNotMet(e3Id); - // enforce caller restriction inside the grace window. - uint256 grace = markFailedGracePeriod; - if (grace > 0) { - uint256 graceEnds = deadline + grace; - if ( - block.timestamp < graceEnds && - msg.sender != _e3Requesters[e3Id] && - msg.sender != owner() && - !_registryFor(e3Id).isCommitteeMember(e3Id, msg.sender) - ) { - revert MarkE3FailedInGracePeriod(e3Id, graceEnds); - } - } + InterfoldPricing.validateMarkFailedCaller( + e3Id, + deadline, + markFailedGracePeriod, + msg.sender, + _e3Requesters[e3Id], + owner(), + address(_registryFor(e3Id)) + ); _markE3FailedWithReason(e3Id, current, reason); } diff --git a/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol b/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol index 2f22c59c67..c24f504e1d 100644 --- a/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol +++ b/packages/interfold-contracts/contracts/lib/InterfoldPricing.sol @@ -83,6 +83,7 @@ library InterfoldPricing { bytes32 ciphertextCommitment, bytes calldata proof ) external view { + if (proof.length == 0) revert IInterfold.ProofRequired(); bytes32 committeeHash = ICiphernodeRegistry(registryAddress) .getCommitteeHash(e3Id); bytes32 decryptionDomain = keccak256( @@ -176,6 +177,25 @@ library InterfoldPricing { revert IInterfold.E3AlreadyFailed(e3Id); } + function validateMarkFailedCaller( + uint256 e3Id, + uint256 deadline, + uint256 grace, + address caller, + address requester, + address contractOwner, + address registry + ) external view { + if (grace == 0) return; + uint256 graceEnds = deadline + grace; + if ( + block.timestamp < graceEnds && + caller != requester && + caller != contractOwner && + !ICiphernodeRegistry(registry).isCommitteeMember(e3Id, caller) + ) revert IInterfold.MarkE3FailedInGracePeriod(e3Id, graceEnds); + } + /// @notice Mirrors the threshold / min-size gates at the top of /// {Interfold.getE3Quote} (post param-set existence check). /// @param committeeSize ABI-encoded as `uint8` to avoid qualified enum diff --git a/packages/interfold-contracts/scripts/checkContractSize.ts b/packages/interfold-contracts/scripts/checkContractSize.ts index 6e97544640..8fa06c77a5 100644 --- a/packages/interfold-contracts/scripts/checkContractSize.ts +++ b/packages/interfold-contracts/scripts/checkContractSize.ts @@ -7,8 +7,8 @@ const MAX_RUNTIME_BYTES = EIP170_LIMIT_BYTES - REQUIRED_HEADROOM_BYTES; const RELEASE_CONTRACTS = [ "Interfold", - "DkgAggregatorVerifier", - "DecryptionAggregatorVerifier", + "contracts/verifiers/bfv/honk/DkgAggregatorVerifier.sol:DkgAggregatorVerifier", + "contracts/verifiers/bfv/honk/DecryptionAggregatorVerifier.sol:DecryptionAggregatorVerifier", ] as const; let failed = false; From 9586653372ae008d2aa0e6af23c53340c544602c Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 10:59:16 +0200 Subject: [PATCH 05/11] fix missing parameter to constructor --- .../crisp-contracts/contracts/Mocks/MockInterfold.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockInterfold.sol b/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockInterfold.sol index c8ce8b9626..cb5af963fd 100644 --- a/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockInterfold.sol +++ b/examples/CRISP/packages/crisp-contracts/contracts/Mocks/MockInterfold.sol @@ -34,7 +34,8 @@ contract MockInterfold { committeePublicKey: committeePublicKey, ciphertextOutput: bytes32(0), plaintextOutput: plaintextOutput, - requester: address(0) + requester: address(0), + ciphertextCommitment: bytes32(0) }); IE3Program(program).validate(nextE3Id, 0, bytes(""), bytes(""), abi.encode(address(0), nextE3Id, 2, 0, 0)); @@ -70,7 +71,8 @@ contract MockInterfold { committeePublicKey: committeePublicKey, ciphertextOutput: bytes32(0), plaintextOutput: plaintextOutput, - requester: address(0) + requester: address(0), + ciphertextCommitment: bytes32(0) }); } } From 012c011fac50347e01b3c4d0847dbf99bbeba364 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 11:08:28 +0200 Subject: [PATCH 06/11] fix missing field --- crates/evm/src/event_decoding/catalog.rs | 4 ++-- crates/evm/src/interfold/events.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/evm/src/event_decoding/catalog.rs b/crates/evm/src/event_decoding/catalog.rs index 9dd2af6e72..7e24d0850e 100644 --- a/crates/evm/src/event_decoding/catalog.rs +++ b/crates/evm/src/event_decoding/catalog.rs @@ -51,7 +51,7 @@ const INTERFOLD: &[EvmEventDefinition] = &[ EvmEventDefinition::new("CiphernodeRegistrySet", "CiphernodeRegistrySet(address)", None), EvmEventDefinition::new( "CiphertextOutputPublished", - "CiphertextOutputPublished(uint256,bytes)", + "CiphertextOutputPublished(uint256,bytes,bytes32)", Some(1), ), EvmEventDefinition::new("CommitteeFinalized", "CommitteeFinalized(uint256)", Some(1)), @@ -71,7 +71,7 @@ const INTERFOLD: &[EvmEventDefinition] = &[ EvmEventDefinition::new("E3RefundManagerSet", "E3RefundManagerSet(address)", None), EvmEventDefinition::new( "E3Requested", - "E3Requested(uint256,(uint256,uint8,uint256,uint256[2],bytes32,address,uint8,bytes,address,address,bytes32,bytes32,bytes,address),address)", + "E3Requested(uint256,(uint256,uint8,uint256,uint256[2],bytes32,address,uint8,bytes,address,address,bytes32,bytes32,bytes,address,bytes32),address)", None, ), EvmEventDefinition::new("E3StageChanged", "E3StageChanged(uint256,uint8,uint8)", Some(1)), diff --git a/crates/evm/src/interfold/events.rs b/crates/evm/src/interfold/events.rs index 6f995b2584..d53f20c62a 100644 --- a/crates/evm/src/interfold/events.rs +++ b/crates/evm/src/interfold/events.rs @@ -571,6 +571,7 @@ mod tests { ciphertextOutput: B256::ZERO, plaintextOutput: Bytes::new(), requester: Address::ZERO, + ciphertextCommitment: B256::ZERO, }, e3Program: Address::ZERO, }; From 5b0f48dadba6cf35474982e8c8c6398234971164 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 15:02:56 +0200 Subject: [PATCH 07/11] avoid non-terminal state replay errors --- .../effects/aggregate_public_key.rs | 10 ++- .../effects/verify_key_proofs.rs | 15 +++++ .../tests/attestations.rs | 60 ++++++++++++++++++ .../src/public_key_aggregation/tests/mod.rs | 10 +++ .../deployed_contracts.json | 63 +++++++++---------- tests/integration/interfold.config.yaml | 16 ++--- 6 files changed, 133 insertions(+), 41 deletions(-) diff --git a/crates/aggregator/src/public_key_aggregation/effects/aggregate_public_key.rs b/crates/aggregator/src/public_key_aggregation/effects/aggregate_public_key.rs index aaf23321fb..11b325c7c0 100644 --- a/crates/aggregator/src/public_key_aggregation/effects/aggregate_public_key.rs +++ b/crates/aggregator/src/public_key_aggregation/effects/aggregate_public_key.rs @@ -15,8 +15,16 @@ impl PublicKeyAggregator { return Ok(()); } + let state = self.state.get(); + if matches!( + state.as_ref(), + Some(PublicKeyAggregatorState::Complete { .. }) + ) { + info!("Ignoring late C5 proof after public-key aggregation completed"); + return Ok(()); + } if !matches!( - self.state.get(), + state.as_ref(), Some(PublicKeyAggregatorState::GeneratingC5Proof { .. }) ) { return Err(anyhow::anyhow!( diff --git a/crates/aggregator/src/public_key_aggregation/effects/verify_key_proofs.rs b/crates/aggregator/src/public_key_aggregation/effects/verify_key_proofs.rs index e6a6e47537..90ff63dfa4 100644 --- a/crates/aggregator/src/public_key_aggregation/effects/verify_key_proofs.rs +++ b/crates/aggregator/src/public_key_aggregation/effects/verify_key_proofs.rs @@ -13,6 +13,13 @@ impl PublicKeyAggregator { c1_proof: Option, ec: &EventContext, ) -> Result<()> { + if matches!( + self.state.get().as_ref(), + Some(PublicKeyAggregatorState::Complete { .. }) + ) { + info!("Ignoring replayed keyshare after public-key aggregation completed"); + return Ok(()); + } self.state.try_mutate(ec, |state| { PublicKeyAggregation::add_keyshare( state, @@ -90,6 +97,14 @@ impl PublicKeyAggregator { return Ok(()); } + if matches!( + self.state.get().as_ref(), + Some(PublicKeyAggregatorState::Complete { .. }) + ) { + info!("Ignoring late C1 verification after public-key aggregation completed"); + return Ok(()); + } + let PublicKeyAggregatorState::VerifyingC1 { submission_order, threshold_m, diff --git a/crates/aggregator/src/public_key_aggregation/tests/attestations.rs b/crates/aggregator/src/public_key_aggregation/tests/attestations.rs index 2e51bdf309..4776eee9d3 100644 --- a/crates/aggregator/src/public_key_aggregation/tests/attestations.rs +++ b/crates/aggregator/src/public_key_aggregation/tests/attestations.rs @@ -6,6 +6,66 @@ use super::*; +#[actix::test] +async fn late_c5_proof_is_ignored_after_completion() -> Result<()> { + let (mut aggregator, _history, e3_id) = build_public_key_aggregator(complete_state()).await?; + let signed_proof = SignedProofPayload { + payload: ProofPayload { + e3_id: e3_id.clone(), + proof_type: ProofType::C5PkAggregation, + proof: dummy_proof(CircuitName::PkAggregation), + }, + signature: ArcBytes::from_bytes(&[0u8; 65]), + }; + let event = PkAggregationProofSigned { + e3_id: e3_id.clone(), + signed_proof, + }; + + aggregator + .handle_pk_aggregation_proof_signed(TypedEvent::new(event.clone(), test_ctx(event)))?; + + assert!(matches!( + aggregator.state.get(), + Some(PublicKeyAggregatorState::Complete { .. }) + )); + Ok(()) +} + +#[actix::test] +async fn replayed_c1_artifacts_are_ignored_after_completion() -> Result<()> { + let (mut aggregator, _history, e3_id) = build_public_key_aggregator(complete_state()).await?; + let verification = ShareVerificationComplete { + e3_id: e3_id.clone(), + kind: VerificationKind::PkGenerationProofs, + dishonest_parties: BTreeSet::new(), + }; + + aggregator.handle_c1_verification_complete(TypedEvent::new( + verification.clone(), + test_ctx(verification), + ))?; + aggregator.add_keyshare( + ArcBytes::from_bytes(&[4, 5, 6]), + "0x0000000000000000000000000000000000000001".to_string(), + 0, + None, + &test_ctx(KeyshareCreated { + pubkey: ArcBytes::from_bytes(&[4, 5, 6]), + e3_id, + node: "0x0000000000000000000000000000000000000001".to_string(), + party_id: 0, + signed_pk_generation_proof: None, + }), + )?; + + assert!(matches!( + aggregator.state.get(), + Some(PublicKeyAggregatorState::Complete { .. }) + )); + Ok(()) +} + #[actix::test] async fn honest_dkg_fold_without_attestation_is_not_buffered() -> Result<()> { let correlation_id = CorrelationId::new(); diff --git a/crates/aggregator/src/public_key_aggregation/tests/mod.rs b/crates/aggregator/src/public_key_aggregation/tests/mod.rs index 8392f0899c..883b05ad16 100644 --- a/crates/aggregator/src/public_key_aggregation/tests/mod.rs +++ b/crates/aggregator/src/public_key_aggregation/tests/mod.rs @@ -54,6 +54,16 @@ fn generating_c5_state(correlation_id: CorrelationId) -> PublicKeyAggregatorStat } } +fn complete_state() -> PublicKeyAggregatorState { + PublicKeyAggregatorState::Complete { + public_key: ArcBytes::from_bytes(&[1, 2, 3]), + keyshares: OrderedSet::new(), + nodes: OrderedSet::new(), + committee_addresses: Vec::new(), + honest_committee_addresses: Vec::new(), + } +} + async fn build_public_key_aggregator( initial_state: PublicKeyAggregatorState, ) -> Result<( diff --git a/packages/interfold-contracts/deployed_contracts.json b/packages/interfold-contracts/deployed_contracts.json index 821bc1eea8..f5783bb63a 100644 --- a/packages/interfold-contracts/deployed_contracts.json +++ b/packages/interfold-contracts/deployed_contracts.json @@ -140,14 +140,14 @@ }, "localhost": { "PoseidonT3": { - "blockNumber": 7, + "blockNumber": 5, "address": "0x3333333C0A88F9BE4fd23ed0536F9B6c427e3B93" }, "MockUSDC": { "constructorArgs": { "initialSupply": "1000000" }, - "blockNumber": 8, + "blockNumber": 6, "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" }, "InterfoldTicketToken": { @@ -156,7 +156,7 @@ "registry": "0x0000000000000000000000000000000000000001", "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 9, + "blockNumber": 7, "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" }, "SlashingManager": { @@ -164,7 +164,7 @@ "initialDelay": "172800", "admin": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, - "blockNumber": 10, + "blockNumber": 8, "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" }, "CiphernodeRegistryOwnable": { @@ -179,7 +179,7 @@ "proxyAdminAddress": "0x61c36a8d610163660E21a8b7359e1Cac0C9133e1", "implementationAddress": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" }, - "blockNumber": 11, + "blockNumber": 9, "address": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" }, "BondingRegistry": { @@ -201,19 +201,18 @@ "proxyAdminAddress": "0x9bd03768a7DCc129555dE410FF8E85528A4F88b5", "implementationAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, - "blockNumber": 12, + "blockNumber": 10, "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "InterfoldToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ccaStart": "1782819831", - "ccaEnd": "1783424631", - "noMoreLocks": "1913024631", - "claimSource": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "ccaStart": "1784469399", + "ccaEnd": "1785074199", + "noMoreLocks": "1917266199", "bondingRegistry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, - "blockNumber": 15, + "blockNumber": 14, "address": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" }, "Interfold": { @@ -227,46 +226,46 @@ "timeoutConfig": "{\"dkgWindow\":7200,\"computeWindow\":86400,\"decryptionWindow\":3600}" }, "proxyRecords": { - "initData": "0x4d600e5d000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e10", + "initData": "0x2a5f0582000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8530000000000000000000000000000000000000000000000000000000000000001000000000000000000000000e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000001c2000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000e1000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000c3500000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000493e000000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c4000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000009c400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", - "proxyAdminAddress": "0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08", - "implementationAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + "proxyAddress": "0x9A676e781A523b5d0C0e43731313A708CB607508", + "proxyAdminAddress": "0x8e80FFe6Dc044F4A766Afd6e5a8732Fe0977A493", + "implementationAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" }, - "blockNumber": 19, - "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" + "blockNumber": 18, + "address": "0x9A676e781A523b5d0C0e43731313A708CB607508" }, "E3RefundManager": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "interfold": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "interfold": "0x9A676e781A523b5d0C0e43731313A708CB607508", "treasury": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" }, "proxyRecords": { - "initData": "0xc0c53b8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000dcd1bf9a1b36ce34237eeafef220932846bcd82000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "initData": "0xc0c53b8b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000009a676e781a523b5d0c0e43731313a708cb607508000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "proxyAddress": "0x0B306BF915C4d645ff596e518fAf3F9669b97016", - "proxyAdminAddress": "0x524F04724632eED237cbA3c37272e018b3A7967e", - "implementationAddress": "0x9A676e781A523b5d0C0e43731313A708CB607508" + "proxyAddress": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", + "proxyAdminAddress": "0x24B3c7704709ed1491473F30393FFc93cFB0FC34", + "implementationAddress": "0x0B306BF915C4d645ff596e518fAf3F9669b97016" }, - "blockNumber": 21, - "address": "0x0B306BF915C4d645ff596e518fAf3F9669b97016" + "blockNumber": 20, + "address": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1" }, "MockComputeProvider": { - "blockNumber": 35, - "address": "0x809d550fca64d94Bd9F66E60752A544199cfAC3D" + "blockNumber": 34, + "address": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029" }, "MockDecryptionVerifier": { - "blockNumber": 36, - "address": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029" + "blockNumber": 35, + "address": "0x1291Be112d480055DaFd8a610b7d1e203891C274" }, "MockPkVerifier": { - "blockNumber": 37, - "address": "0x1291Be112d480055DaFd8a610b7d1e203891C274" + "blockNumber": 36, + "address": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" }, "MockE3Program": { - "blockNumber": 38, - "address": "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" + "blockNumber": 37, + "address": "0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575" } } } \ No newline at end of file diff --git a/tests/integration/interfold.config.yaml b/tests/integration/interfold.config.yaml index 16fd9f85e8..ddd6881445 100644 --- a/tests/integration/interfold.config.yaml +++ b/tests/integration/interfold.config.yaml @@ -4,23 +4,23 @@ chains: rpc_url: 'ws://localhost:8545' contracts: e3_program: - address: "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154" - deploy_block: 38 + address: "0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575" + deploy_block: 37 interfold: - address: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" - deploy_block: 19 + address: "0x9A676e781A523b5d0C0e43731313A708CB607508" + deploy_block: 18 ciphernode_registry: address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707" - deploy_block: 11 + deploy_block: 9 bonding_registry: address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" - deploy_block: 12 + deploy_block: 10 slashing_manager: address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" - deploy_block: 10 + deploy_block: 8 fee_token: address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - deploy_block: 8 + deploy_block: 6 program: dev: true From 34e46df589067e089605a8a234ddea86d4d07d5f Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 15:39:23 +0200 Subject: [PATCH 08/11] additional restart replay effects --- .../effects/initialize_dkg.rs | 27 +++++++++++++++++++ .../effects/encryption_key_result.rs | 4 +-- .../deployed_contracts.json | 6 ++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/crates/keyshare/src/threshold_keyshare/effects/initialize_dkg.rs b/crates/keyshare/src/threshold_keyshare/effects/initialize_dkg.rs index 12936fb590..fe0323e2a0 100644 --- a/crates/keyshare/src/threshold_keyshare/effects/initialize_dkg.rs +++ b/crates/keyshare/src/threshold_keyshare/effects/initialize_dkg.rs @@ -158,6 +158,33 @@ impl ThresholdKeyshare { ) -> Result<()> { let (res, ec) = res.into_components(); + let state = self.state.try_get()?; + match &state.state { + KeyshareState::GeneratingThresholdShare(data) + if data.pk_share.is_none() + && data.sk_sss.is_none() + && data.e_sm_raw.is_none() + && data.proof_request_data.is_none() => {} + KeyshareState::GeneratingThresholdShare(_) => { + info!("Ignoring duplicate GenPkShareAndSkSss response"); + return Ok(()); + } + KeyshareState::AggregatingDecryptionKey(_) + | KeyshareState::ReadyForDecryption(_) + | KeyshareState::Decrypting(_) + | KeyshareState::GeneratingDecryptionProof(_) + | KeyshareState::Completed => { + info!( + state = state.variant_name(), + "Ignoring replayed GenPkShareAndSkSss response after DKG advanced" + ); + return Ok(()); + } + KeyshareState::Init | KeyshareState::CollectingEncryptionKeys(_) => { + bail!("GenPkShareAndSkSss response received before GeneratingThresholdShare state"); + } + } + let output: GenPkShareAndSkSssResponse = res .try_into() .context("Error extracting data from compute process")?; diff --git a/crates/zk-prover/src/proof_request/effects/encryption_key_result.rs b/crates/zk-prover/src/proof_request/effects/encryption_key_result.rs index 6762865b3f..f5374078eb 100644 --- a/crates/zk-prover/src/proof_request/effects/encryption_key_result.rs +++ b/crates/zk-prover/src/proof_request/effects/encryption_key_result.rs @@ -12,8 +12,8 @@ impl ProofRequestActor { ec: &EventContext, ) { let Some(pending) = self.pending.remove(correlation_id) else { - error!( - "Received PkBfv ComputeResponse with correlation_id {:?} but no matching pending request found.", + warn!( + "Ignoring orphaned or replayed PkBfv ComputeResponse with correlation_id {:?}", correlation_id ); return; diff --git a/packages/interfold-contracts/deployed_contracts.json b/packages/interfold-contracts/deployed_contracts.json index f5783bb63a..e146fe1e4b 100644 --- a/packages/interfold-contracts/deployed_contracts.json +++ b/packages/interfold-contracts/deployed_contracts.json @@ -207,9 +207,9 @@ "InterfoldToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ccaStart": "1784469399", - "ccaEnd": "1785074199", - "noMoreLocks": "1917266199", + "ccaStart": "1784471470", + "ccaEnd": "1785076270", + "noMoreLocks": "1917268270", "bondingRegistry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "blockNumber": 14, From b1ffe0a026ffa18374642241af1c90e5adfd452b Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 16:00:39 +0200 Subject: [PATCH 09/11] update fake_encrypt and relative tests --- crates/test-helpers/src/bin/fake_encrypt.rs | 14 +++++++ .../contracts/test/MockE3Program.sol | 18 +++++++- .../deployed_contracts.json | 6 +-- .../interfold-contracts/tasks/interfold.ts | 41 +++++++++++++++---- packages/interfold-contracts/tasks/program.ts | 26 +++++++++++- tests/integration/base.sh | 8 ++-- tests/integration/persist.sh | 4 +- 7 files changed, 97 insertions(+), 20 deletions(-) diff --git a/crates/test-helpers/src/bin/fake_encrypt.rs b/crates/test-helpers/src/bin/fake_encrypt.rs index aa1999cb21..3a58b21b03 100644 --- a/crates/test-helpers/src/bin/fake_encrypt.rs +++ b/crates/test-helpers/src/bin/fake_encrypt.rs @@ -6,6 +6,7 @@ // This is a test script designed to encrypt some fixed data to a fhe public key use clap::Parser; +use e3_bfv_client::compute_ct_commitment; use e3_fhe_params::DEFAULT_BFV_PRESET; use e3_fhe_params::{build_bfv_params_from_set_arc, decode_bfv_params_arc}; use fhe::bfv::{Encoding, Plaintext, PublicKey}; @@ -38,6 +39,9 @@ struct Args { #[arg(short, long)] output: String, + #[arg(long)] + commitment_output: Option, + #[arg(short, long, value_delimiter = ',')] plaintext: Vec, @@ -66,6 +70,16 @@ fn main() -> Result<(), Box> { let ciphertext_bytes = ciphertext.clone().to_bytes(); fs::write(&args.output, &ciphertext_bytes)?; + if let Some(commitment_output) = args.commitment_output { + let commitment = compute_ct_commitment( + ciphertext_bytes.clone(), + params.degree(), + params.plaintext(), + params.moduli().to_vec(), + )?; + fs::write(&commitment_output, commitment)?; + println!("Created {}", commitment_output); + } println!("Created {}", args.output); Ok(()) diff --git a/packages/interfold-contracts/contracts/test/MockE3Program.sol b/packages/interfold-contracts/contracts/test/MockE3Program.sol index 2a01a412d7..dd947197c1 100644 --- a/packages/interfold-contracts/contracts/test/MockE3Program.sol +++ b/packages/interfold-contracts/contracts/test/MockE3Program.sol @@ -46,6 +46,22 @@ contract MockE3Program is IE3Program { } function publishInput(uint256 e3Id, bytes memory data) external { + _publishInput(e3Id, data, keccak256(data)); + } + + function publishInputWithCommitment( + uint256 e3Id, + bytes memory data, + bytes32 ciphertextCommitment + ) external { + _publishInput(e3Id, data, ciphertextCommitment); + } + + function _publishInput( + uint256 e3Id, + bytes memory data, + bytes32 ciphertextCommitment + ) internal { if (data.length == 3) { revert InvalidInput(); } @@ -59,7 +75,7 @@ contract MockE3Program is IE3Program { interfold.publishCiphertextOutput( e3Id, data, - keccak256(data), + ciphertextCommitment, data ); } diff --git a/packages/interfold-contracts/deployed_contracts.json b/packages/interfold-contracts/deployed_contracts.json index e146fe1e4b..5476797942 100644 --- a/packages/interfold-contracts/deployed_contracts.json +++ b/packages/interfold-contracts/deployed_contracts.json @@ -207,9 +207,9 @@ "InterfoldToken": { "constructorArgs": { "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "ccaStart": "1784471470", - "ccaEnd": "1785076270", - "noMoreLocks": "1917268270", + "ccaStart": "1784472771", + "ccaEnd": "1785077571", + "noMoreLocks": "1917269571", "bondingRegistry": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853" }, "blockNumber": 14, diff --git a/packages/interfold-contracts/tasks/interfold.ts b/packages/interfold-contracts/tasks/interfold.ts index 86c14e9e26..d83ccc882d 100644 --- a/packages/interfold-contracts/tasks/interfold.ts +++ b/packages/interfold-contracts/tasks/interfold.ts @@ -329,12 +329,6 @@ export const publishCommittee = task( defaultValue: "0x", type: ArgumentType.STRING, }) - .addOption({ - name: "ciphertextCommitment", - description: "circuit-compatible SAFE commitment to the decoded ciphertext", - defaultValue: "", - type: ArgumentType.STRING, - }) .addOption({ name: "dkgAttestationBundle", description: @@ -529,9 +523,29 @@ export const publishCiphertext = task( defaultValue: "", type: ArgumentType.STRING, }) + .addOption({ + name: "ciphertextCommitment", + description: "circuit-compatible SAFE commitment to the decoded ciphertext", + defaultValue: "", + type: ArgumentType.STRING, + }) + .addOption({ + name: "ciphertextCommitmentFile", + description: "file containing the 32-byte ciphertext commitment", + defaultValue: "", + type: ArgumentType.STRING, + }) .setAction(async () => ({ default: async ( - { e3Id, data, dataFile, proof, proofFile, ciphertextCommitment }, + { + e3Id, + data, + dataFile, + proof, + proofFile, + ciphertextCommitment, + ciphertextCommitmentFile, + }, hre, ) => { const { deployAndSaveInterfold } = await import( @@ -556,10 +570,21 @@ export const publishCiphertext = task( proofToSend = file.toString(); } + let commitmentToSend = ciphertextCommitment; + if (ciphertextCommitmentFile) { + commitmentToSend = + "0x" + fs.readFileSync(ciphertextCommitmentFile).toString("hex"); + } + if (!isHexString(commitmentToSend, 32)) { + throw new Error( + "A 32-byte --ciphertext-commitment or --ciphertext-commitment-file is required", + ); + } + const tx = await interfold.publishCiphertextOutput( e3Id, dataToSend, - ciphertextCommitment, + commitmentToSend, proofToSend, ); diff --git a/packages/interfold-contracts/tasks/program.ts b/packages/interfold-contracts/tasks/program.ts index 52773d91b4..e84112c876 100644 --- a/packages/interfold-contracts/tasks/program.ts +++ b/packages/interfold-contracts/tasks/program.ts @@ -3,6 +3,7 @@ // This file is provided WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +import { isHexString } from "ethers"; import fs from "fs"; import { task } from "hardhat/config"; import { ArgumentType } from "hardhat/types/arguments"; @@ -40,8 +41,17 @@ export const publishInput = task( defaultValue: "", type: ArgumentType.STRING, }) + .addOption({ + name: "ciphertextCommitmentFile", + description: "file containing the 32-byte ciphertext commitment", + defaultValue: "", + type: ArgumentType.STRING, + }) .setAction(async () => ({ - default: async ({ e3Id, data, dataFile, programAddress }, hre) => { + default: async ( + { e3Id, data, dataFile, programAddress, ciphertextCommitmentFile }, + hre, + ) => { const { deployAndSaveMockProgram } = await import( "../scripts/deployAndSave/mockProgram" ); @@ -78,7 +88,19 @@ export const publishInput = task( dataToSend = "0x" + file.toString("hex"); } - await program.publishInput(e3Id, dataToSend); + if (ciphertextCommitmentFile) { + const commitment = + "0x" + fs.readFileSync(ciphertextCommitmentFile).toString("hex"); + if (!isHexString(commitment, 32)) { + throw new Error("Ciphertext commitment file must contain 32 bytes"); + } + const publishInputWithCommitment = program.getFunction( + "publishInputWithCommitment", + ); + await publishInputWithCommitment(e3Id, dataToSend, commitment); + } else { + await program.publishInput(e3Id, dataToSend); + } console.log(`Input published to ${actualProgramAddress} (e3Id=${e3Id})`); }, diff --git a/tests/integration/base.sh b/tests/integration/base.sh index 15b00c04f4..b5f2ac8bc0 100755 --- a/tests/integration/base.sh +++ b/tests/integration/base.sh @@ -102,17 +102,17 @@ if [[ "$FULL_PROOF_AGGREGATION" == "true" ]]; then pnpm e3-program:setMockInterfold --network localhost heading "Encrypt plaintext under the published committee pubkey" - $SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" + $SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --commitment-output "$SCRIPT_DIR/output/ciphertext_commitment.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" waiton "$SCRIPT_DIR/output/output.bin" heading "Publish E3 input (forwards to publishCiphertextOutput; nodes run decryption with ZK proofs)" - pnpm e3-program:publishInput --network localhost --e3-id 0 --data-file "$SCRIPT_DIR/output/output.bin" + pnpm e3-program:publishInput --network localhost --e3-id 0 --data-file "$SCRIPT_DIR/output/output.bin" --ciphertext-commitment-file "$SCRIPT_DIR/output/ciphertext_commitment.bin" heading "Wait for on-chain plaintext (BFV decryption verifier)" wait_for_plaintext_output 0 "$SCRIPT_DIR/output/plaintext.txt" "$INTEGRATION_DKG_TIMEOUT" else heading "Mock encrypted plaintext" - $SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" + $SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --commitment-output "$SCRIPT_DIR/output/ciphertext_commitment.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" heading "Mock publish input e3-id" pnpm e3-program:publishInput --network localhost --e3-id 0 --data 0x12345678 @@ -122,7 +122,7 @@ else waiton "$SCRIPT_DIR/output/output.bin" heading "Publish ciphertext to EVM" - pnpm e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --proof 0x12345678 + pnpm e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --ciphertext-commitment-file "$SCRIPT_DIR/output/ciphertext_commitment.bin" --proof 0x12345678 wait_for_plaintext_output 0 "$SCRIPT_DIR/output/plaintext.txt" fi diff --git a/tests/integration/persist.sh b/tests/integration/persist.sh index 0c168876bd..bdafb7471f 100755 --- a/tests/integration/persist.sh +++ b/tests/integration/persist.sh @@ -99,7 +99,7 @@ interfold_nodes_start "$ACTIVE_AGG" sleep 5 heading "Mock encrypted plaintext" -$SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" +$SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --commitment-output "$SCRIPT_DIR/output/ciphertext_commitment.bin" --plaintext "$PLAINTEXT" --params "$ENCODED_PARAMS" heading "Mock publish input e3-id" pnpm e3-program:publishInput --network localhost --e3-id 0 --data 0x12345678 @@ -109,7 +109,7 @@ sleep 6 # wait for input deadline to pass waiton "$SCRIPT_DIR/output/output.bin" heading "Publish ciphertext to EVM" -pnpm e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --proof 0x12345678 +pnpm e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --ciphertext-commitment-file "$SCRIPT_DIR/output/ciphertext_commitment.bin" --proof 0x12345678 wait_for_plaintext_output 0 "$SCRIPT_DIR/output/plaintext.txt" From 0f8331619a5e5db8c41ac61e9dde1d552d0e001e Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 16:28:11 +0200 Subject: [PATCH 10/11] update integration chain --- Cargo.lock | 2 ++ crates/program-server/Cargo.toml | 2 ++ crates/program-server/src/lib.rs | 17 ++++++++++++++++- crates/program-server/src/types.rs | 21 ++++++++++++++++++++- templates/default/Cargo.lock | 2 ++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c68128cb5..a03680c446 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3702,7 +3702,9 @@ dependencies = [ "actix-web", "anyhow", "derivative", + "e3-bfv-client", "e3-compute-provider", + "e3-fhe-params", "hex", "reqwest", "serde", diff --git a/crates/program-server/Cargo.toml b/crates/program-server/Cargo.toml index 236b5342d0..6a04da6f75 100644 --- a/crates/program-server/Cargo.toml +++ b/crates/program-server/Cargo.toml @@ -12,6 +12,8 @@ serde.workspace = true serde_json.workspace = true tokio.workspace = true e3-compute-provider.workspace = true +e3-bfv-client.workspace = true +e3-fhe-params.workspace = true reqwest.workspace = true anyhow.workspace = true hex.workspace = true diff --git a/crates/program-server/src/lib.rs b/crates/program-server/src/lib.rs index 70b1368747..32e6486c2a 100644 --- a/crates/program-server/src/lib.rs +++ b/crates/program-server/src/lib.rs @@ -8,7 +8,9 @@ mod types; use actix_web::{middleware::Logger, web, App, HttpResponse, HttpServer, Result as ActixResult}; use anyhow::{Context, Result}; +use e3_bfv_client::compute_ct_commitment; use e3_compute_provider::FHEInputs; +use e3_fhe_params::decode_bfv_params_arc; use serde::Serialize; use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; use tokio::sync::Semaphore; @@ -258,14 +260,27 @@ async fn process_computation_background( callback_url: reqwest::Url, fhe_inputs: FHEInputs, ) -> Result<()> { - match runner(fhe_inputs).await { + match runner(fhe_inputs.clone()).await { Ok((proof, ciphertext)) => { println!("computation finished!"); + // Compute the SAFE commitment for the produced ciphertext so the + // downstream template server can forward it to + // `Interfold.publishCiphertextOutput`. + let params = decode_bfv_params_arc(&fhe_inputs.params) + .context("failed to decode BFV params for commitment")?; + let ciphertext_commitment = compute_ct_commitment( + ciphertext.clone(), + params.degree(), + params.plaintext(), + params.moduli().to_vec(), + ) + .context("failed to compute ciphertext commitment")?; println!("handling webhook delivery..."); let payload = WebhookPayload::Completed { e3_id, ciphertext, proof, + ciphertext_commitment, }; handle_webhook_delivery(&webhook_client, &callback_url, payload).await?; println!("✓ Computation completed for E3 {}", e3_id); diff --git a/crates/program-server/src/types.rs b/crates/program-server/src/types.rs index 45039948c5..a5409d4d9e 100644 --- a/crates/program-server/src/types.rs +++ b/crates/program-server/src/types.rs @@ -39,6 +39,12 @@ pub enum WebhookPayload { #[serde(deserialize_with = "deserialize_hex_string")] #[derivative(Debug = "ignore")] proof: Vec, + /// Circuit-compatible SAFE commitment to the decrypted ciphertext. + /// Required by `Interfold.publishCiphertextOutput` since the + /// ciphertext-binding remediation. Serialized as a 0x-prefixed + /// hex string for direct forwarding to the template server. + #[serde(serialize_with = "serialize_bytes32_as_hex")] + ciphertext_commitment: [u8; 32], }, Failed { e3_id: u64, @@ -54,6 +60,14 @@ where serializer.serialize_str(&hex_string) } +fn serialize_bytes32_as_hex(bytes: &[u8; 32], serializer: S) -> Result +where + S: Serializer, +{ + let hex_string = format!("0x{}", hex::encode(bytes)); + serializer.serialize_str(&hex_string) +} + pub fn deserialize_hex_string<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -151,14 +165,19 @@ mod tests { #[test] fn test_webhook_payload_serialization_completed() { + let commitment = [0x11u8; 32]; let payload = WebhookPayload::Completed { e3_id: 12345, ciphertext: vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], proof: vec![0xde, 0xad, 0xbe, 0xef], + ciphertext_commitment: commitment, }; let json = serde_json::to_string(&payload).expect("Failed to serialize"); - let expected = r#"{"status":"completed","e3_id":12345,"ciphertext":"0x0123456789abcdef","proof":"0xdeadbeef"}"#; + let expected = format!( + r#"{{"status":"completed","e3_id":12345,"ciphertext":"0x0123456789abcdef","proof":"0xdeadbeef","ciphertext_commitment":"0x{}"}}"#, + hex::encode(commitment), + ); assert_eq!(json, expected); } diff --git a/templates/default/Cargo.lock b/templates/default/Cargo.lock index 5f2d1fa36f..1e3970a893 100644 --- a/templates/default/Cargo.lock +++ b/templates/default/Cargo.lock @@ -1369,7 +1369,9 @@ dependencies = [ "actix-web", "anyhow", "derivative", + "e3-bfv-client", "e3-compute-provider", + "e3-fhe-params", "hex", "reqwest", "serde", From 93b86ee46c502db0869be5d84425c73e43734a9c Mon Sep 17 00:00:00 2001 From: 0xjei Date: Sun, 19 Jul 2026 16:40:20 +0200 Subject: [PATCH 11/11] refresh lock for crisp --- examples/CRISP/Cargo.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/CRISP/Cargo.lock b/examples/CRISP/Cargo.lock index 64dd74392b..823b95b0c3 100644 --- a/examples/CRISP/Cargo.lock +++ b/examples/CRISP/Cargo.lock @@ -2532,7 +2532,9 @@ dependencies = [ "actix-web", "anyhow", "derivative", + "e3-bfv-client", "e3-compute-provider", + "e3-fhe-params", "hex", "reqwest", "serde",