From 902e9d09410a3ac988d543c629bc866ddb1dc725 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Thu, 12 Dec 2024 16:03:25 +0400 Subject: [PATCH 01/13] add poseidon example and gas benchmark --- Cargo.lock | 39 ++++++++++------ Cargo.toml | 2 + benches/src/lib.rs | 1 + benches/src/main.rs | 3 +- benches/src/poseidon.rs | 68 ++++++++++++++++++++++++++++ examples/ecdsa/Cargo.toml | 2 +- examples/poseidon/Cargo.toml | 24 ++++++++++ examples/poseidon/src/lib.rs | 33 ++++++++++++++ examples/poseidon/tests/abi/mod.rs | 10 +++++ examples/poseidon/tests/poseidon.rs | 30 +++++++++++++ lib/crypto/src/bigint.rs | 23 +++++++++- lib/crypto/src/poseidon2/mod.rs | 69 ++++++++++++++++++++++++++++- 12 files changed, 287 insertions(+), 17 deletions(-) create mode 100644 benches/src/poseidon.rs create mode 100644 examples/poseidon/Cargo.toml create mode 100644 examples/poseidon/src/lib.rs create mode 100644 examples/poseidon/tests/abi/mod.rs create mode 100644 examples/poseidon/tests/poseidon.rs diff --git a/Cargo.lock b/Cargo.lock index ff7be5413..3c46dad00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,19 +1252,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cryptography-example" -version = "0.2.0-alpha.1" -dependencies = [ - "alloy", - "alloy-primitives", - "e2e", - "eyre", - "openzeppelin-stylus", - "stylus-sdk", - "tokio", -] - [[package]] name = "ctr" version = "0.9.2" @@ -1444,6 +1431,19 @@ dependencies = [ "spki", ] +[[package]] +name = "ecdsa-example" +version = "0.2.0-alpha.1" +dependencies = [ + "alloy", + "alloy-primitives", + "e2e", + "eyre", + "openzeppelin-stylus", + "stylus-sdk", + "tokio", +] + [[package]] name = "educe" version = "0.6.0" @@ -2829,6 +2829,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "poseidon-example" +version = "0.2.0-alpha.1" +dependencies = [ + "alloy", + "alloy-primitives", + "e2e", + "eyre", + "openzeppelin-crypto", + "stylus-sdk", + "tokio", +] + [[package]] name = "ppv-lite86" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index 66270beb7..45b6ed99a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ members = [ "examples/basic/token", "examples/basic/script", "examples/ecdsa", + "examples/poseidon", "examples/ownable-two-step", "examples/safe-erc20", "benches", @@ -49,6 +50,7 @@ default-members = [ "examples/access-control", "examples/basic/token", "examples/ecdsa", + "examples/poseidon", ] # Explicitly set the resolver to version 2, which is the default for packages diff --git a/benches/src/lib.rs b/benches/src/lib.rs index bdad0189c..a45d6f1f3 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -21,6 +21,7 @@ pub mod erc20; pub mod erc721; pub mod merkle_proofs; pub mod ownable; +pub mod poseidon; pub mod report; pub mod vesting_wallet; diff --git a/benches/src/main.rs b/benches/src/main.rs index ba06fd578..8d915a559 100644 --- a/benches/src/main.rs +++ b/benches/src/main.rs @@ -1,6 +1,6 @@ use benches::{ access_control, erc1155, erc1155_metadata_uri, erc20, erc721, - merkle_proofs, ownable, report::BenchmarkReport, + merkle_proofs, ownable, poseidon, report::BenchmarkReport, }; use futures::FutureExt; use itertools::Itertools; @@ -15,6 +15,7 @@ async fn main() -> eyre::Result<()> { ownable::bench().boxed(), erc1155::bench().boxed(), erc1155_metadata_uri::bench().boxed(), + poseidon::bench().boxed(), ]; // Run benchmarks max 3 at the same time. diff --git a/benches/src/poseidon.rs b/benches/src/poseidon.rs new file mode 100644 index 000000000..29d9be6cf --- /dev/null +++ b/benches/src/poseidon.rs @@ -0,0 +1,68 @@ +use alloy::{ + network::{AnyNetwork, EthereumWallet}, + primitives::Address, + providers::ProviderBuilder, + sol, + sol_types::SolCall, +}; +use alloy_primitives::bytes; +use e2e::{receipt, Account}; + +use crate::{ + report::{ContractReport, FunctionReport}, + CacheOpt, +}; + +sol!( + #[sol(rpc)] + contract PoseidonExample { + #[derive(Debug)] + function hash(bytes calldata data) external view returns (bytes32 hash); + } +); + +pub async fn bench() -> eyre::Result { + let reports = run_with(CacheOpt::None).await?; + let report = reports + .into_iter() + .try_fold(ContractReport::new("Poseidon"), ContractReport::add)?; + + let cached_reports = run_with(CacheOpt::Bid(0)).await?; + let report = cached_reports + .into_iter() + .try_fold(report, ContractReport::add_cached)?; + + Ok(report) +} + +pub async fn run_with( + cache_opt: CacheOpt, +) -> eyre::Result> { + let alice = Account::new().await?; + let alice_wallet = ProviderBuilder::new() + .network::() + .with_recommended_fillers() + .wallet(EthereumWallet::from(alice.signer.clone())) + .on_http(alice.url().parse()?); + + let contract_addr = deploy(&alice, cache_opt).await?; + + let contract = PoseidonExample::new(contract_addr, &alice_wallet); + + #[rustfmt::skip] + let receipts = vec![ + (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash(bytes!("deadbeef")))?), + ]; + + receipts + .into_iter() + .map(FunctionReport::new) + .collect::>>() +} + +async fn deploy( + account: &Account, + cache_opt: CacheOpt, +) -> eyre::Result
{ + crate::deploy(account, "poseidon", None, cache_opt).await +} diff --git a/examples/ecdsa/Cargo.toml b/examples/ecdsa/Cargo.toml index 2a2291fb5..5844f6078 100644 --- a/examples/ecdsa/Cargo.toml +++ b/examples/ecdsa/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cryptography-example" +name = "ecdsa-example" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/examples/poseidon/Cargo.toml b/examples/poseidon/Cargo.toml new file mode 100644 index 000000000..337b30beb --- /dev/null +++ b/examples/poseidon/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "poseidon-example" +edition.workspace = true +license.workspace = true +repository.workspace = true +publish = false +version.workspace = true + +[dependencies] +openzeppelin-crypto.workspace = true +alloy-primitives.workspace = true +stylus-sdk.workspace = true + +[dev-dependencies] +alloy.workspace = true +e2e.workspace = true +tokio.workspace = true +eyre.workspace = true + +[lib] +crate-type = ["lib", "cdylib"] + +[features] +e2e = [] diff --git a/examples/poseidon/src/lib.rs b/examples/poseidon/src/lib.rs new file mode 100644 index 000000000..eb97c45cf --- /dev/null +++ b/examples/poseidon/src/lib.rs @@ -0,0 +1,33 @@ +#![cfg_attr(not(test), no_main)] +extern crate alloc; + +use alloc::vec::Vec; + +use alloy_primitives::B256; +use openzeppelin_crypto::{ + field::instance::FpVesta, + hash::Hasher, + poseidon2::{instance::vesta::VestaParams, Poseidon2}, +}; +use stylus_sdk::prelude::{entrypoint, public, storage}; + +#[entrypoint] +#[storage] +struct PoseidonExample {} + +#[public] +impl PoseidonExample { + pub fn hash( + &mut self, + data: stylus_sdk::abi::Bytes, + ) -> Result> { + let input = data.to_vec(); + + // Compute hash from bytes. + let mut first_hasher = Poseidon2::::new(); + first_hasher.update(&input); + let hash = first_hasher.finalize(); + + Ok(B256::from(hash)) + } +} diff --git a/examples/poseidon/tests/abi/mod.rs b/examples/poseidon/tests/abi/mod.rs new file mode 100644 index 000000000..0e0d786bd --- /dev/null +++ b/examples/poseidon/tests/abi/mod.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] +use alloy::sol; + +sol!( + #[sol(rpc)] + contract PoseidonExample { + #[derive(Debug)] + function hash(bytes calldata data) external view returns (bytes32 hash); + } +); diff --git a/examples/poseidon/tests/poseidon.rs b/examples/poseidon/tests/poseidon.rs new file mode 100644 index 000000000..3b883ba7e --- /dev/null +++ b/examples/poseidon/tests/poseidon.rs @@ -0,0 +1,30 @@ +#![cfg(feature = "e2e")] + +use alloy_primitives::{bytes, hex, B256}; +use e2e::{Account, ReceiptExt, Revert}; +use eyre::Result; + +use crate::abi::PoseidonExample; + +mod abi; + +// ============================================================================ +// Integration Tests: Poseidon +// ============================================================================ + +#[e2e::test] +async fn poseidon_works(alice: Account) -> Result<()> { + let contract_addr = alice.as_deployer().deploy().await?.address()?; + let contract = PoseidonExample::new(contract_addr, &alice.wallet); + + let PoseidonExample::hashReturn { hash } = + contract.hash(bytes!("deadbeef")).call().await?; + + let expected = B256::from(hex!( + "438ba31003629145d5a99d47392a014833076ab2fbd485ce446ce617cc83e03f" + )); + + assert_eq!(hash, expected); + + Ok(()) +} diff --git a/lib/crypto/src/bigint.rs b/lib/crypto/src/bigint.rs index 1c245a641..5701739b9 100644 --- a/lib/crypto/src/bigint.rs +++ b/lib/crypto/src/bigint.rs @@ -11,7 +11,7 @@ use core::{ #[allow(clippy::module_name_repetitions)] pub use crypto_bigint; -use crypto_bigint::{Integer, Limb, Uint, Word, Zero}; +use crypto_bigint::{Encoding, Integer, Limb, Uint, Word, Zero}; use num_traits::ConstZero; use zeroize::Zeroize; @@ -55,6 +55,9 @@ pub trait BigInteger: /// Number of `usize` limbs representing `Self`. const NUM_LIMBS: usize; + /// Number of bytes in the integer. + const BYTES: usize = Self::NUM_LIMBS * Limb::BYTES; + /// Returns true if this number is odd. /// # Example /// @@ -117,6 +120,16 @@ pub trait BigInteger: /// assert!(!one.get_bit(1)); /// ``` fn get_bit(&self, i: usize) -> bool; + + /// Create bigint from little-endian bytes. + /// + /// # Panics + /// + /// Panic if the number of bytes is not equal to `Self::BYTES`. + fn from_bytes_le(bytes: &[u8]) -> Self; + + /// Convert bigint to little-endian bytes. + fn into_bytes_le(self) -> alloc::vec::Vec; } impl BigInteger for Uint { @@ -141,6 +154,14 @@ impl BigInteger for Uint { fn get_bit(&self, i: usize) -> bool { self.bit(i).into() } + + fn from_bytes_le(bytes: &[u8]) -> Self { + Self::from_le_slice(bytes) + } + + fn into_bytes_le(self) -> alloc::vec::Vec { + self.to_limbs().into_iter().flat_map(|l| l.to_le_bytes()).collect() + } } impl BitIteratorBE for Uint { diff --git a/lib/crypto/src/poseidon2/mod.rs b/lib/crypto/src/poseidon2/mod.rs index 6933f9299..eb48983b3 100644 --- a/lib/crypto/src/poseidon2/mod.rs +++ b/lib/crypto/src/poseidon2/mod.rs @@ -13,7 +13,10 @@ pub mod params; use alloc::{boxed::Box, vec, vec::Vec}; -use crate::{field::prime::PrimeField, poseidon2::params::PoseidonParams}; +use crate::{ + bigint::BigInteger, field::prime::PrimeField, hash::Hasher, + poseidon2::params::PoseidonParams, +}; /// Determines whether poseidon sponge in absorbing or squeezing state. /// In squeezing state, sponge can only squeeze elements. @@ -298,3 +301,67 @@ impl, F: PrimeField> Poseidon2 { self.state[0] += P::ROUND_CONSTANTS[round][0]; } } + +impl, F: PrimeField> Hasher for Poseidon2 { + type Output = [u8; 32]; + + fn update(&mut self, input: impl AsRef<[u8]>) { + for chunk in input.as_ref().chunks(F::BigInt::BYTES) { + // Convert chunk of bytes to a big integer. + let big_int = if chunk.len() == F::BigInt::BYTES { + F::BigInt::from_bytes_le(chunk) + } else { + // If the chunk size is actually smaller, then pad it with + // zeros. + let mut padded = vec![0; F::BigInt::BYTES]; + padded[..chunk.len()].copy_from_slice(chunk); + F::BigInt::from_bytes_le(&padded) + }; + let elem = F::from_bigint(big_int); + self.absorb(&elem); + } + } + + fn finalize(mut self) -> Self::Output { + self.squeeze_batch(32 / F::BigInt::BYTES) + .into_iter() + .flat_map(|elem| elem.into_bigint().into_bytes_le()) + .collect::>() + .try_into() + .expect("invalid output length") + } +} + +#[cfg(test)] +mod tests { + use proptest::proptest; + + use super::*; + use crate::{ + field::instance::FpVesta, + hash::Hasher, + poseidon2::{instance::vesta::VestaParams, Poseidon2}, + }; + + // NOTE: Value of this test mostly because it tests hash on random number of + // inputs without panic, instead of checking actual consistency. + // Real consistency is hard to prove on purely random inputs. + #[test] + fn consistent_hasher() { + proptest!(|(first_input: Vec, second_input: Vec)| { + let mut first_hasher = Poseidon2::::new(); + first_hasher.update(&first_input); + let first_result = first_hasher.finalize(); + + let mut second_hasher = Poseidon2::::new(); + second_hasher.update(&second_input); + let second_result = second_hasher.finalize(); + + if first_input == second_input { + assert_eq!(first_result, second_result); + } else { + assert_ne!(first_result, second_result); + } + }); + } +} From a4e3813e5bbf5fef185f0b1b840f5107db122b73 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 18 Dec 2024 19:48:28 +0400 Subject: [PATCH 02/13] add renegades referenced implementation to benchmark --- Cargo.lock | 129 +++++++++++++++++++++++++ Cargo.toml | 4 +- benches/src/lib.rs | 1 + benches/src/main.rs | 18 ++-- benches/src/poseidon_renegades.rs | 69 +++++++++++++ examples/poseidon-renegades/Cargo.toml | 27 ++++++ examples/poseidon-renegades/src/lib.rs | 46 +++++++++ examples/poseidon/src/lib.rs | 19 ++-- 8 files changed, 297 insertions(+), 16 deletions(-) create mode 100644 benches/src/poseidon_renegades.rs create mode 100644 examples/poseidon-renegades/Cargo.toml create mode 100644 examples/poseidon-renegades/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3c46dad00..538981add 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -577,6 +577,46 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff 0.4.2", + "ark-poly", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ed-on-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71892f265d01650e34988a546b37ea1d2ba1da162a639597a03d1550f26004d8" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + [[package]] name = "ark-ff" version = "0.3.0" @@ -660,6 +700,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", +] + [[package]] name = "ark-serialize" version = "0.3.0" @@ -676,11 +729,23 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ + "ark-serialize-derive", "ark-std 0.4.0", "digest 0.10.7", "num-bigint", ] +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-std" version = "0.3.0" @@ -827,6 +892,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -1063,6 +1139,16 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "constants" +version = "0.1.0" +source = "git+https://github.com/renegade-fi/renegade.git#814e98425c2a0c23df43441677ddd21b5171b6f2" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ed-on-bn254", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1987,6 +2073,15 @@ dependencies = [ "ahash 0.7.8", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -2518,6 +2613,8 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand", + "serde", ] [[package]] @@ -2842,6 +2939,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "poseidon-renegades-example" +version = "0.2.0-alpha.1" +dependencies = [ + "alloy", + "alloy-primitives", + "ark-bn254", + "ark-ec", + "ark-ff 0.4.2", + "e2e", + "eyre", + "renegade-crypto", + "stylus-sdk", + "tokio", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3105,6 +3218,22 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "renegade-crypto" +version = "0.1.0" +source = "git+https://github.com/renegade-fi/renegade.git#814e98425c2a0c23df43441677ddd21b5171b6f2" +dependencies = [ + "ark-ec", + "ark-ff 0.4.2", + "bigdecimal", + "constants", + "itertools 0.10.5", + "lazy_static", + "num-bigint", + "serde", + "serde_json", +] + [[package]] name = "reqwest" version = "0.12.5" diff --git a/Cargo.toml b/Cargo.toml index 45b6ed99a..4caf5dea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,11 @@ members = [ "examples/basic/token", "examples/basic/script", "examples/ecdsa", - "examples/poseidon", "examples/ownable-two-step", "examples/safe-erc20", "benches", + "examples/poseidon", + "examples/poseidon-renegades", ] default-members = [ "contracts", @@ -51,6 +52,7 @@ default-members = [ "examples/basic/token", "examples/ecdsa", "examples/poseidon", + "examples/poseidon-renegades", ] # Explicitly set the resolver to version 2, which is the default for packages diff --git a/benches/src/lib.rs b/benches/src/lib.rs index a45d6f1f3..99004f3b7 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -22,6 +22,7 @@ pub mod erc721; pub mod merkle_proofs; pub mod ownable; pub mod poseidon; +pub mod poseidon_renegades; pub mod report; pub mod vesting_wallet; diff --git a/benches/src/main.rs b/benches/src/main.rs index 8d915a559..9c6d10a5d 100644 --- a/benches/src/main.rs +++ b/benches/src/main.rs @@ -1,6 +1,7 @@ use benches::{ access_control, erc1155, erc1155_metadata_uri, erc20, erc721, - merkle_proofs, ownable, poseidon, report::BenchmarkReport, + merkle_proofs, ownable, poseidon, poseidon_renegades, + report::BenchmarkReport, }; use futures::FutureExt; use itertools::Itertools; @@ -8,14 +9,15 @@ use itertools::Itertools; #[tokio::main] async fn main() -> eyre::Result<()> { let benchmarks = [ - access_control::bench().boxed(), - erc20::bench().boxed(), - erc721::bench().boxed(), - merkle_proofs::bench().boxed(), - ownable::bench().boxed(), - erc1155::bench().boxed(), - erc1155_metadata_uri::bench().boxed(), + // access_control::bench().boxed(), + // erc20::bench().boxed(), + // erc721::bench().boxed(), + // merkle_proofs::bench().boxed(), + // ownable::bench().boxed(), + // erc1155::bench().boxed(), + // erc1155_metadata_uri::bench().boxed(), poseidon::bench().boxed(), + poseidon_renegades::bench().boxed(), ]; // Run benchmarks max 3 at the same time. diff --git a/benches/src/poseidon_renegades.rs b/benches/src/poseidon_renegades.rs new file mode 100644 index 000000000..597cbaf24 --- /dev/null +++ b/benches/src/poseidon_renegades.rs @@ -0,0 +1,69 @@ +use alloy::{ + network::{AnyNetwork, EthereumWallet}, + primitives::Address, + providers::ProviderBuilder, + sol, + sol_types::SolCall, +}; +use alloy_primitives::bytes; +use e2e::{receipt, Account}; + +use crate::{ + report::{ContractReport, FunctionReport}, + CacheOpt, +}; + +sol!( + #[sol(rpc)] + contract PoseidonExample { + #[derive(Debug)] + function hash(bytes calldata data) external view returns (bytes32 hash); + } +); + +pub async fn bench() -> eyre::Result { + let reports = run_with(CacheOpt::None).await?; + let report = reports.into_iter().try_fold( + ContractReport::new("renegades::Poseidon"), + ContractReport::add, + )?; + + let cached_reports = run_with(CacheOpt::Bid(0)).await?; + let report = cached_reports + .into_iter() + .try_fold(report, ContractReport::add_cached)?; + + Ok(report) +} + +pub async fn run_with( + cache_opt: CacheOpt, +) -> eyre::Result> { + let alice = Account::new().await?; + let alice_wallet = ProviderBuilder::new() + .network::() + .with_recommended_fillers() + .wallet(EthereumWallet::from(alice.signer.clone())) + .on_http(alice.url().parse()?); + + let contract_addr = deploy(&alice, cache_opt).await?; + + let contract = PoseidonExample::new(contract_addr, &alice_wallet); + + #[rustfmt::skip] + let receipts = vec![ + (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash(bytes!("deadbeef")))?), + ]; + + receipts + .into_iter() + .map(FunctionReport::new) + .collect::>>() +} + +async fn deploy( + account: &Account, + cache_opt: CacheOpt, +) -> eyre::Result
{ + crate::deploy(account, "poseidon-renegades", None, cache_opt).await +} diff --git a/examples/poseidon-renegades/Cargo.toml b/examples/poseidon-renegades/Cargo.toml new file mode 100644 index 000000000..9909c02f4 --- /dev/null +++ b/examples/poseidon-renegades/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "poseidon-renegades-example" +edition.workspace = true +license.workspace = true +repository.workspace = true +publish = false +version.workspace = true + +[dependencies] +alloy-primitives.workspace = true +stylus-sdk.workspace = true +renegade-crypto = { git = "https://github.com/renegade-fi/renegade.git", package = "renegade-crypto", default-features = false } +ark-ff = "0.4" +ark-ec = "0.4" +ark-bn254 = "0.4.0" + +[dev-dependencies] +alloy.workspace = true +e2e.workspace = true +tokio.workspace = true +eyre.workspace = true + +[lib] +crate-type = ["lib", "cdylib"] + +[features] +e2e = [] diff --git a/examples/poseidon-renegades/src/lib.rs b/examples/poseidon-renegades/src/lib.rs new file mode 100644 index 000000000..8b0bce9c3 --- /dev/null +++ b/examples/poseidon-renegades/src/lib.rs @@ -0,0 +1,46 @@ +#![cfg_attr(not(test), no_main)] +extern crate alloc; + +use alloc::vec::Vec; + +use alloy_primitives::B256; +use ark_ec::Group; +use ark_ff::{BigInteger, Fp256, MontBackend, MontConfig, PrimeField}; +use renegade_crypto::hash::Poseidon2Sponge; +use stylus_sdk::prelude::{entrypoint, public, storage}; + +pub type SystemCurveGroup = ark_bn254::G1Projective; +pub type ScalarField = ::ScalarField; + +// #[derive(MontConfig)] +// #[modulus = +// "21888242871839275222246405745257275088548364400416034343698204186575808495617" +// ] #[generator = "7"] +// pub struct FqConfig; +// pub type FpBN256 = Fp256>; + +#[entrypoint] +#[storage] +struct PoseidonExample {} + +#[public] +impl PoseidonExample { + pub fn hash( + &mut self, + data: stylus_sdk::abi::Bytes, + ) -> Result> { + let input = data.to_vec(); + + let mut hasher = Poseidon2Sponge::new(); + + for i in 0..1 { + let fp = ScalarField::from(i); + hasher.absorb(&fp); + } + + let hash = hasher.squeeze(); + let hash = hash.into_bigint().to_bytes_le(); + + Ok(B256::from_slice(&hash)) + } +} diff --git a/examples/poseidon/src/lib.rs b/examples/poseidon/src/lib.rs index eb97c45cf..58a4f575e 100644 --- a/examples/poseidon/src/lib.rs +++ b/examples/poseidon/src/lib.rs @@ -5,8 +5,8 @@ use alloc::vec::Vec; use alloy_primitives::B256; use openzeppelin_crypto::{ - field::instance::FpVesta, - hash::Hasher, + bigint::BigInteger, + field::{instance::FpVesta, prime::PrimeField}, poseidon2::{instance::vesta::VestaParams, Poseidon2}, }; use stylus_sdk::prelude::{entrypoint, public, storage}; @@ -23,11 +23,16 @@ impl PoseidonExample { ) -> Result> { let input = data.to_vec(); - // Compute hash from bytes. - let mut first_hasher = Poseidon2::::new(); - first_hasher.update(&input); - let hash = first_hasher.finalize(); + let mut hasher = Poseidon2::::new(); - Ok(B256::from(hash)) + for i in 0..1 { + let fp = FpVesta::from(i); + hasher.absorb(&fp); + } + + let hash = hasher.squeeze(); + let hash = hash.into_bigint().into_bytes_le(); + + Ok(B256::from_slice(&hash)) } } From a726252bd0cffd26792c46f657f04001fef2eeb7 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Fri, 27 Dec 2024 15:07:59 +0400 Subject: [PATCH 03/13] add poseidon solidity implementation + wasm opt --- .github/workflows/gas-bench.yml | 3 + benches/src/PoseidonT3.sol | 53 ++++++++++++ benches/src/access_control.rs | 24 ++---- benches/src/erc1155.rs | 23 +---- benches/src/erc1155_metadata_uri.rs | 24 +----- benches/src/erc1155_supply.rs | 23 +---- benches/src/erc20.rs | 23 +---- benches/src/erc721.rs | 23 +---- benches/src/lib.rs | 26 ++++-- benches/src/main.rs | 17 ++-- benches/src/merkle_proofs.rs | 23 +---- benches/src/ownable.rs | 23 +---- benches/src/poseidon.rs | 32 +++---- benches/src/poseidon_renegades.rs | 24 +----- benches/src/poseidon_sol.rs | 112 +++++++++++++++++++++++++ benches/src/report.rs | 87 ++++++++++++++++--- benches/src/vesting_wallet.rs | 25 ++---- examples/poseidon-renegades/src/lib.rs | 2 +- examples/poseidon/src/lib.rs | 19 ++--- lib/crypto/src/field/mod.rs | 38 +++++++-- scripts/bench.sh | 27 +++++- 21 files changed, 387 insertions(+), 264 deletions(-) create mode 100644 benches/src/PoseidonT3.sol create mode 100644 benches/src/poseidon_sol.rs diff --git a/.github/workflows/gas-bench.yml b/.github/workflows/gas-bench.yml index 62c8ed73c..0e91fc1cc 100644 --- a/.github/workflows/gas-bench.yml +++ b/.github/workflows/gas-bench.yml @@ -28,6 +28,9 @@ jobs: - name: Install cargo-stylus run: cargo install cargo-stylus@0.5.3 + - name: Install wasm-opt + run: cargo install wasm-opt@0.116.1 + - name: Install solc run: | curl -LO https://github.com/ethereum/solidity/releases/download/v0.8.24/solc-static-linux diff --git a/benches/src/PoseidonT3.sol b/benches/src/PoseidonT3.sol new file mode 100644 index 000000000..333993bce --- /dev/null +++ b/benches/src/PoseidonT3.sol @@ -0,0 +1,53 @@ +/// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract PoseidonT3 { + uint constant F = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint constant ROUNDS_F = 8; + uint constant ROUNDS_P = 57; + uint constant T = 3; + + uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b; + uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771; + uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7; + uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0; + uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23; + uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911; + uint constant M20 = 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d; + uint constant M21 = 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa; + uint constant M22 = 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0; + + // Based on https://github.com/chancehudson/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol + function hash(uint[2] memory inputs) public pure returns (uint) { + uint[195] memory C = [0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161]; + + uint state0 = 0; + uint state1 = inputs[0]; + uint state2 = inputs[1]; + uint swap0 = 0; + uint swap1 = inputs[0]; + uint swap2 = inputs[1]; + for (uint8 r = 0; r < ROUNDS_F + ROUNDS_P; r++) { + state0 = addmod(swap0, C[r * T + 0], F); + state1 = addmod(swap1, C[r * T + 1], F); + state2 = addmod(swap2, C[r * T + 2], F); + + state0 = pow5mod(state0); + if (r < ROUNDS_F / 2 || r >= ROUNDS_F / 2 + ROUNDS_P) { + state1 = pow5mod(state1); + state2 = pow5mod(state2); + } + + swap0 = addmod(addmod(addmod(0, mulmod(state0, M00, F), F), mulmod(state1, M10, F), F), mulmod(state2, M20, F), F); + swap1 = addmod(addmod(addmod(0, mulmod(state0, M01, F), F), mulmod(state1, M11, F), F), mulmod(state2, M21, F), F); + swap2 = addmod(addmod(addmod(0, mulmod(state0, M02, F), F), mulmod(state1, M12, F), F), mulmod(state2, M22, F), F); + } + return swap0; + } + + function pow5mod(uint i) public pure returns (uint) { + uint a = mulmod(i, i, F); + uint c = mulmod(a, a, F); + return mulmod(i, c, F); + } +} \ No newline at end of file diff --git a/benches/src/access_control.rs b/benches/src/access_control.rs index 12ccfaa80..078e90550 100644 --- a/benches/src/access_control.rs +++ b/benches/src/access_control.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -37,21 +37,10 @@ const NEW_ADMIN_ROLE: [u8; 32] = hex!("879ce0d4bfd332649ca3552efe772a38d64a315eb70ab69689fd309c735946b5"); pub async fn bench() -> eyre::Result { - let receipts = run_with(CacheOpt::None).await?; - let report = receipts - .into_iter() - .try_fold(ContractReport::new("AccessControl"), ContractReport::add)?; - - let cached_receipts = run_with(CacheOpt::Bid(0)).await?; - let report = cached_receipts - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("AccessControl", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { + +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_addr = alice.address(); let alice_wallet = ProviderBuilder::new() @@ -91,10 +80,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = AccessControl::constructorCall {}; let args = alloy::hex::encode(args.abi_encode()); crate::deploy(account, "access-control", Some(args), cache_opt).await diff --git a/benches/src/erc1155.rs b/benches/src/erc1155.rs index e4431543e..27ab3accf 100644 --- a/benches/src/erc1155.rs +++ b/benches/src/erc1155.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -30,22 +30,10 @@ sol!( ); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Erc1155"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Erc1155", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_addr = alice.address(); let alice_wallet = ProviderBuilder::new() @@ -105,9 +93,6 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ crate::deploy(account, "erc1155", None, cache_opt).await } diff --git a/benches/src/erc1155_metadata_uri.rs b/benches/src/erc1155_metadata_uri.rs index 24a28e769..88e3c5cd0 100644 --- a/benches/src/erc1155_metadata_uri.rs +++ b/benches/src/erc1155_metadata_uri.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -29,23 +29,10 @@ const BASE_URI: &str = "https://github.com"; const TOKEN_URI: &str = "/some/token/uri"; pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports.into_iter().try_fold( - ContractReport::new("Erc1155MetadataUri"), - ContractReport::add, - )?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Erc1155MetadataUri", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -74,10 +61,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = Erc1155MetadataUriExample::constructorCall { uri_: URI.to_owned() }; let args = alloy::hex::encode(args.abi_encode()); diff --git a/benches/src/erc1155_supply.rs b/benches/src/erc1155_supply.rs index 448e15272..943906435 100644 --- a/benches/src/erc1155_supply.rs +++ b/benches/src/erc1155_supply.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -24,22 +24,10 @@ sol!( ); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Erc1155Supply"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Erc1155Supply", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_addr = alice.address(); let alice_wallet = ProviderBuilder::new() @@ -71,9 +59,6 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ crate::deploy(account, "erc1155-supply", None, cache_opt).await } diff --git a/benches/src/erc20.rs b/benches/src/erc20.rs index bcf63435e..1e1467673 100644 --- a/benches/src/erc20.rs +++ b/benches/src/erc20.rs @@ -11,7 +11,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -43,22 +43,10 @@ const TOKEN_SYMBOL: &str = "TTK"; const CAP: U256 = uint!(1_000_000_U256); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Erc20"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Erc20", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_addr = alice.address(); let alice_wallet = ProviderBuilder::new() @@ -105,10 +93,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = Erc20Example::constructorCall { name_: TOKEN_NAME.to_owned(), symbol_: TOKEN_SYMBOL.to_owned(), diff --git a/benches/src/erc721.rs b/benches/src/erc721.rs index b00729a19..f606fee64 100644 --- a/benches/src/erc721.rs +++ b/benches/src/erc721.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -33,22 +33,10 @@ sol!( sol!("../examples/erc721/src/constructor.sol"); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Erc721"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Erc721", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_addr = alice.address(); let alice_wallet = ProviderBuilder::new() @@ -96,10 +84,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = Erc721Example::constructorCall {}; let args = alloy::hex::encode(args.abi_encode()); crate::deploy(account, "erc721", Some(args), cache_opt).await diff --git a/benches/src/lib.rs b/benches/src/lib.rs index 99004f3b7..877cf1c5e 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -23,6 +23,7 @@ pub mod merkle_proofs; pub mod ownable; pub mod poseidon; pub mod poseidon_renegades; +pub mod poseidon_sol; pub mod report; pub mod vesting_wallet; @@ -38,9 +39,10 @@ struct ArbOtherFields { /// Cache options for the contract. /// `Bid(0)` will likely cache the contract on the nitro test node. #[derive(Clone)] -pub enum CacheOpt { +pub enum Opt { None, - Bid(u32), + Cache, + WasmOpt, } type ArbTxReceipt = @@ -50,16 +52,25 @@ async fn deploy( account: &Account, contract_name: &str, args: Option, - cache_opt: CacheOpt, + opt: Opt, ) -> eyre::Result
{ let manifest_dir = std::env::current_dir().context("should get current dir from env")?; + let contract_type = match opt { + Opt::WasmOpt => "example_opt", + Opt::None | Opt::Cache => "example", + }; + let wasm_path = manifest_dir .join("target") .join("wasm32-unknown-unknown") .join("release") - .join(format!("{}_example.wasm", contract_name.replace('-', "_"))); + .join(format!( + "{}_{}.wasm", + contract_name.replace('-', "_"), + contract_type + )); let sol_path = args.as_ref().map(|_| { manifest_dir .join("examples") @@ -92,8 +103,11 @@ async fn deploy( .expect("should deploy contract") .address()?; - if let CacheOpt::Bid(bid) = cache_opt { - cache_contract(account, address, bid)?; + match opt { + Opt::Cache | Opt::WasmOpt => { + cache_contract(account, address, 0)?; + } + Opt::None => {} } Ok(address) diff --git a/benches/src/main.rs b/benches/src/main.rs index 9c6d10a5d..daca41058 100644 --- a/benches/src/main.rs +++ b/benches/src/main.rs @@ -1,6 +1,6 @@ use benches::{ access_control, erc1155, erc1155_metadata_uri, erc20, erc721, - merkle_proofs, ownable, poseidon, poseidon_renegades, + merkle_proofs, ownable, poseidon, poseidon_renegades, poseidon_sol, report::BenchmarkReport, }; use futures::FutureExt; @@ -9,14 +9,15 @@ use itertools::Itertools; #[tokio::main] async fn main() -> eyre::Result<()> { let benchmarks = [ - // access_control::bench().boxed(), - // erc20::bench().boxed(), - // erc721::bench().boxed(), - // merkle_proofs::bench().boxed(), - // ownable::bench().boxed(), - // erc1155::bench().boxed(), - // erc1155_metadata_uri::bench().boxed(), + access_control::bench().boxed(), + erc20::bench().boxed(), + erc721::bench().boxed(), + merkle_proofs::bench().boxed(), + ownable::bench().boxed(), + erc1155::bench().boxed(), + erc1155_metadata_uri::bench().boxed(), poseidon::bench().boxed(), + poseidon_sol::bench().boxed(), poseidon_renegades::bench().boxed(), ]; diff --git a/benches/src/merkle_proofs.rs b/benches/src/merkle_proofs.rs index fd9865203..5867d5e61 100644 --- a/benches/src/merkle_proofs.rs +++ b/benches/src/merkle_proofs.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -61,22 +61,10 @@ const PROOF: [[u8; 32]; 16] = bytes_array! { }; pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("MerkleProofs"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("MerkleProofs", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -101,9 +89,6 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ crate::deploy(account, "merkle-proofs", None, cache_opt).await } diff --git a/benches/src/ownable.rs b/benches/src/ownable.rs index bf9e4b60c..d7709ba7a 100644 --- a/benches/src/ownable.rs +++ b/benches/src/ownable.rs @@ -9,7 +9,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -24,22 +24,10 @@ sol!( sol!("../examples/ownable/src/constructor.sol"); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Ownable"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Ownable", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -75,10 +63,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = OwnableExample::constructorCall { initialOwner: account.address() }; let args = alloy::hex::encode(args.abi_encode()); diff --git a/benches/src/poseidon.rs b/benches/src/poseidon.rs index 29d9be6cf..a0daecc98 100644 --- a/benches/src/poseidon.rs +++ b/benches/src/poseidon.rs @@ -1,3 +1,5 @@ +use std::future::Future; + use alloy::{ network::{AnyNetwork, EthereumWallet}, primitives::Address, @@ -5,39 +7,28 @@ use alloy::{ sol, sol_types::SolCall, }; -use alloy_primitives::bytes; +use alloy_primitives::uint; use e2e::{receipt, Account}; +use futures::FutureExt; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( #[sol(rpc)] contract PoseidonExample { #[derive(Debug)] - function hash(bytes calldata data) external view returns (bytes32 hash); + function hash(uint256[2] memory inputs) external view returns (uint256 hash); } ); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("Poseidon"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("Poseidon", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -51,7 +42,7 @@ pub async fn run_with( #[rustfmt::skip] let receipts = vec![ - (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash(bytes!("deadbeef")))?), + (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash([uint!(123_U256), uint!(123456_U256)]))?), ]; receipts @@ -60,9 +51,6 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ crate::deploy(account, "poseidon", None, cache_opt).await } diff --git a/benches/src/poseidon_renegades.rs b/benches/src/poseidon_renegades.rs index 597cbaf24..2be18a2fa 100644 --- a/benches/src/poseidon_renegades.rs +++ b/benches/src/poseidon_renegades.rs @@ -10,7 +10,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -22,23 +22,10 @@ sol!( ); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports.into_iter().try_fold( - ContractReport::new("renegades::Poseidon"), - ContractReport::add, - )?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("renegades::Poseidon", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -61,9 +48,6 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ crate::deploy(account, "poseidon-renegades", None, cache_opt).await } diff --git a/benches/src/poseidon_sol.rs b/benches/src/poseidon_sol.rs new file mode 100644 index 000000000..fdd94b0b8 --- /dev/null +++ b/benches/src/poseidon_sol.rs @@ -0,0 +1,112 @@ +use alloy::{ + network::{AnyNetwork, EthereumWallet}, + primitives::Address, + providers::ProviderBuilder, + sol, + sol_types::SolCall, +}; +use alloy_primitives::uint; +use e2e::{receipt, Account}; + +use crate::report::{ContractReport, FunctionReport}; + +sol!( + #[sol(rpc)] + contract PoseidonExample { + #[derive(Debug)] + function hash(uint256[2] memory inputs) external view returns (uint256 hash); + } +); + +pub async fn bench() -> eyre::Result { + let reports = run().await?; + let report = reports + .into_iter() + .try_fold(ContractReport::new("Sol:Poseidon"), ContractReport::add)?; + + Ok(report) +} + +pub async fn run() -> eyre::Result> { + let alice = Account::new().await?; + let alice_wallet = ProviderBuilder::new() + .network::() + .with_recommended_fillers() + .wallet(EthereumWallet::from(alice.signer.clone())) + .on_http(alice.url().parse()?); + + let contract_addr = deploy(&alice).await?; + + let contract = PoseidonExample::new(contract_addr, &alice_wallet); + + #[rustfmt::skip] + let receipts = vec![ + (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash([uint!(123_U256), uint!(123456_U256)]))?), + ]; + + receipts + .into_iter() + .map(FunctionReport::new) + .collect::>>() +} + +pub async fn deploy(account: &Account) -> eyre::Result
{ + let contract = PoseidonT3::deploy(&account.wallet).await?; + Ok(*contract.address()) +} + +sol! { + #[allow(missing_docs)] + // Built with Remix IDE; solc v0.8.21+commit.d9974bed + #[sol(rpc, bytecode="608060405234801561000f575f80fd5b506128a28061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063561558fe146100385780638cc13d8a14610068575b5f80fd5b610052600480360381019061004d919061268f565b610098565b60405161005f91906126c9565b60405180910390f35b610082600480360381019061007d91906126e2565b61246b565b60405161008f91906126c9565b60405180910390f35b5f806040518061186001604052807f0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e81526020017ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e86481526020017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f581526020017f2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d081526020017f2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf281526020017f0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa81526020017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d81526020017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb7881526020017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63281526020017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d42881526020017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f681526020017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c81526020017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de55981526020017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f681526020017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870581526020017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d81526020017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be82881526020017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b981526020017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa681526020017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc81526020017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd181526020017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d0981526020017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea56581526020017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f981526020017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b581526020017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d6028081526020017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b81526020017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec081526020017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c46081526020017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc081526020017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e81526020017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f844881526020017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f81526020017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e81526020017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f81526020017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88781526020017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c881526020017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf181526020017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5381526020017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c81526020017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e81526020017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3881526020017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a73520681526020017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad81526020017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c81526020017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef81526020017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c9181526020017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a081526020017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c075081526020017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e81526020017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e81526020017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab81526020017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a7009239331181526020017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a81526020017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da981526020017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c456552981526020017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50281526020017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b5481526020017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef81526020017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a81526020017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd80481526020017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd64981526020017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a81526020017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff181526020017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d381526020017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8981526020017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be81526020017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af181526020017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c581526020017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f10081526020017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c296781526020017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e481526020017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b0281526020017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b64681526020017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d81526020017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc681526020017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da481526020017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e81526020017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea065462681526020017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb81526020017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1381526020017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b375881526020017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef81526020017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e981526020017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d81526020017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f281526020017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003581526020017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b14781526020017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac281526020017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a81526020017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc81526020017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f81526020017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6981526020017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a81526020017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d181526020017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b881526020017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a81526020017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c78581526020017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7781526020017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a6781526020017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c7172781526020017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b81526020017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d281526020017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe81526020017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351281526020017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d81526020017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda981526020017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80881526020017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae181526020017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e6497381526020017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0981526020017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af3881526020017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd81526020017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828481526020017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af81526020017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee46681526020017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad81526020017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c822514508681526020017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c381526020017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80081526020017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb681526020017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e781526020017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b81526020017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b81526020017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c9859181526020017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17881526020017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d4081526020017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d481526020017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423381526020017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b16887381526020017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d81526020017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc081526020017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb81526020017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f932647887581526020017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e81526020017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f01981526020017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b81526020017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5981526020017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f81526020017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a881526020017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894881526020017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f81526020017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f81526020017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14281526020017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b81526020017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f2381526020017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c081526020017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a81526020017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b581526020017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5881526020017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f281526020017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b81526020017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0181526020017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b181526020017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b81526020017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d81526020017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec81526020017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb281526020017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79281526020017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e3686081526020017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d81526020017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611181526020017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c71181526020017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb81526020017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33681526020017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a81526020017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf186081526020017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d681526020017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b81526020017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b81526020017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45181526020017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c55681526020017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f7081526020017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7781526020017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea81526020017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d81526020017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63081526020017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f81526020017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd7881526020017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc81526020017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb81526020017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d6081526020017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f81526020017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a481526020017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f181526020017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc81526020017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf0881526020017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb2410081526020017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232081526020017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad87081526020017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba81526020017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f881526020017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab181526020017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d2281526020017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516181525090505f80845f60028110611da657611da561270d565b5b602002015190505f85600160028110611dc257611dc161270d565b5b602002015190505f80875f60028110611dde57611ddd61270d565b5b602002015190505f88600160028110611dfa57611df961270d565b5b602002015190505f5b60396008611e119190612767565b8160ff16101561245b577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611e4a57611e4961279a565b5b885f60038460ff16611e5c91906127c7565b611e669190612767565b60c38110611e7757611e7661270d565b5b6020020151850896507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611eaf57611eae61279a565b5b88600160038460ff16611ec291906127c7565b611ecc9190612767565b60c38110611edd57611edc61270d565b5b6020020151840895507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611f1557611f1461279a565b5b88600260038460ff16611f2891906127c7565b611f329190612767565b60c38110611f4357611f4261270d565b5b602002015183089450611f558761246b565b965060026008611f659190612808565b8160ff161080611f915750603960026008611f809190612808565b611f8a9190612767565b8160ff1610155b15611fad57611f9f8661246b565b9550611faa8561246b565b94505b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611fdc57611fdb61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061200b5761200a61279a565b5b7f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061205d5761205c61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061208c5761208b61279a565b5b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e08a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806120de576120dd61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061210d5761210c61279a565b5b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b8d095f08080893507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121655761216461279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121945761219361279a565b5b7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121e6576121e561279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122155761221461279a565b5b7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe238a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122675761226661279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122965761229561279a565b5b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd7718d095f08080892507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122ee576122ed61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061231d5761231c61279a565b5b7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e087097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061236f5761236e61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061239e5761239d61279a565b5b7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee29118a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806123f0576123ef61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061241f5761241e61279a565b5b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a78d095f0808089150808061245390612844565b915050611e03565b5082975050505050505050919050565b5f807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061249c5761249b61279a565b5b83840990505f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806124d1576124d061279a565b5b82830990507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806125055761250461279a565b5b81850992505050919050565b5f604051905090565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61256882612522565b810181811067ffffffffffffffff8211171561258757612586612532565b5b80604052505050565b5f612599612511565b90506125a5828261255f565b919050565b5f67ffffffffffffffff8211156125c4576125c3612532565b5b602082029050919050565b5f80fd5b5f819050919050565b6125e5816125d3565b81146125ef575f80fd5b50565b5f81359050612600816125dc565b92915050565b5f612618612613846125aa565b612590565b90508060208402830185811115612632576126316125cf565b5b835b8181101561265b578061264788826125f2565b845260208401935050602081019050612634565b5050509392505050565b5f82601f8301126126795761267861251e565b5b6002612686848285612606565b91505092915050565b5f604082840312156126a4576126a361251a565b5b5f6126b184828501612665565b91505092915050565b6126c3816125d3565b82525050565b5f6020820190506126dc5f8301846126ba565b92915050565b5f602082840312156126f7576126f661251a565b5b5f612704848285016125f2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612771826125d3565b915061277c836125d3565b92508282019050808211156127945761279361273a565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6127d1826125d3565b91506127dc836125d3565b92508282026127ea816125d3565b915082820484148315176128015761280061273a565b5b5092915050565b5f612812826125d3565b915061281d836125d3565b92508261282d5761282c61279a565b5b828204905092915050565b5f60ff82169050919050565b5f61284e82612838565b915060ff82036128615761286061273a565b5b60018201905091905056fea2646970667358221220aedcc192d50a90a370e758fb76fe1f7746e2fedf56005c74f9cf6bd30ef793d464736f6c63430008150033")] + contract PoseidonT3 { + uint constant F = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint constant ROUNDS_F = 8; + uint constant ROUNDS_P = 57; + uint constant T = 3; + + uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b; + uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771; + uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7; + uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0; + uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23; + uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911; + uint constant M20 = 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d; + uint constant M21 = 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa; + uint constant M22 = 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0; + + // Based on https://github.com/chancehudson/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol + function hash(uint[2] memory inputs) public pure returns (uint) { + uint[195] memory C = [0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161]; + + uint state0 = 0; + uint state1 = inputs[0]; + uint state2 = inputs[1]; + uint swap0 = 0; + uint swap1 = inputs[0]; + uint swap2 = inputs[1]; + for (uint8 r = 0; r < ROUNDS_F + ROUNDS_P; r++) { + state0 = addmod(swap0, C[r * T + 0], F); + state1 = addmod(swap1, C[r * T + 1], F); + state2 = addmod(swap2, C[r * T + 2], F); + + state0 = pow5mod(state0); + if (r < ROUNDS_F / 2 || r >= ROUNDS_F / 2 + ROUNDS_P) { + state1 = pow5mod(state1); + state2 = pow5mod(state2); + } + + swap0 = addmod(addmod(addmod(0, mulmod(state0, M00, F), F), mulmod(state1, M10, F), F), mulmod(state2, M20, F), F); + swap1 = addmod(addmod(addmod(0, mulmod(state0, M01, F), F), mulmod(state1, M11, F), F), mulmod(state2, M21, F), F); + swap2 = addmod(addmod(addmod(0, mulmod(state0, M02, F), F), mulmod(state1, M12, F), F), mulmod(state2, M22, F), F); + } + return swap0; + } + + function pow5mod(uint i) public pure returns (uint) { + uint a = mulmod(i, i, F); + uint c = mulmod(a, a, F); + return mulmod(i, c, F); + } + } +} diff --git a/benches/src/report.rs b/benches/src/report.rs index 49b5fe70f..98ef943c4 100644 --- a/benches/src/report.rs +++ b/benches/src/report.rs @@ -1,6 +1,6 @@ -use std::{collections::HashMap, fmt::Display}; +use std::{collections::HashMap, fmt::Display, future::Future}; -use crate::{ArbOtherFields, ArbTxReceipt}; +use crate::{ArbOtherFields, ArbTxReceipt, Opt}; const SEPARATOR: &str = "::"; @@ -24,14 +24,40 @@ pub struct ContractReport { contract: String, functions: Vec, functions_cached: Vec, + functions_wasm_opt_cached: Vec, } impl ContractReport { + pub async fn generate< + F: Future>>, + >( + name: &str, + run: impl Fn(Opt) -> F, + ) -> eyre::Result { + let reports = run(Opt::None).await?; + let report = reports + .into_iter() + .try_fold(ContractReport::new(name), ContractReport::add)?; + + let cached_reports = run(Opt::Cache).await?; + let report = cached_reports + .into_iter() + .try_fold(report, ContractReport::add_cached)?; + + let wasm_opt_cached_reports = run(Opt::WasmOpt).await?; + let report = wasm_opt_cached_reports + .into_iter() + .try_fold(report, ContractReport::add_wasm_opt_cached)?; + + Ok(report) + } + pub fn new(contract: &str) -> Self { ContractReport { contract: contract.to_owned(), functions: vec![], functions_cached: vec![], + functions_wasm_opt_cached: vec![], } } @@ -48,6 +74,14 @@ impl ContractReport { Ok(self) } + pub fn add_wasm_opt_cached( + mut self, + fn_report: FunctionReport, + ) -> eyre::Result { + self.functions_wasm_opt_cached.push(fn_report); + Ok(self) + } + fn signature_max_len(&self) -> usize { let prefix_len = self.contract.len() + SEPARATOR.len(); self.functions @@ -72,6 +106,14 @@ impl ContractReport { .max() .unwrap_or_default() } + + fn gas_wasm_opt_cached_max_len(&self) -> usize { + self.functions_wasm_opt_cached + .iter() + .map(|FunctionReport { gas, .. }| gas.to_string().len()) + .max() + .unwrap_or_default() + } } #[derive(Debug, Default)] @@ -100,6 +142,7 @@ impl BenchmarkReport { impl Display for BenchmarkReport { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { const HEADER_SIG: &str = "Contract::function"; + const HEADER_WASM_OPT_GAS_CACHED: &str = "WASM Opt & Cached"; const HEADER_GAS_CACHED: &str = "Cached"; const HEADER_GAS: &str = "Not Cached"; @@ -107,40 +150,58 @@ impl Display for BenchmarkReport { let width1 = self.column_width(ContractReport::signature_max_len, HEADER_SIG); let width2 = self.column_width( + ContractReport::gas_wasm_opt_cached_max_len, + HEADER_WASM_OPT_GAS_CACHED, + ); + let width3 = self.column_width( ContractReport::gas_cached_max_len, HEADER_GAS_CACHED, ); - let width3 = self.column_width(ContractReport::gas_max_len, HEADER_GAS); + let width4 = self.column_width(ContractReport::gas_max_len, HEADER_GAS); // Print headers for the table columns. writeln!( f, - "| {HEADER_SIG:width2$} | {HEADER_GAS:>width3$} |" + "| {HEADER_SIG:width2$} | {HEADER_GAS_CACHED:>width3$} | {HEADER_GAS:>width4$} |" )?; writeln!( f, - "| {:->width1$} | {:->width2$} | {:->width3$} |", - "", "", "" + "| {:->width1$} | {:->width2$} | {:->width3$} | {:->width4$} |", + "", "", "", "", )?; // Merging a non-cached gas report with a cached one. for report in &self.0 { let prefix = format!("{}{SEPARATOR}", report.contract); - let gas: HashMap<_, _> = report - .functions + + let wasm_opt_cached: HashMap<_, _> = report + .functions_wasm_opt_cached + .iter() + .map(|func| (&*func.sig, func.gas)) + .collect(); + + let gas_cached: HashMap<_, _> = report + .functions_cached .iter() .map(|func| (&*func.sig, func.gas)) .collect(); - for report_cached in &report.functions_cached { - let sig = &*report_cached.sig; - let gas_cached = &report_cached.gas; - let gas = gas[sig]; + for report in &report.functions { + let sig = &*report.sig; + let gas_wasm_opt_cached = wasm_opt_cached + .get(sig) + .map(u128::to_string) + .unwrap_or("—".to_string()); + let gas_cached = gas_cached + .get(sig) + .map(u128::to_string) + .unwrap_or("—".to_string()); + let gas = &report.gas; let full_sig = format!("{prefix}{sig}"); writeln!( f, - "| {full_sig:width2$} | {gas:>width3$} |" + "| {full_sig:width2$} | {gas_cached:>width3$} | {gas:>width4$} |" )?; } } diff --git a/benches/src/vesting_wallet.rs b/benches/src/vesting_wallet.rs index 484d335cb..977efcb83 100644 --- a/benches/src/vesting_wallet.rs +++ b/benches/src/vesting_wallet.rs @@ -11,7 +11,7 @@ use e2e::{receipt, Account}; use crate::{ report::{ContractReport, FunctionReport}, - CacheOpt, + Opt, }; sol!( @@ -49,22 +49,10 @@ const TOKEN_SYMBOL: &str = "TTK"; const CAP: U256 = uint!(1_000_000_U256); pub async fn bench() -> eyre::Result { - let reports = run_with(CacheOpt::None).await?; - let report = reports - .into_iter() - .try_fold(ContractReport::new("VestingWallet"), ContractReport::add)?; - - let cached_reports = run_with(CacheOpt::Bid(0)).await?; - let report = cached_reports - .into_iter() - .try_fold(report, ContractReport::add_cached)?; - - Ok(report) + ContractReport::generate("VestingWallet", run).await } -pub async fn run_with( - cache_opt: CacheOpt, -) -> eyre::Result> { +pub async fn run(cache_opt: Opt) -> eyre::Result> { let alice = Account::new().await?; let alice_wallet = ProviderBuilder::new() .network::() @@ -105,10 +93,7 @@ pub async fn run_with( .collect::>>() } -async fn deploy( - account: &Account, - cache_opt: CacheOpt, -) -> eyre::Result
{ +async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ let args = VestingWalletExample::constructorCall { beneficiary: account.address(), startTimestamp: START_TIMESTAMP, @@ -120,7 +105,7 @@ async fn deploy( async fn deploy_token( account: &Account, - cache_opt: CacheOpt, + cache_opt: Opt, ) -> eyre::Result
{ let args = Erc20Example::constructorCall { name_: TOKEN_NAME.to_owned(), diff --git a/examples/poseidon-renegades/src/lib.rs b/examples/poseidon-renegades/src/lib.rs index 8b0bce9c3..d5d2167ea 100644 --- a/examples/poseidon-renegades/src/lib.rs +++ b/examples/poseidon-renegades/src/lib.rs @@ -33,7 +33,7 @@ impl PoseidonExample { let mut hasher = Poseidon2Sponge::new(); - for i in 0..1 { + for i in 0..2 { let fp = ScalarField::from(i); hasher.absorb(&fp); } diff --git a/examples/poseidon/src/lib.rs b/examples/poseidon/src/lib.rs index 58a4f575e..2ce3de5ce 100644 --- a/examples/poseidon/src/lib.rs +++ b/examples/poseidon/src/lib.rs @@ -3,9 +3,9 @@ extern crate alloc; use alloc::vec::Vec; -use alloy_primitives::B256; +use alloy_primitives::U256; use openzeppelin_crypto::{ - bigint::BigInteger, + bigint::{crypto_bigint::Uint, BigInteger}, field::{instance::FpVesta, prime::PrimeField}, poseidon2::{instance::vesta::VestaParams, Poseidon2}, }; @@ -17,22 +17,19 @@ struct PoseidonExample {} #[public] impl PoseidonExample { - pub fn hash( - &mut self, - data: stylus_sdk::abi::Bytes, - ) -> Result> { - let input = data.to_vec(); - + pub fn hash(&mut self, inputs: [U256; 2]) -> Result> { let mut hasher = Poseidon2::::new(); - for i in 0..1 { - let fp = FpVesta::from(i); + for input in inputs.iter() { + let fp = FpVesta::from_bigint(Uint::from_bytes_le( + &input.to_le_bytes_vec(), + )); hasher.absorb(&fp); } let hash = hasher.squeeze(); let hash = hash.into_bigint().into_bytes_le(); - Ok(B256::from_slice(&hash)) + Ok(U256::from_le_slice(&hash)) } } diff --git a/lib/crypto/src/field/mod.rs b/lib/crypto/src/field/mod.rs index 03333f6d2..a5ce76d3b 100644 --- a/lib/crypto/src/field/mod.rs +++ b/lib/crypto/src/field/mod.rs @@ -114,20 +114,40 @@ pub trait Field: /// sets `self` to `self.inverse().unwrap()`. fn inverse_in_place(&mut self) -> Option<&mut Self>; - /// Returns `self^exp`, where `exp` is an integer represented with `u64` - /// limbs. - /// Least significant limb first. + /// Returns `self^exp`, where `exp` is an integer. + /// + /// NOTE: Consumers should pass `exp`'s type `S` with the least bit size + /// possible. + /// e.g. for `pow(12)` u8 type is small enough to represent `12`. #[must_use] fn pow(&self, exp: S) -> Self { - let mut res = Self::one(); + // Variant `Option::::None` corresponds to `one`. + // This approach removes pointless multiplications by one, that + // are still expensive. + let mut res: Option = None; - for i in exp.bit_be_trimmed_iter() { - res.square_in_place(); + for has_bit in exp.bit_be_trimmed_iter() { + // If res is not empty, square it. + if let Some(res) = &mut res { + res.square_in_place(); + } - if i { - res *= self; + // If bit is set, + if has_bit { + match res { + None => { + // and res is empty, set it to self. + res = Some(*self); + } + Some(ref mut res) => { + // and res is not empty, multiply it by self. + *res *= self; + } + } } } - res + + // If res is empty, return one. + res.unwrap_or(Self::ONE) } } diff --git a/scripts/bench.sh b/scripts/bench.sh index 4cc0f1bd3..3a93fdb24 100755 --- a/scripts/bench.sh +++ b/scripts/bench.sh @@ -5,12 +5,37 @@ MYDIR=$(realpath "$(dirname "$0")") cd "$MYDIR" cd .. +# Optimize contract's wasm binary by crate name. +opt_wasm () { + local CONTRACT_CRATE_NAME=$1 + local CONTRACT_BIN_NAME="${CONTRACT_CRATE_NAME//-/_}.wasm" + local CONTRACT_OPT_BIN_NAME="${CONTRACT_CRATE_NAME//-/_}_opt.wasm" + + echo + echo "Optimising $CONTRACT_CRATE_NAME WASM binary" + # https://rustwasm.github.io/book/reference/code-size.html + wasm-opt -O3 -o ./target/wasm32-unknown-unknown/release/"$CONTRACT_OPT_BIN_NAME" ./target/wasm32-unknown-unknown/release/"$CONTRACT_BIN_NAME" +} + +# Retrieve all alphanumeric contract's crate names in `./examples` directory. +get_example_crate_names () { + # shellcheck disable=SC2038 + # NOTE: optimistically relying on the 'name = ' string at Cargo.toml file + find ./examples -maxdepth 2 -type f -name "Cargo.toml" | xargs grep 'name = ' | grep -oE '".*"' | tr -d "'\"" +} + cargo build --release --target wasm32-unknown-unknown -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort +# Optimize contract's wasm for gas usage. +for CRATE_NAME in $(get_example_crate_names) +do + opt_wasm "$CRATE_NAME" +done + export RPC_URL=http://localhost:8547 # No need to compile benchmarks with `--release` -# since this only runs the benchmarking code and the contracts have already been compiled with `--release` +# since this only runs the benchmarking code and the contracts have already been compiled with `--release`. cargo run -p benches echo "NOTE: To measure non cached contract's gas usage correctly, From 1af5b0baae94ec95cdbfc6594fd5401db2600aae Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 08:50:57 +0400 Subject: [PATCH 04/13] remove renegades poseidon implementation --- Cargo.lock | 129 ------------------------- Cargo.toml | 2 - benches/src/lib.rs | 1 - benches/src/main.rs | 4 +- benches/src/poseidon_renegades.rs | 53 ---------- examples/poseidon-renegades/Cargo.toml | 27 ------ examples/poseidon-renegades/src/lib.rs | 46 --------- 7 files changed, 1 insertion(+), 261 deletions(-) delete mode 100644 benches/src/poseidon_renegades.rs delete mode 100644 examples/poseidon-renegades/Cargo.toml delete mode 100644 examples/poseidon-renegades/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 538981add..3c46dad00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -577,46 +577,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" -[[package]] -name = "ark-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" -dependencies = [ - "ark-ec", - "ark-ff 0.4.2", - "ark-std 0.4.0", -] - -[[package]] -name = "ark-ec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" -dependencies = [ - "ark-ff 0.4.2", - "ark-poly", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.2", - "itertools 0.10.5", - "num-traits", - "zeroize", -] - -[[package]] -name = "ark-ed-on-bn254" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71892f265d01650e34988a546b37ea1d2ba1da162a639597a03d1550f26004d8" -dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ff 0.4.2", - "ark-std 0.4.0", -] - [[package]] name = "ark-ff" version = "0.3.0" @@ -700,19 +660,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ark-poly" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" -dependencies = [ - "ark-ff 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "hashbrown 0.13.2", -] - [[package]] name = "ark-serialize" version = "0.3.0" @@ -729,23 +676,11 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "ark-serialize-derive", "ark-std 0.4.0", "digest 0.10.7", "num-bigint", ] -[[package]] -name = "ark-serialize-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-std" version = "0.3.0" @@ -892,17 +827,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -1139,16 +1063,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constants" -version = "0.1.0" -source = "git+https://github.com/renegade-fi/renegade.git#814e98425c2a0c23df43441677ddd21b5171b6f2" -dependencies = [ - "ark-bn254", - "ark-ec", - "ark-ed-on-bn254", -] - [[package]] name = "convert_case" version = "0.4.0" @@ -2073,15 +1987,6 @@ dependencies = [ "ahash 0.7.8", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash 0.8.11", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -2613,8 +2518,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "rand", - "serde", ] [[package]] @@ -2939,22 +2842,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "poseidon-renegades-example" -version = "0.2.0-alpha.1" -dependencies = [ - "alloy", - "alloy-primitives", - "ark-bn254", - "ark-ec", - "ark-ff 0.4.2", - "e2e", - "eyre", - "renegade-crypto", - "stylus-sdk", - "tokio", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3218,22 +3105,6 @@ dependencies = [ "bytecheck", ] -[[package]] -name = "renegade-crypto" -version = "0.1.0" -source = "git+https://github.com/renegade-fi/renegade.git#814e98425c2a0c23df43441677ddd21b5171b6f2" -dependencies = [ - "ark-ec", - "ark-ff 0.4.2", - "bigdecimal", - "constants", - "itertools 0.10.5", - "lazy_static", - "num-bigint", - "serde", - "serde_json", -] - [[package]] name = "reqwest" version = "0.12.5" diff --git a/Cargo.toml b/Cargo.toml index 4caf5dea8..e845e3671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ members = [ "examples/safe-erc20", "benches", "examples/poseidon", - "examples/poseidon-renegades", ] default-members = [ "contracts", @@ -52,7 +51,6 @@ default-members = [ "examples/basic/token", "examples/ecdsa", "examples/poseidon", - "examples/poseidon-renegades", ] # Explicitly set the resolver to version 2, which is the default for packages diff --git a/benches/src/lib.rs b/benches/src/lib.rs index 877cf1c5e..49d11c24a 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -22,7 +22,6 @@ pub mod erc721; pub mod merkle_proofs; pub mod ownable; pub mod poseidon; -pub mod poseidon_renegades; pub mod poseidon_sol; pub mod report; pub mod vesting_wallet; diff --git a/benches/src/main.rs b/benches/src/main.rs index daca41058..9d801f50b 100644 --- a/benches/src/main.rs +++ b/benches/src/main.rs @@ -1,7 +1,6 @@ use benches::{ access_control, erc1155, erc1155_metadata_uri, erc20, erc721, - merkle_proofs, ownable, poseidon, poseidon_renegades, poseidon_sol, - report::BenchmarkReport, + merkle_proofs, ownable, poseidon, poseidon_sol, report::BenchmarkReport, }; use futures::FutureExt; use itertools::Itertools; @@ -18,7 +17,6 @@ async fn main() -> eyre::Result<()> { erc1155_metadata_uri::bench().boxed(), poseidon::bench().boxed(), poseidon_sol::bench().boxed(), - poseidon_renegades::bench().boxed(), ]; // Run benchmarks max 3 at the same time. diff --git a/benches/src/poseidon_renegades.rs b/benches/src/poseidon_renegades.rs deleted file mode 100644 index 2be18a2fa..000000000 --- a/benches/src/poseidon_renegades.rs +++ /dev/null @@ -1,53 +0,0 @@ -use alloy::{ - network::{AnyNetwork, EthereumWallet}, - primitives::Address, - providers::ProviderBuilder, - sol, - sol_types::SolCall, -}; -use alloy_primitives::bytes; -use e2e::{receipt, Account}; - -use crate::{ - report::{ContractReport, FunctionReport}, - Opt, -}; - -sol!( - #[sol(rpc)] - contract PoseidonExample { - #[derive(Debug)] - function hash(bytes calldata data) external view returns (bytes32 hash); - } -); - -pub async fn bench() -> eyre::Result { - ContractReport::generate("renegades::Poseidon", run).await -} - -pub async fn run(cache_opt: Opt) -> eyre::Result> { - let alice = Account::new().await?; - let alice_wallet = ProviderBuilder::new() - .network::() - .with_recommended_fillers() - .wallet(EthereumWallet::from(alice.signer.clone())) - .on_http(alice.url().parse()?); - - let contract_addr = deploy(&alice, cache_opt).await?; - - let contract = PoseidonExample::new(contract_addr, &alice_wallet); - - #[rustfmt::skip] - let receipts = vec![ - (PoseidonExample::hashCall::SIGNATURE, receipt!(contract.hash(bytes!("deadbeef")))?), - ]; - - receipts - .into_iter() - .map(FunctionReport::new) - .collect::>>() -} - -async fn deploy(account: &Account, cache_opt: Opt) -> eyre::Result
{ - crate::deploy(account, "poseidon-renegades", None, cache_opt).await -} diff --git a/examples/poseidon-renegades/Cargo.toml b/examples/poseidon-renegades/Cargo.toml deleted file mode 100644 index 9909c02f4..000000000 --- a/examples/poseidon-renegades/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "poseidon-renegades-example" -edition.workspace = true -license.workspace = true -repository.workspace = true -publish = false -version.workspace = true - -[dependencies] -alloy-primitives.workspace = true -stylus-sdk.workspace = true -renegade-crypto = { git = "https://github.com/renegade-fi/renegade.git", package = "renegade-crypto", default-features = false } -ark-ff = "0.4" -ark-ec = "0.4" -ark-bn254 = "0.4.0" - -[dev-dependencies] -alloy.workspace = true -e2e.workspace = true -tokio.workspace = true -eyre.workspace = true - -[lib] -crate-type = ["lib", "cdylib"] - -[features] -e2e = [] diff --git a/examples/poseidon-renegades/src/lib.rs b/examples/poseidon-renegades/src/lib.rs deleted file mode 100644 index d5d2167ea..000000000 --- a/examples/poseidon-renegades/src/lib.rs +++ /dev/null @@ -1,46 +0,0 @@ -#![cfg_attr(not(test), no_main)] -extern crate alloc; - -use alloc::vec::Vec; - -use alloy_primitives::B256; -use ark_ec::Group; -use ark_ff::{BigInteger, Fp256, MontBackend, MontConfig, PrimeField}; -use renegade_crypto::hash::Poseidon2Sponge; -use stylus_sdk::prelude::{entrypoint, public, storage}; - -pub type SystemCurveGroup = ark_bn254::G1Projective; -pub type ScalarField = ::ScalarField; - -// #[derive(MontConfig)] -// #[modulus = -// "21888242871839275222246405745257275088548364400416034343698204186575808495617" -// ] #[generator = "7"] -// pub struct FqConfig; -// pub type FpBN256 = Fp256>; - -#[entrypoint] -#[storage] -struct PoseidonExample {} - -#[public] -impl PoseidonExample { - pub fn hash( - &mut self, - data: stylus_sdk::abi::Bytes, - ) -> Result> { - let input = data.to_vec(); - - let mut hasher = Poseidon2Sponge::new(); - - for i in 0..2 { - let fp = ScalarField::from(i); - hasher.absorb(&fp); - } - - let hash = hasher.squeeze(); - let hash = hash.into_bigint().to_bytes_le(); - - Ok(B256::from_slice(&hash)) - } -} From 0e200ce616875f10ea2b4241a3946f9d435cdd7f Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 09:13:19 +0400 Subject: [PATCH 05/13] ++ --- examples/poseidon/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/poseidon/src/lib.rs b/examples/poseidon/src/lib.rs index 2ce3de5ce..de688ac1c 100644 --- a/examples/poseidon/src/lib.rs +++ b/examples/poseidon/src/lib.rs @@ -6,8 +6,8 @@ use alloc::vec::Vec; use alloy_primitives::U256; use openzeppelin_crypto::{ bigint::{crypto_bigint::Uint, BigInteger}, - field::{instance::FpVesta, prime::PrimeField}, - poseidon2::{instance::vesta::VestaParams, Poseidon2}, + field::{instance::FpBN256, prime::PrimeField}, + poseidon2::{instance::bn256::BN256Params, Poseidon2}, }; use stylus_sdk::prelude::{entrypoint, public, storage}; @@ -18,10 +18,10 @@ struct PoseidonExample {} #[public] impl PoseidonExample { pub fn hash(&mut self, inputs: [U256; 2]) -> Result> { - let mut hasher = Poseidon2::::new(); + let mut hasher = Poseidon2::::new(); for input in inputs.iter() { - let fp = FpVesta::from_bigint(Uint::from_bytes_le( + let fp = FpBN256::from_bigint(Uint::from_bytes_le( &input.to_le_bytes_vec(), )); hasher.absorb(&fp); From 383abb42f7e66c3f4a37f5e50a8870fc13140e56 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 09:25:42 +0400 Subject: [PATCH 06/13] ++ --- examples/poseidon/tests/abi/mod.rs | 2 +- examples/poseidon/tests/poseidon.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/poseidon/tests/abi/mod.rs b/examples/poseidon/tests/abi/mod.rs index 0e0d786bd..0dbb9f1df 100644 --- a/examples/poseidon/tests/abi/mod.rs +++ b/examples/poseidon/tests/abi/mod.rs @@ -5,6 +5,6 @@ sol!( #[sol(rpc)] contract PoseidonExample { #[derive(Debug)] - function hash(bytes calldata data) external view returns (bytes32 hash); + function hash(uint[2] memory inputs) external view returns (uint hash); } ); diff --git a/examples/poseidon/tests/poseidon.rs b/examples/poseidon/tests/poseidon.rs index 3b883ba7e..f0c1bfc58 100644 --- a/examples/poseidon/tests/poseidon.rs +++ b/examples/poseidon/tests/poseidon.rs @@ -1,6 +1,6 @@ #![cfg(feature = "e2e")] -use alloy_primitives::{bytes, hex, B256}; +use alloy_primitives::{hex, uint, U256}; use e2e::{Account, ReceiptExt, Revert}; use eyre::Result; @@ -18,10 +18,10 @@ async fn poseidon_works(alice: Account) -> Result<()> { let contract = PoseidonExample::new(contract_addr, &alice.wallet); let PoseidonExample::hashReturn { hash } = - contract.hash(bytes!("deadbeef")).call().await?; + contract.hash([uint!(123_U256), uint!(123456_U256)]).call().await?; - let expected = B256::from(hex!( - "438ba31003629145d5a99d47392a014833076ab2fbd485ce446ce617cc83e03f" + let expected = U256::from_be_slice(&hex!( + "16f70722695a5829a59319fbf746df957a513fdf72b070a67bb72db08070e5de" )); assert_eq!(hash, expected); From 1821b2ccbb20a01c140f145b4043ebfe2a3e2c59 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 09:28:09 +0400 Subject: [PATCH 07/13] ++ --- lib/crypto/src/poseidon2/mod.rs | 69 +-------------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/lib/crypto/src/poseidon2/mod.rs b/lib/crypto/src/poseidon2/mod.rs index eb48983b3..6933f9299 100644 --- a/lib/crypto/src/poseidon2/mod.rs +++ b/lib/crypto/src/poseidon2/mod.rs @@ -13,10 +13,7 @@ pub mod params; use alloc::{boxed::Box, vec, vec::Vec}; -use crate::{ - bigint::BigInteger, field::prime::PrimeField, hash::Hasher, - poseidon2::params::PoseidonParams, -}; +use crate::{field::prime::PrimeField, poseidon2::params::PoseidonParams}; /// Determines whether poseidon sponge in absorbing or squeezing state. /// In squeezing state, sponge can only squeeze elements. @@ -301,67 +298,3 @@ impl, F: PrimeField> Poseidon2 { self.state[0] += P::ROUND_CONSTANTS[round][0]; } } - -impl, F: PrimeField> Hasher for Poseidon2 { - type Output = [u8; 32]; - - fn update(&mut self, input: impl AsRef<[u8]>) { - for chunk in input.as_ref().chunks(F::BigInt::BYTES) { - // Convert chunk of bytes to a big integer. - let big_int = if chunk.len() == F::BigInt::BYTES { - F::BigInt::from_bytes_le(chunk) - } else { - // If the chunk size is actually smaller, then pad it with - // zeros. - let mut padded = vec![0; F::BigInt::BYTES]; - padded[..chunk.len()].copy_from_slice(chunk); - F::BigInt::from_bytes_le(&padded) - }; - let elem = F::from_bigint(big_int); - self.absorb(&elem); - } - } - - fn finalize(mut self) -> Self::Output { - self.squeeze_batch(32 / F::BigInt::BYTES) - .into_iter() - .flat_map(|elem| elem.into_bigint().into_bytes_le()) - .collect::>() - .try_into() - .expect("invalid output length") - } -} - -#[cfg(test)] -mod tests { - use proptest::proptest; - - use super::*; - use crate::{ - field::instance::FpVesta, - hash::Hasher, - poseidon2::{instance::vesta::VestaParams, Poseidon2}, - }; - - // NOTE: Value of this test mostly because it tests hash on random number of - // inputs without panic, instead of checking actual consistency. - // Real consistency is hard to prove on purely random inputs. - #[test] - fn consistent_hasher() { - proptest!(|(first_input: Vec, second_input: Vec)| { - let mut first_hasher = Poseidon2::::new(); - first_hasher.update(&first_input); - let first_result = first_hasher.finalize(); - - let mut second_hasher = Poseidon2::::new(); - second_hasher.update(&second_input); - let second_result = second_hasher.finalize(); - - if first_input == second_input { - assert_eq!(first_result, second_result); - } else { - assert_ne!(first_result, second_result); - } - }); - } -} From 50a455bce6cdd4fa38735aa664e0c84f21fbf2a2 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 09:30:07 +0400 Subject: [PATCH 08/13] ++ --- Cargo.lock | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 142588479..1000a1d40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,19 +1252,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cryptography-example" -version = "0.2.0-alpha.2" -dependencies = [ - "alloy", - "alloy-primitives", - "e2e", - "eyre", - "openzeppelin-stylus", - "stylus-sdk", - "tokio", -] - [[package]] name = "ctr" version = "0.9.2" @@ -1444,6 +1431,19 @@ dependencies = [ "spki", ] +[[package]] +name = "ecdsa-example" +version = "0.2.0-alpha.2" +dependencies = [ + "alloy", + "alloy-primitives", + "e2e", + "eyre", + "openzeppelin-stylus", + "stylus-sdk", + "tokio", +] + [[package]] name = "educe" version = "0.6.0" @@ -2842,6 +2842,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "poseidon-example" +version = "0.2.0-alpha.2" +dependencies = [ + "alloy", + "alloy-primitives", + "e2e", + "eyre", + "openzeppelin-crypto", + "stylus-sdk", + "tokio", +] + [[package]] name = "ppv-lite86" version = "0.2.17" From e689d2f26faaa384cf10e3a7e95107c88a5ecb60 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 09:46:14 +0400 Subject: [PATCH 09/13] ++ --- benches/src/poseidon.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/benches/src/poseidon.rs b/benches/src/poseidon.rs index a0daecc98..a596bccc0 100644 --- a/benches/src/poseidon.rs +++ b/benches/src/poseidon.rs @@ -1,5 +1,3 @@ -use std::future::Future; - use alloy::{ network::{AnyNetwork, EthereumWallet}, primitives::Address, @@ -9,7 +7,6 @@ use alloy::{ }; use alloy_primitives::uint; use e2e::{receipt, Account}; -use futures::FutureExt; use crate::{ report::{ContractReport, FunctionReport}, From bf4249e346a0bf6fe51637b335e3084f1e268d7c Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 10:07:36 +0400 Subject: [PATCH 10/13] ++ --- examples/poseidon/tests/poseidon.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/poseidon/tests/poseidon.rs b/examples/poseidon/tests/poseidon.rs index f0c1bfc58..763c37b3c 100644 --- a/examples/poseidon/tests/poseidon.rs +++ b/examples/poseidon/tests/poseidon.rs @@ -1,7 +1,7 @@ #![cfg(feature = "e2e")] use alloy_primitives::{hex, uint, U256}; -use e2e::{Account, ReceiptExt, Revert}; +use e2e::{Account, ReceiptExt}; use eyre::Result; use crate::abi::PoseidonExample; From 758b88ea93ab7b1db6efa0e945bacd2e68f51cdc Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 16:20:23 +0400 Subject: [PATCH 11/13] ++ --- benches/src/lib.rs | 11 ++++++----- benches/src/poseidon_sol.rs | 4 ++-- benches/src/report.rs | 2 +- scripts/bench.sh | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/benches/src/lib.rs b/benches/src/lib.rs index 49d11c24a..394123a2b 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -35,13 +35,14 @@ struct ArbOtherFields { l1_block_number: String, } -/// Cache options for the contract. -/// `Bid(0)` will likely cache the contract on the nitro test node. +/// Optimisation options for the contract. +/// +/// Cache or cache optimized WASM. #[derive(Clone)] pub enum Opt { None, Cache, - WasmOpt, + CacheWasmOpt, } type ArbTxReceipt = @@ -57,7 +58,7 @@ async fn deploy( std::env::current_dir().context("should get current dir from env")?; let contract_type = match opt { - Opt::WasmOpt => "example_opt", + Opt::CacheWasmOpt => "example_opt", Opt::None | Opt::Cache => "example", }; @@ -103,7 +104,7 @@ async fn deploy( .address()?; match opt { - Opt::Cache | Opt::WasmOpt => { + Opt::Cache | Opt::CacheWasmOpt => { cache_contract(account, address, 0)?; } Opt::None => {} diff --git a/benches/src/poseidon_sol.rs b/benches/src/poseidon_sol.rs index fdd94b0b8..cc1cb03df 100644 --- a/benches/src/poseidon_sol.rs +++ b/benches/src/poseidon_sol.rs @@ -57,8 +57,8 @@ pub async fn deploy(account: &Account) -> eyre::Result
{ sol! { #[allow(missing_docs)] - // Built with Remix IDE; solc v0.8.21+commit.d9974bed - #[sol(rpc, bytecode="608060405234801561000f575f80fd5b506128a28061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063561558fe146100385780638cc13d8a14610068575b5f80fd5b610052600480360381019061004d919061268f565b610098565b60405161005f91906126c9565b60405180910390f35b610082600480360381019061007d91906126e2565b61246b565b60405161008f91906126c9565b60405180910390f35b5f806040518061186001604052807f0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e81526020017ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e86481526020017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f581526020017f2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d081526020017f2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf281526020017f0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa81526020017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d81526020017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb7881526020017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63281526020017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d42881526020017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f681526020017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c81526020017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de55981526020017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f681526020017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870581526020017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d81526020017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be82881526020017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b981526020017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa681526020017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc81526020017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd181526020017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d0981526020017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea56581526020017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f981526020017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b581526020017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d6028081526020017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b81526020017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec081526020017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c46081526020017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc081526020017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e81526020017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f844881526020017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f81526020017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e81526020017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f81526020017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88781526020017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c881526020017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf181526020017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5381526020017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c81526020017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e81526020017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3881526020017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a73520681526020017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad81526020017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c81526020017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef81526020017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c9181526020017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a081526020017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c075081526020017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e81526020017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e81526020017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab81526020017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a7009239331181526020017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a81526020017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da981526020017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c456552981526020017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50281526020017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b5481526020017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef81526020017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a81526020017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd80481526020017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd64981526020017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a81526020017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff181526020017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d381526020017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8981526020017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be81526020017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af181526020017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c581526020017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f10081526020017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c296781526020017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e481526020017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b0281526020017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b64681526020017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d81526020017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc681526020017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da481526020017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e81526020017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea065462681526020017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb81526020017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1381526020017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b375881526020017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef81526020017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e981526020017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d81526020017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f281526020017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003581526020017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b14781526020017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac281526020017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a81526020017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc81526020017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f81526020017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6981526020017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a81526020017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d181526020017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b881526020017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a81526020017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c78581526020017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7781526020017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a6781526020017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c7172781526020017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b81526020017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d281526020017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe81526020017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351281526020017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d81526020017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda981526020017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80881526020017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae181526020017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e6497381526020017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0981526020017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af3881526020017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd81526020017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828481526020017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af81526020017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee46681526020017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad81526020017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c822514508681526020017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c381526020017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80081526020017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb681526020017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e781526020017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b81526020017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b81526020017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c9859181526020017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17881526020017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d4081526020017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d481526020017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423381526020017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b16887381526020017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d81526020017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc081526020017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb81526020017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f932647887581526020017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e81526020017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f01981526020017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b81526020017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5981526020017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f81526020017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a881526020017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894881526020017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f81526020017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f81526020017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14281526020017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b81526020017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f2381526020017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c081526020017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a81526020017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b581526020017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5881526020017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f281526020017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b81526020017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0181526020017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b181526020017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b81526020017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d81526020017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec81526020017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb281526020017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79281526020017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e3686081526020017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d81526020017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611181526020017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c71181526020017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb81526020017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33681526020017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a81526020017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf186081526020017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d681526020017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b81526020017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b81526020017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45181526020017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c55681526020017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f7081526020017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7781526020017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea81526020017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d81526020017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63081526020017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f81526020017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd7881526020017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc81526020017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb81526020017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d6081526020017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f81526020017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a481526020017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f181526020017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc81526020017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf0881526020017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb2410081526020017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232081526020017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad87081526020017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba81526020017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f881526020017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab181526020017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d2281526020017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516181525090505f80845f60028110611da657611da561270d565b5b602002015190505f85600160028110611dc257611dc161270d565b5b602002015190505f80875f60028110611dde57611ddd61270d565b5b602002015190505f88600160028110611dfa57611df961270d565b5b602002015190505f5b60396008611e119190612767565b8160ff16101561245b577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611e4a57611e4961279a565b5b885f60038460ff16611e5c91906127c7565b611e669190612767565b60c38110611e7757611e7661270d565b5b6020020151850896507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611eaf57611eae61279a565b5b88600160038460ff16611ec291906127c7565b611ecc9190612767565b60c38110611edd57611edc61270d565b5b6020020151840895507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611f1557611f1461279a565b5b88600260038460ff16611f2891906127c7565b611f329190612767565b60c38110611f4357611f4261270d565b5b602002015183089450611f558761246b565b965060026008611f659190612808565b8160ff161080611f915750603960026008611f809190612808565b611f8a9190612767565b8160ff1610155b15611fad57611f9f8661246b565b9550611faa8561246b565b94505b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611fdc57611fdb61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061200b5761200a61279a565b5b7f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061205d5761205c61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061208c5761208b61279a565b5b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e08a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806120de576120dd61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061210d5761210c61279a565b5b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b8d095f08080893507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121655761216461279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121945761219361279a565b5b7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121e6576121e561279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122155761221461279a565b5b7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe238a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122675761226661279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122965761229561279a565b5b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd7718d095f08080892507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122ee576122ed61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061231d5761231c61279a565b5b7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e087097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061236f5761236e61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061239e5761239d61279a565b5b7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee29118a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806123f0576123ef61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061241f5761241e61279a565b5b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a78d095f0808089150808061245390612844565b915050611e03565b5082975050505050505050919050565b5f807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061249c5761249b61279a565b5b83840990505f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806124d1576124d061279a565b5b82830990507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806125055761250461279a565b5b81850992505050919050565b5f604051905090565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61256882612522565b810181811067ffffffffffffffff8211171561258757612586612532565b5b80604052505050565b5f612599612511565b90506125a5828261255f565b919050565b5f67ffffffffffffffff8211156125c4576125c3612532565b5b602082029050919050565b5f80fd5b5f819050919050565b6125e5816125d3565b81146125ef575f80fd5b50565b5f81359050612600816125dc565b92915050565b5f612618612613846125aa565b612590565b90508060208402830185811115612632576126316125cf565b5b835b8181101561265b578061264788826125f2565b845260208401935050602081019050612634565b5050509392505050565b5f82601f8301126126795761267861251e565b5b6002612686848285612606565b91505092915050565b5f604082840312156126a4576126a361251a565b5b5f6126b184828501612665565b91505092915050565b6126c3816125d3565b82525050565b5f6020820190506126dc5f8301846126ba565b92915050565b5f602082840312156126f7576126f661251a565b5b5f612704848285016125f2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612771826125d3565b915061277c836125d3565b92508282019050808211156127945761279361273a565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6127d1826125d3565b91506127dc836125d3565b92508282026127ea816125d3565b915082820484148315176128015761280061273a565b5b5092915050565b5f612812826125d3565b915061281d836125d3565b92508261282d5761282c61279a565b5b828204905092915050565b5f60ff82169050919050565b5f61284e82612838565b915060ff82036128615761286061273a565b5b60018201905091905056fea2646970667358221220aedcc192d50a90a370e758fb76fe1f7746e2fedf56005c74f9cf6bd30ef793d464736f6c63430008150033")] + // Built with Remix IDE; solc 0.8.24+commit.e11b9ed9 + #[sol(rpc, bytecode="608060405234801561000f575f80fd5b506128a28061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063561558fe146100385780638cc13d8a14610068575b5f80fd5b610052600480360381019061004d919061268f565b610098565b60405161005f91906126c9565b60405180910390f35b610082600480360381019061007d91906126e2565b61246b565b60405161008f91906126c9565b60405180910390f35b5f806040518061186001604052807f0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e81526020017ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e86481526020017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f581526020017f2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d081526020017f2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf281526020017f0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa81526020017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d81526020017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb7881526020017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63281526020017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d42881526020017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f681526020017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c81526020017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de55981526020017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f681526020017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870581526020017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d81526020017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be82881526020017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b981526020017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa681526020017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc81526020017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd181526020017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d0981526020017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea56581526020017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f981526020017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b581526020017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d6028081526020017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b81526020017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec081526020017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c46081526020017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc081526020017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e81526020017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f844881526020017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f81526020017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e81526020017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f81526020017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88781526020017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c881526020017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf181526020017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5381526020017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c81526020017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e81526020017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3881526020017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a73520681526020017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad81526020017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c81526020017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef81526020017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c9181526020017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a081526020017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c075081526020017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e81526020017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e81526020017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab81526020017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a7009239331181526020017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a81526020017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da981526020017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c456552981526020017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50281526020017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b5481526020017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef81526020017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a81526020017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd80481526020017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd64981526020017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a81526020017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff181526020017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d381526020017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8981526020017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be81526020017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af181526020017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c581526020017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f10081526020017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c296781526020017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e481526020017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b0281526020017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b64681526020017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d81526020017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc681526020017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da481526020017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e81526020017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea065462681526020017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb81526020017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1381526020017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b375881526020017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef81526020017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e981526020017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d81526020017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f281526020017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003581526020017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b14781526020017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac281526020017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a81526020017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc81526020017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f81526020017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6981526020017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a81526020017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d181526020017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b881526020017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a81526020017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c78581526020017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7781526020017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a6781526020017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c7172781526020017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b81526020017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d281526020017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe81526020017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351281526020017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d81526020017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda981526020017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80881526020017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae181526020017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e6497381526020017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0981526020017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af3881526020017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd81526020017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828481526020017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af81526020017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee46681526020017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad81526020017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c822514508681526020017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c381526020017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80081526020017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb681526020017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e781526020017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b81526020017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b81526020017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c9859181526020017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17881526020017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d4081526020017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d481526020017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423381526020017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b16887381526020017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d81526020017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc081526020017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb81526020017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f932647887581526020017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e81526020017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f01981526020017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b81526020017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5981526020017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f81526020017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a881526020017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894881526020017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f81526020017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f81526020017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14281526020017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b81526020017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f2381526020017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c081526020017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a81526020017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b581526020017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5881526020017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f281526020017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b81526020017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0181526020017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b181526020017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b81526020017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d81526020017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec81526020017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb281526020017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79281526020017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e3686081526020017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d81526020017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611181526020017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c71181526020017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb81526020017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33681526020017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a81526020017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf186081526020017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d681526020017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b81526020017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b81526020017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45181526020017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c55681526020017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f7081526020017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7781526020017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea81526020017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d81526020017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63081526020017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f81526020017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd7881526020017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc81526020017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb81526020017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d6081526020017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f81526020017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a481526020017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f181526020017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc81526020017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf0881526020017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb2410081526020017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232081526020017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad87081526020017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba81526020017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f881526020017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab181526020017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d2281526020017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516181525090505f80845f60028110611da657611da561270d565b5b602002015190505f85600160028110611dc257611dc161270d565b5b602002015190505f80875f60028110611dde57611ddd61270d565b5b602002015190505f88600160028110611dfa57611df961270d565b5b602002015190505f5b60396008611e119190612767565b8160ff16101561245b577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611e4a57611e4961279a565b5b885f60038460ff16611e5c91906127c7565b611e669190612767565b60c38110611e7757611e7661270d565b5b6020020151850896507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611eaf57611eae61279a565b5b88600160038460ff16611ec291906127c7565b611ecc9190612767565b60c38110611edd57611edc61270d565b5b6020020151840895507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611f1557611f1461279a565b5b88600260038460ff16611f2891906127c7565b611f329190612767565b60c38110611f4357611f4261270d565b5b602002015183089450611f558761246b565b965060026008611f659190612808565b8160ff161080611f915750603960026008611f809190612808565b611f8a9190612767565b8160ff1610155b15611fad57611f9f8661246b565b9550611faa8561246b565b94505b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000180611fdc57611fdb61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061200b5761200a61279a565b5b7f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061205d5761205c61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061208c5761208b61279a565b5b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e08a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806120de576120dd61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061210d5761210c61279a565b5b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b8d095f08080893507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121655761216461279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121945761219361279a565b5b7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa87097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806121e6576121e561279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122155761221461279a565b5b7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe238a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122675761226661279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122965761229561279a565b5b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd7718d095f08080892507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806122ee576122ed61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061231d5761231c61279a565b5b7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e087097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061236f5761236e61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061239e5761239d61279a565b5b7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee29118a097f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806123f0576123ef61279a565b5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061241f5761241e61279a565b5b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a78d095f0808089150808061245390612844565b915050611e03565b5082975050505050505050919050565b5f807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018061249c5761249b61279a565b5b83840990505f7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806124d1576124d061279a565b5b82830990507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001806125055761250461279a565b5b81850992505050919050565b5f604051905090565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61256882612522565b810181811067ffffffffffffffff8211171561258757612586612532565b5b80604052505050565b5f612599612511565b90506125a5828261255f565b919050565b5f67ffffffffffffffff8211156125c4576125c3612532565b5b602082029050919050565b5f80fd5b5f819050919050565b6125e5816125d3565b81146125ef575f80fd5b50565b5f81359050612600816125dc565b92915050565b5f612618612613846125aa565b612590565b90508060208402830185811115612632576126316125cf565b5b835b8181101561265b578061264788826125f2565b845260208401935050602081019050612634565b5050509392505050565b5f82601f8301126126795761267861251e565b5b6002612686848285612606565b91505092915050565b5f604082840312156126a4576126a361251a565b5b5f6126b184828501612665565b91505092915050565b6126c3816125d3565b82525050565b5f6020820190506126dc5f8301846126ba565b92915050565b5f602082840312156126f7576126f661251a565b5b5f612704848285016125f2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612771826125d3565b915061277c836125d3565b92508282019050808211156127945761279361273a565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6127d1826125d3565b91506127dc836125d3565b92508282026127ea816125d3565b915082820484148315176128015761280061273a565b5b5092915050565b5f612812826125d3565b915061281d836125d3565b92508261282d5761282c61279a565b5b828204905092915050565b5f60ff82169050919050565b5f61284e82612838565b915060ff82036128615761286061273a565b5b60018201905091905056fea2646970667358221220bbca6b465040aed1280d5f1c36307be5f51332df0a9b378c08219b2d27168faa64736f6c63430008180033")] contract PoseidonT3 { uint constant F = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint constant ROUNDS_F = 8; diff --git a/benches/src/report.rs b/benches/src/report.rs index 98ef943c4..f617ea82c 100644 --- a/benches/src/report.rs +++ b/benches/src/report.rs @@ -44,7 +44,7 @@ impl ContractReport { .into_iter() .try_fold(report, ContractReport::add_cached)?; - let wasm_opt_cached_reports = run(Opt::WasmOpt).await?; + let wasm_opt_cached_reports = run(Opt::CacheWasmOpt).await?; let report = wasm_opt_cached_reports .into_iter() .try_fold(report, ContractReport::add_wasm_opt_cached)?; diff --git a/scripts/bench.sh b/scripts/bench.sh index 3a93fdb24..3941d0653 100755 --- a/scripts/bench.sh +++ b/scripts/bench.sh @@ -13,7 +13,7 @@ opt_wasm () { echo echo "Optimising $CONTRACT_CRATE_NAME WASM binary" - # https://rustwasm.github.io/book/reference/code-size.html + # https://rustwasm.github.io/book/reference/code-size.html#use-the-wasm-opt-tool wasm-opt -O3 -o ./target/wasm32-unknown-unknown/release/"$CONTRACT_OPT_BIN_NAME" ./target/wasm32-unknown-unknown/release/"$CONTRACT_BIN_NAME" } From 2eb5c1b9ff4ba6318d5ef7d7fa125bf663f143f5 Mon Sep 17 00:00:00 2001 From: Alisander Qoshqosh Date: Wed, 8 Jan 2025 21:31:34 +0400 Subject: [PATCH 12/13] ++ --- benches/src/PoseidonT3.sol | 82 +++++++++++++++++++------------------- scripts/bench.sh | 2 +- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/benches/src/PoseidonT3.sol b/benches/src/PoseidonT3.sol index 333993bce..4fa232fe4 100644 --- a/benches/src/PoseidonT3.sol +++ b/benches/src/PoseidonT3.sol @@ -2,52 +2,52 @@ pragma solidity ^0.8.0; contract PoseidonT3 { - uint constant F = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint constant ROUNDS_F = 8; - uint constant ROUNDS_P = 57; - uint constant T = 3; + uint constant F = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint constant ROUNDS_F = 8; + uint constant ROUNDS_P = 57; + uint constant T = 3; - uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b; - uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771; - uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7; - uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0; - uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23; - uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911; - uint constant M20 = 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d; - uint constant M21 = 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa; - uint constant M22 = 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0; + uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b; + uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771; + uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7; + uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0; + uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23; + uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911; + uint constant M20 = 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d; + uint constant M21 = 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa; + uint constant M22 = 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0; - // Based on https://github.com/chancehudson/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol - function hash(uint[2] memory inputs) public pure returns (uint) { - uint[195] memory C = [0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161]; + // Based on https://github.com/chancehudson/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol + function hash(uint[2] memory inputs) public pure returns (uint) { + uint[195] memory C = [0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161]; - uint state0 = 0; - uint state1 = inputs[0]; - uint state2 = inputs[1]; - uint swap0 = 0; - uint swap1 = inputs[0]; - uint swap2 = inputs[1]; - for (uint8 r = 0; r < ROUNDS_F + ROUNDS_P; r++) { - state0 = addmod(swap0, C[r * T + 0], F); - state1 = addmod(swap1, C[r * T + 1], F); - state2 = addmod(swap2, C[r * T + 2], F); + uint state0 = 0; + uint state1 = inputs[0]; + uint state2 = inputs[1]; + uint swap0 = 0; + uint swap1 = inputs[0]; + uint swap2 = inputs[1]; + for (uint8 r = 0; r < ROUNDS_F + ROUNDS_P; r++) { + state0 = addmod(swap0, C[r * T + 0], F); + state1 = addmod(swap1, C[r * T + 1], F); + state2 = addmod(swap2, C[r * T + 2], F); - state0 = pow5mod(state0); - if (r < ROUNDS_F / 2 || r >= ROUNDS_F / 2 + ROUNDS_P) { - state1 = pow5mod(state1); - state2 = pow5mod(state2); - } + state0 = pow5mod(state0); + if (r < ROUNDS_F / 2 || r >= ROUNDS_F / 2 + ROUNDS_P) { + state1 = pow5mod(state1); + state2 = pow5mod(state2); + } - swap0 = addmod(addmod(addmod(0, mulmod(state0, M00, F), F), mulmod(state1, M10, F), F), mulmod(state2, M20, F), F); - swap1 = addmod(addmod(addmod(0, mulmod(state0, M01, F), F), mulmod(state1, M11, F), F), mulmod(state2, M21, F), F); - swap2 = addmod(addmod(addmod(0, mulmod(state0, M02, F), F), mulmod(state1, M12, F), F), mulmod(state2, M22, F), F); + swap0 = addmod(addmod(addmod(0, mulmod(state0, M00, F), F), mulmod(state1, M10, F), F), mulmod(state2, M20, F), F); + swap1 = addmod(addmod(addmod(0, mulmod(state0, M01, F), F), mulmod(state1, M11, F), F), mulmod(state2, M21, F), F); + swap2 = addmod(addmod(addmod(0, mulmod(state0, M02, F), F), mulmod(state1, M12, F), F), mulmod(state2, M22, F), F); + } + return swap0; } - return swap0; - } - function pow5mod(uint i) public pure returns (uint) { - uint a = mulmod(i, i, F); - uint c = mulmod(a, a, F); - return mulmod(i, c, F); - } + function pow5mod(uint i) public pure returns (uint) { + uint a = mulmod(i, i, F); + uint c = mulmod(a, a, F); + return mulmod(i, c, F); + } } \ No newline at end of file diff --git a/scripts/bench.sh b/scripts/bench.sh index 3941d0653..a464ed6eb 100755 --- a/scripts/bench.sh +++ b/scripts/bench.sh @@ -12,7 +12,7 @@ opt_wasm () { local CONTRACT_OPT_BIN_NAME="${CONTRACT_CRATE_NAME//-/_}_opt.wasm" echo - echo "Optimising $CONTRACT_CRATE_NAME WASM binary" + echo "Optimizing $CONTRACT_CRATE_NAME WASM binary" # https://rustwasm.github.io/book/reference/code-size.html#use-the-wasm-opt-tool wasm-opt -O3 -o ./target/wasm32-unknown-unknown/release/"$CONTRACT_OPT_BIN_NAME" ./target/wasm32-unknown-unknown/release/"$CONTRACT_BIN_NAME" } From 41c8671ff114d0e5cccf011187103d063b7e8547 Mon Sep 17 00:00:00 2001 From: Nenad Date: Wed, 8 Jan 2025 19:57:02 +0100 Subject: [PATCH 13/13] ref: add missing new line to benches/src/PoseidonT3.sol --- benches/src/PoseidonT3.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/src/PoseidonT3.sol b/benches/src/PoseidonT3.sol index 4fa232fe4..0ae08bee1 100644 --- a/benches/src/PoseidonT3.sol +++ b/benches/src/PoseidonT3.sol @@ -50,4 +50,4 @@ contract PoseidonT3 { uint c = mulmod(a, a, F); return mulmod(i, c, F); } -} \ No newline at end of file +}