From efed026c88f0a86cc916ac1a9bb39180189a77a7 Mon Sep 17 00:00:00 2001 From: Andrew Kirillov <20803092+akirillo@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:01:49 -0700 Subject: [PATCH] renegade_contracts: merkle: poseidon: using spongemode, fuzz tests passing --- .github/actions/install_cairo/action.yml | 18 -------- .github/workflows/test_devnet.yml | 5 +-- src/merkle/poseidon.cairo | 56 +++++++++++++++++------- tests/src/poseidon/utils.rs | 12 ++--- tests/src/utils.rs | 2 - 5 files changed, 49 insertions(+), 44 deletions(-) delete mode 100644 .github/actions/install_cairo/action.yml diff --git a/.github/actions/install_cairo/action.yml b/.github/actions/install_cairo/action.yml deleted file mode 100644 index 55a2f450..00000000 --- a/.github/actions/install_cairo/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Install Cairo -description: Downloads and installs latest Cairo 1.0 release running on Starknet -inputs: - CAIRO_ARCHIVE_LINK: - description: "URL from which to download the Cairo release" - required: true -runs: - using: "composite" - steps: - - name: "[Cairo] Download binaries" - shell: bash - run: curl -L -o cairo.zip ${{inputs.CAIRO_ARCHIVE_LINK}} - - name: "[Cairo] Unzip binaries" - shell: bash - run: mkdir ./cairo && tar -xvf cairo.zip --strip-components 1 -C ./cairo - - name: "[Cairo] Make binaries available" - shell: bash - run: echo "./cairo/bin" >> $GITHUB_PATH diff --git a/.github/workflows/test_devnet.yml b/.github/workflows/test_devnet.yml index 9b35cc8f..9d575175 100644 --- a/.github/workflows/test_devnet.yml +++ b/.github/workflows/test_devnet.yml @@ -29,9 +29,8 @@ jobs: uses: actions-rs/cargo@v1 env: ARTIFACTS_PATH: ${{ github.workspace }}/target/release - RUST_LOG: "tests=trace,katana_core=warn" + RUST_LOG: "tests=trace,katana_core=debug" + CAIRO_STEP_LIMIT: 10000000 with: command: test args: -p tests --all-targets --lib --verbose -- --nocapture - - \ No newline at end of file diff --git a/src/merkle/poseidon.cairo b/src/merkle/poseidon.cairo index be304e3e..609b09a9 100644 --- a/src/merkle/poseidon.cairo +++ b/src/merkle/poseidon.cairo @@ -27,11 +27,18 @@ const T: usize = 3; // TODO: Hardcode all MDS entries (only 9) // TODO: Hardcode all round constants +#[derive(Drop)] +enum SpongeMode { + /// Signifies that the sponge is currently absorbing input at the given index + Absorbing: usize, + /// Signifies that the sponge is currently squeezing output from the given index + Squeezing: usize, +} + #[derive(Destruct)] struct PoseidonSponge { state: NullableVec, - absorb_index: usize, - squeeze_index: usize, + mode: SpongeMode, round_constants: Array>, mds: Array>, } @@ -54,46 +61,63 @@ impl PoseidonImpl of PoseidonTrait { let round_constants = round_constants(); let mds = mds(); - PoseidonSponge { state, absorb_index: 0, squeeze_index: 0, round_constants, mds, } + PoseidonSponge { state, mode: SpongeMode::Absorbing(0), round_constants, mds, } } fn absorb(ref self: PoseidonSponge, input: Span) { - let PoseidonSponge{mut state, mut absorb_index, squeeze_index, round_constants, mds } = - self; + let PoseidonSponge{mut state, mut mode, round_constants, mds } = self; let round_constants_span = round_constants.deep_span(); let mds_span = mds.deep_span(); + let mut absorb_index = match mode { + SpongeMode::Absorbing(i) => i, + SpongeMode::Squeezing(_) => { + permute(ref state, round_constants_span, mds_span); + 0 + } + }; + let mut i = 0; loop { if i == input.len() { break; } + // Only permute if we're not done absorbing + if absorb_index == RATE { + permute(ref state, round_constants_span, mds_span); + absorb_index = 0; + } + let mut state_i = state[CAPACITY + absorb_index]; state_i += *input[i]; state.set(CAPACITY + absorb_index, state_i); absorb_index += 1; - if absorb_index == RATE { - permute(ref state, round_constants_span, mds_span); - absorb_index = 0; - } - i += 1; }; - self = PoseidonSponge { state, absorb_index, squeeze_index, round_constants, mds }; + mode = SpongeMode::Absorbing(absorb_index); + + self = PoseidonSponge { state, mode, round_constants, mds }; } fn squeeze(ref self: PoseidonSponge, num_elements: usize) -> Array { - let PoseidonSponge{mut state, absorb_index, mut squeeze_index, round_constants, mds } = - self; + let PoseidonSponge{mut state, mut mode, round_constants, mds } = self; let round_constants_span = round_constants.deep_span(); let mds_span = mds.deep_span(); + let mut squeeze_index = match mode { + SpongeMode::Absorbing(_) => { + permute(ref state, round_constants_span, mds_span); + 0 + }, + SpongeMode::Squeezing(i) => i, + }; + let mut output = ArrayTrait::new(); let mut i = 0; @@ -108,14 +132,16 @@ impl PoseidonImpl of PoseidonTrait { squeeze_index = 0; } - output.append(state[squeeze_index]); + output.append(state[CAPACITY + squeeze_index]); squeeze_index += 1; i += 1; }; - self = PoseidonSponge { state, absorb_index, squeeze_index, round_constants, mds }; + mode = SpongeMode::Squeezing(squeeze_index); + + self = PoseidonSponge { state, mode, round_constants, mds }; output } diff --git a/tests/src/poseidon/utils.rs b/tests/src/poseidon/utils.rs index abde07e2..073a6c3b 100644 --- a/tests/src/poseidon/utils.rs +++ b/tests/src/poseidon/utils.rs @@ -16,9 +16,9 @@ use tracing::debug; use crate::utils::{call_contract, global_setup, invoke_contract, ARTIFACTS_PATH_ENV_VAR}; -pub const FUZZ_ROUNDS: usize = 1; -const MAX_INPUT_SIZE: usize = 10; -const MAX_OUTPUT_SIZE: usize = 10; +pub const FUZZ_ROUNDS: usize = 10; +const MAX_INPUT_SIZE: usize = 16; +const MAX_OUTPUT_SIZE: usize = 16; const POSEIDON_FULL_ROUNDS: usize = 2; // DUMMY VALUE const POSEIDON_PARTIAL_ROUNDS: usize = 4; // DUMMY VALUE @@ -126,10 +126,10 @@ pub fn random_input(len: usize) -> Vec { pub async fn get_random_input_hashes( account: &ScriptAccount, ) -> Result<(Vec, Vec)> { - let input_len = thread_rng().gen_range(0..MAX_INPUT_SIZE); + let input_len = thread_rng().gen_range(1..MAX_INPUT_SIZE); let input = random_input(input_len); let ark_input: Vec = input.iter().map(|s| s.inner()).collect(); - let num_elements = thread_rng().gen_range(0..MAX_OUTPUT_SIZE); + let num_elements = thread_rng().gen_range(1..MAX_OUTPUT_SIZE); debug!( "Absorbing {} elements, squeezing {} elements", @@ -181,7 +181,7 @@ fn round_constants() -> Vec> { fn ark_poseidon_params() -> PoseidonConfig { PoseidonConfig::new( - POSEIDON_FULL_ROUNDS, + POSEIDON_FULL_ROUNDS * 2, POSEIDON_PARTIAL_ROUNDS, POSEIDON_ALPHA, mds(), diff --git a/tests/src/utils.rs b/tests/src/utils.rs index 4e9f4055..d981f715 100644 --- a/tests/src/utils.rs +++ b/tests/src/utils.rs @@ -28,8 +28,6 @@ fn get_test_starknet_config() -> StarknetConfig { let invoke_max_steps = env::var(CAIRO_STEP_LIMIT_ENV_VAR) .map_or(DEFAULT_INVOKE_MAX_STEPS, |s| s.parse::().unwrap()); - debug!("Running sequencer with {} max steps", invoke_max_steps); - StarknetConfig { env: Environment { invoke_max_steps,