diff --git a/.github/workflows/proof_verification_tests.yml b/.github/workflows/proof_verification_tests.yml index c9eedfdc7..007ab83bf 100644 --- a/.github/workflows/proof_verification_tests.yml +++ b/.github/workflows/proof_verification_tests.yml @@ -15,8 +15,9 @@ jobs: matrix: cairo_version: ["cairo0", "cairo1"] layout: ["recursive", "recursive_with_poseidon", "small", "dex", "starknet", "starknet_with_keccak"] - hasher: ["keccak_160_lsb"] - prover: ["stone5"] + hash_function: ["keccak"] + hasher_bit_length: ["lsb160"] + stone_version: ["stone5"] steps: - name: Checkout repository uses: actions/checkout@v3 @@ -28,7 +29,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Build project - run: scarb build --no-default-features --features monolith,${{ matrix.layout }},${{ matrix.hasher }},${{ matrix.prover }} + run: scarb build --no-default-features --features monolith,${{ matrix.layout }},${{ matrix.hash_function }} - name: Run verification - run: cargo run --release --bin runner -- -p target/dev/cairo_verifier.sierra.json -c ${{ matrix.cairo_version }} < examples/proofs/${{ matrix.layout }}/${{ matrix.cairo_version }}_example_proof.json + run: cargo run --release --bin runner -- --program target/dev/cairo_verifier.sierra.json --cairo-version ${{ matrix.cairo_version }} --stone-version ${{ matrix.stone_version }} --hasher-bit-length ${{ matrix.hasher_bit_length }} < examples/proofs/${{ matrix.layout }}/${{ matrix.cairo_version }}_example_proof.json diff --git a/Scarb.toml b/Scarb.toml index 461e1fe18..d6d726da0 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -22,15 +22,10 @@ small = [] starknet = [] starknet_with_keccak = [] -keccak_160_lsb = [] -keccak_248_lsb = [] -blake2s_160_lsb = [] -blake2s_248_lsb = [] - -stone5 = [] -stone6 = [] +keccak = [] +blake2s = [] monolith = [] split = [] -default = ["recursive", "keccak_160_lsb", "stone5", "monolith"] +default = ["recursive", "keccak", "monolith"] diff --git a/runner/src/lib.rs b/runner/src/lib.rs index 7abca839a..c2ef97781 100644 --- a/runner/src/lib.rs +++ b/runner/src/lib.rs @@ -19,3 +19,33 @@ impl From for Felt252 { } } } + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum StoneVersion { + Stone5 = 0, + Stone6 = 1, +} + +impl From for Felt252 { + fn from(value: StoneVersion) -> Self { + match value { + StoneVersion::Stone5 => Felt252::from(0), + StoneVersion::Stone6 => Felt252::from(1), + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum HasherBitLength { + Lsb160 = 0, + Lsb248 = 1, +} + +impl From for Felt252 { + fn from(value: HasherBitLength) -> Self { + match value { + HasherBitLength::Lsb160 => Felt252::from(0), + HasherBitLength::Lsb248 => Felt252::from(1), + } + } +} \ No newline at end of file diff --git a/runner/src/main.rs b/runner/src/main.rs index d0f0a7d2b..cc2b9dc95 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -7,7 +7,7 @@ use cairo_lang_sierra::program::VersionedProgram; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use clap::Parser; use itertools::{chain, Itertools}; -use runner::CairoVersion; +use runner::{CairoVersion, HasherBitLength, StoneVersion}; use std::{ fs, io::{stdin, Read}, @@ -26,6 +26,12 @@ struct Cli { /// Cairo version - public memory pattern #[clap(value_enum, short, long, default_value_t=CairoVersion::Cairo0)] cairo_version: CairoVersion, + /// Stone version + #[clap(value_enum, short, long, default_value_t=StoneVersion::Stone5)] + stone_version: StoneVersion, + /// Hasher bit length + #[clap(value_enum, short, long, default_value_t=HasherBitLength::Lsb160)] + hasher_bit_length: HasherBitLength, } fn main() -> anyhow::Result<()> { @@ -66,6 +72,8 @@ fn main() -> anyhow::Result<()> { let args = &[ Arg::Array(proof.into_iter().map(Arg::Value).collect_vec()), Arg::Value(cli.cairo_version.into()), + Arg::Value(cli.hasher_bit_length.into()), + Arg::Value(cli.stone_version.into()), ]; let result = runner .run_function_with_starknet_context(func, args, Some(u32::MAX as usize), Default::default()) diff --git a/src/air/layouts/dex/traces.cairo b/src/air/layouts/dex/traces.cairo index 81eb6f93f..21d583d22 100644 --- a/src/air/layouts/dex/traces.cairo +++ b/src/air/layouts/dex/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -120,7 +120,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/layouts/recursive/traces.cairo b/src/air/layouts/recursive/traces.cairo index 7bbcbb6ba..97eb06861 100644 --- a/src/air/layouts/recursive/traces.cairo +++ b/src/air/layouts/recursive/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -123,7 +123,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/layouts/recursive_with_poseidon/traces.cairo b/src/air/layouts/recursive_with_poseidon/traces.cairo index b430577d1..19e323b9b 100644 --- a/src/air/layouts/recursive_with_poseidon/traces.cairo +++ b/src/air/layouts/recursive_with_poseidon/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -123,7 +123,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/layouts/small/traces.cairo b/src/air/layouts/small/traces.cairo index 1acf683d5..3ad7ee04b 100644 --- a/src/air/layouts/small/traces.cairo +++ b/src/air/layouts/small/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -120,7 +120,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/layouts/starknet.cairo b/src/air/layouts/starknet.cairo index c1f2d330b..6bac0d559 100644 --- a/src/air/layouts/starknet.cairo +++ b/src/air/layouts/starknet.cairo @@ -3,13 +3,23 @@ mod constants; mod global_values; mod public_input; mod traces; +<<<<<<< HEAD #[cfg(feature: 'split')] +======= +>>>>>>> autogenerated_split mod contract; use cairo_verifier::{ air::{ constants::{SHIFT_POINT_X, SHIFT_POINT_Y, StarkCurve}, layouts::starknet::{ +<<<<<<< HEAD +======= + contract::{ + IStarknetLayoutContract1Dispatcher, IStarknetLayoutContract1DispatcherTrait, + IStarknetLayoutContract2Dispatcher, IStarknetLayoutContract2DispatcherTrait, + }, +>>>>>>> autogenerated_split global_values::{ GlobalValues, InteractionElements, EcPoint, EcdsaSigConfig, CurveConfig }, diff --git a/src/air/layouts/starknet/contract.cairo b/src/air/layouts/starknet/contract.cairo index e73220b8c..600440c52 100644 --- a/src/air/layouts/starknet/contract.cairo +++ b/src/air/layouts/starknet/contract.cairo @@ -27,10 +27,14 @@ trait ILayoutOodsContract { #[starknet::contract] mod LayoutCompositionContract { +<<<<<<< HEAD use super::{ ILayoutCompositionContract, ILayoutCompositionContractDispatcher, ILayoutCompositionContractDispatcherTrait }; +======= + use super::ILayoutCompositionContract; +>>>>>>> autogenerated_split use cairo_verifier::air::layouts::starknet::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_1, }; @@ -38,8 +42,12 @@ mod LayoutCompositionContract { #[storage] struct Storage { +<<<<<<< HEAD continuation_contract1: ContractAddress, continuation_contract2: ContractAddress, +======= + continuation_contracts: Array, +>>>>>>> autogenerated_split } #[abi(embed_v0)] @@ -53,7 +61,11 @@ mod LayoutCompositionContract { global_values: GlobalValues ) -> felt252 { let mut total_sum = ILayoutCompositionContractDispatcher { +<<<<<<< HEAD contract_address: self.continuation_contract1.read() +======= + contract_address: continuation_contracts[0] +>>>>>>> autogenerated_split } .eval_composition_polynomial_inner( mask_values, @@ -64,9 +76,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract2.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[1] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(99, 99), diff --git a/src/air/layouts/starknet/traces.cairo b/src/air/layouts/starknet/traces.cairo index 70a09d032..2cf65e05b 100644 --- a/src/air/layouts/starknet/traces.cairo +++ b/src/air/layouts/starknet/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -123,7 +123,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/layouts/starknet_with_keccak.cairo b/src/air/layouts/starknet_with_keccak.cairo index d5ef76ae3..496bfad24 100644 --- a/src/air/layouts/starknet_with_keccak.cairo +++ b/src/air/layouts/starknet_with_keccak.cairo @@ -3,13 +3,25 @@ mod constants; mod global_values; mod public_input; mod traces; +<<<<<<< HEAD #[cfg(feature: 'split')] +======= +>>>>>>> autogenerated_split mod contract; use cairo_verifier::{ air::{ constants::{SHIFT_POINT_X, SHIFT_POINT_Y, StarkCurve}, layouts::starknet_with_keccak::{ +<<<<<<< HEAD +======= + contract::{ + IStarknetWithKeccakLayoutContract1Dispatcher, + IStarknetWithKeccakLayoutContract1DispatcherTrait, + IStarknetWithKeccakLayoutContract2Dispatcher, + IStarknetWithKeccakLayoutContract2DispatcherTrait, + }, +>>>>>>> autogenerated_split global_values::{ GlobalValues, InteractionElements, EcPoint, EcdsaSigConfig, CurveConfig }, @@ -36,7 +48,11 @@ use cairo_verifier::{ use starknet::ContractAddress; #[cfg(feature: 'monolith')] +<<<<<<< HEAD use cairo_verifier::air::layouts::starknet_with_keccak::autogenerated::{ +======= +use cairo_verifier::air::layouts::starknet::autogenerated::{ +>>>>>>> autogenerated_split eval_composition_polynomial_inner as eval_composition_polynomial_inner_, eval_oods_polynomial_inner as eval_oods_polynomial_inner_, }; @@ -71,7 +87,11 @@ fn eval_oods_polynomial_inner( } #[cfg(feature: 'split')] +<<<<<<< HEAD use cairo_verifier::air::layouts::starknet_with_keccak::contract::{ +======= +use cairo_verifier::air::layouts::starknet::contract::{ +>>>>>>> autogenerated_split ILayoutCompositionContractDispatcher, ILayoutCompositionContractDispatcherTrait, ILayoutOodsContractDispatcher, ILayoutOodsContractDispatcherTrait, }; diff --git a/src/air/layouts/starknet_with_keccak/autogenerated.cairo b/src/air/layouts/starknet_with_keccak/autogenerated.cairo index 3d0dad818..36fc886b8 100644 --- a/src/air/layouts/starknet_with_keccak/autogenerated.cairo +++ b/src/air/layouts/starknet_with_keccak/autogenerated.cairo @@ -15135,7 +15135,11 @@ fn eval_oods_polynomial_inner( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_1( +======= +fn eval_composition_polynomial_inner_part1( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -21611,7 +21615,11 @@ fn eval_composition_polynomial_inner_part_1( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_2( +======= +fn eval_composition_polynomial_inner_part2( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -28030,7 +28038,11 @@ fn eval_composition_polynomial_inner_part_2( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_3( +======= +fn eval_composition_polynomial_inner_part3( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -36594,7 +36606,11 @@ fn eval_composition_polynomial_inner_part_3( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_4( +======= +fn eval_composition_polynomial_inner_part4( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -43625,7 +43641,11 @@ fn eval_composition_polynomial_inner_part_4( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_5( +======= +fn eval_composition_polynomial_inner_part5( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -50298,7 +50318,11 @@ fn eval_composition_polynomial_inner_part_5( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_6( +======= +fn eval_composition_polynomial_inner_part6( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -56734,7 +56758,11 @@ fn eval_composition_polynomial_inner_part_6( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_composition_polynomial_inner_part_7( +======= +fn eval_composition_polynomial_inner_part7( +>>>>>>> autogenerated_split mut mask_values: Span, mut constraint_coefficients: Span, point: felt252, @@ -62088,7 +62116,11 @@ fn eval_composition_polynomial_inner_part_7( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_oods_polynomial_inner_part_1( +======= +fn eval_oods_polynomial_inner_part1( +>>>>>>> autogenerated_split mut column_values: Span, mut oods_values: Span, mut constraint_coefficients: Span, @@ -63127,7 +63159,11 @@ fn eval_oods_polynomial_inner_part_1( } #[cfg(feature: 'split')] +<<<<<<< HEAD fn eval_oods_polynomial_inner_part_2( +======= +fn eval_oods_polynomial_inner_part2( +>>>>>>> autogenerated_split mut column_values: Span, mut oods_values: Span, mut constraint_coefficients: Span, diff --git a/src/air/layouts/starknet_with_keccak/contract.cairo b/src/air/layouts/starknet_with_keccak/contract.cairo index 6a0d3e428..fc5212dc5 100644 --- a/src/air/layouts/starknet_with_keccak/contract.cairo +++ b/src/air/layouts/starknet_with_keccak/contract.cairo @@ -27,15 +27,20 @@ trait ILayoutOodsContract { #[starknet::contract] mod LayoutCompositionContract { +<<<<<<< HEAD use super::{ ILayoutCompositionContract, ILayoutCompositionContractDispatcher, ILayoutCompositionContractDispatcherTrait }; +======= + use super::ILayoutCompositionContract; +>>>>>>> autogenerated_split use cairo_verifier::air::layouts::starknet_with_keccak::{global_values::GlobalValues,}; use starknet::ContractAddress; #[storage] struct Storage { +<<<<<<< HEAD continuation_contract1: ContractAddress, continuation_contract2: ContractAddress, continuation_contract3: ContractAddress, @@ -43,6 +48,9 @@ mod LayoutCompositionContract { continuation_contract5: ContractAddress, continuation_contract6: ContractAddress, continuation_contract7: ContractAddress, +======= + continuation_contracts: Array, +>>>>>>> autogenerated_split } #[abi(embed_v0)] @@ -56,7 +64,11 @@ mod LayoutCompositionContract { global_values: GlobalValues ) -> felt252 { let mut total_sum = ILayoutCompositionContractDispatcher { +<<<<<<< HEAD contract_address: self.continuation_contract1.read() +======= + contract_address: continuation_contracts[0] +>>>>>>> autogenerated_split } .eval_composition_polynomial_inner( mask_values, @@ -67,9 +79,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract2.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[1] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(95, 100), @@ -79,9 +95,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract3.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[2] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(195, 34), @@ -91,9 +111,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract4.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[3] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(229, 31), @@ -103,9 +127,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract5.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[4] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(260, 25), @@ -115,9 +143,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract6.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[5] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(285, 25), @@ -127,9 +159,13 @@ mod LayoutCompositionContract { ); total_sum += +<<<<<<< HEAD ILayoutCompositionContractDispatcher { contract_address: self.continuation_contract7.read() } +======= + ILayoutCompositionContractDispatcher { contract_address: continuation_contracts[6] } +>>>>>>> autogenerated_split .eval_composition_polynomial_inner( mask_values, constraint_coefficients.slice(310, 37), @@ -148,7 +184,10 @@ mod LayoutCompositionContract1 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_1, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -176,7 +215,10 @@ mod LayoutCompositionContract2 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_2, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -204,7 +246,10 @@ mod LayoutCompositionContract3 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_3, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -232,7 +277,10 @@ mod LayoutCompositionContract4 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_4, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -260,7 +308,10 @@ mod LayoutCompositionContract5 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_5, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -288,7 +339,10 @@ mod LayoutCompositionContract6 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_6, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -316,7 +370,10 @@ mod LayoutCompositionContract7 { use cairo_verifier::air::layouts::starknet_with_keccak::{ global_values::GlobalValues, autogenerated::eval_composition_polynomial_inner_part_7, }; +<<<<<<< HEAD use starknet::ContractAddress; +======= +>>>>>>> autogenerated_split #[storage] struct Storage {} @@ -339,6 +396,7 @@ mod LayoutCompositionContract7 { } #[starknet::contract] +<<<<<<< HEAD mod LayoutOodsContract { use super::{ ILayoutOodsContract, ILayoutOodsContractDispatcher, ILayoutOodsContractDispatcherTrait @@ -350,6 +408,15 @@ mod LayoutOodsContract { struct Storage { continuation_contract1: ContractAddress, continuation_contract2: ContractAddress, +======= +mod LayoutOodsContract1 { + use super::ILayoutOodsContract; + use cairo_verifier::air::layouts::starknet_with_keccak::{global_values::GlobalValues,}; + + #[storage] + struct Storage { + continuation_contracts: Array, +>>>>>>> autogenerated_split } #[abi(embed_v0)] @@ -364,7 +431,11 @@ mod LayoutOodsContract { trace_generator: felt252, ) -> felt252 { let mut total_sum = ILayoutOodsContractDispatcher { +<<<<<<< HEAD contract_address: self.continuation_contract1.read() +======= + contract_address: continuation_contracts[0] +>>>>>>> autogenerated_split } .eval_oods_polynomial_inner( column_values, @@ -376,9 +447,13 @@ mod LayoutOodsContract { ); total_sum += +<<<<<<< HEAD ILayoutOodsContractDispatcher { contract_address: self.continuation_contract2.read() } +======= + ILayoutOodsContractDispatcher { contract_address: continuation_contracts[1] } +>>>>>>> autogenerated_split .eval_oods_polynomial_inner( column_values, oods_values.slice(349, oods_values.len() - 349), diff --git a/src/air/layouts/starknet_with_keccak/traces.cairo b/src/air/layouts/starknet_with_keccak/traces.cairo index d1106d12c..19584fd3b 100644 --- a/src/air/layouts/starknet_with_keccak/traces.cairo +++ b/src/air/layouts/starknet_with_keccak/traces.cairo @@ -8,7 +8,7 @@ use cairo_verifier::{ TableCommitmentConfig }, vector_commitment::vector_commitment::VectorCommitmentConfigTrait, - common::asserts::assert_in_range + common::asserts::assert_in_range, settings::VerifierSettings, }; // A protocol component (see stark.cairo for details about protocol components) for the traces @@ -123,7 +123,10 @@ fn traces_decommit( commitment: TracesCommitment, decommitment: TracesDecommitment, witness: TracesWitness, + settings: VerifierSettings, ) { - table_decommit(commitment.original, queries, decommitment.original, witness.original); - table_decommit(commitment.interaction, queries, decommitment.interaction, witness.interaction) + table_decommit(commitment.original, queries, decommitment.original, witness.original, settings); + table_decommit( + commitment.interaction, queries, decommitment.interaction, witness.interaction, settings + ) } diff --git a/src/air/public_input.cairo b/src/air/public_input.cairo index abbbda9e4..716ee67d4 100644 --- a/src/air/public_input.cairo +++ b/src/air/public_input.cairo @@ -7,6 +7,7 @@ use cairo_verifier::{ array_extend::ArrayExtend, array_append::ArrayAppendTrait, math::{pow, Felt252PartialOrd, Felt252Div}, }, + settings::{StoneVersion, VerifierSettings}, }; use core::{pedersen::PedersenTrait, hash::{HashStateTrait, HashStateExTrait, Hash}}; use poseidon::poseidon_hash_span; @@ -46,12 +47,6 @@ struct PublicInput { continuous_page_headers: Array } -#[derive(Drop, Copy, PartialEq, Serde)] -enum CairoVersion { - Cairo0, - Cairo1, -} - trait PublicInputTrait { fn verify_cairo0(self: @PublicInput) -> (felt252, felt252); fn verify_cairo1(self: @PublicInput) -> (felt252, felt252); @@ -61,7 +56,9 @@ trait PublicInputTrait { // Computes the hash of the public input, which is used as the initial seed for the Fiat-Shamir // heuristic. fn get_public_input_hash( - public_input: @PublicInput, n_verifier_friendly_commitment_layers: felt252 + public_input: @PublicInput, + n_verifier_friendly_commitment_layers: felt252, + settings: VerifierSettings, ) -> felt252 { // Main page hash. let mut main_page_hash_state = PedersenTrait::new(0); @@ -79,7 +76,13 @@ fn get_public_input_hash( let mut hash_data = ArrayTrait::::new(); - hash_data_init(ref hash_data, public_input, n_verifier_friendly_commitment_layers); + if settings.stone_version == StoneVersion::Stone6 { + hash_data.append(n_verifier_friendly_commitment_layers); + } + hash_data.append(*public_input.log_n_steps); + hash_data.append(*public_input.range_check_min); + hash_data.append(*public_input.range_check_max); + hash_data.append(*public_input.layout); hash_data.extend(public_input.dynamic_params.span()); @@ -119,33 +122,6 @@ fn get_public_input_hash( poseidon_hash_span(hash_data.span()) } -// Stone6 Prover version specific hash_data initialization -#[cfg(feature: 'stone6')] -fn hash_data_init( - ref hash_data: Array, - public_input: @PublicInput, - n_verifier_friendly_commitment_layers: felt252 -) { - hash_data.append(n_verifier_friendly_commitment_layers); - hash_data.append(*public_input.log_n_steps); - hash_data.append(*public_input.range_check_min); - hash_data.append(*public_input.range_check_max); - hash_data.append(*public_input.layout); -} - -// Stone5 Prover version specific hash_data initialization -#[cfg(feature: 'stone5')] -fn hash_data_init( - ref hash_data: Array, - public_input: @PublicInput, - _n_verifier_friendly_commitment_layers: felt252 -) { - hash_data.append(*public_input.log_n_steps); - hash_data.append(*public_input.range_check_min); - hash_data.append(*public_input.range_check_max); - hash_data.append(*public_input.layout); -} - // Returns the ratio between the product of all public memory cells and z^|public_memory|. // This is the value that needs to be at the memory__multi_column_perm__perm__public_memory_prod // member expression. @@ -210,17 +186,22 @@ fn verify_cairo1_public_input(public_input: @PublicInput) -> (felt252, felt252) } -#[cfg(feature: 'stone5')] #[cfg(feature: 'recursive')] #[cfg(test)] mod tests { use super::get_public_input_hash; use cairo_verifier::tests::stone_proof_fibonacci_keccak::public_input::get; + use cairo_verifier::settings::{VerifierSettings, CairoVersion, HasherBitLength, StoneVersion}; #[test] #[available_gas(9999999999)] fn test_get_public_input_hash() { + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo1, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; let public_input = get(); - let hash = get_public_input_hash(@public_input, 0); + let hash = get_public_input_hash(@public_input, 0, settings); assert( hash == 0xaf91f2c71f4a594b1575d258ce82464475c82d8fb244142d0db450491c1b52, 'Hash invalid' ) diff --git a/src/benches/air/traces/decommit.cairo b/src/benches/air/traces/decommit.cairo index adac95790..66c4b6a1b 100644 --- a/src/benches/air/traces/decommit.cairo +++ b/src/benches/air/traces/decommit.cairo @@ -1,6 +1,7 @@ use cairo_verifier::{ channel::channel::ChannelImpl, air::layouts::recursive::{traces::traces_decommit}, tests::stone_proof_fibonacci, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; fn bench_air_traces_decommit() { @@ -9,5 +10,10 @@ fn bench_air_traces_decommit() { let decommitment = stone_proof_fibonacci::traces::decommitment::get(); let witness = stone_proof_fibonacci::traces::witness::get(); - traces_decommit(queries, commitment, decommitment, witness); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; + traces_decommit(queries, commitment, decommitment, witness, settings); } diff --git a/src/benches/stark/stark_proof_verify.cairo b/src/benches/stark/stark_proof_verify.cairo index 5db784088..75ce01e50 100644 --- a/src/benches/stark/stark_proof_verify.cairo +++ b/src/benches/stark/stark_proof_verify.cairo @@ -1,5 +1,8 @@ use starknet::contract_address::ContractAddressZero; -use cairo_verifier::{stark::{StarkProof, StarkProofTrait}, tests::stone_proof_fibonacci_keccak}; +use cairo_verifier::{ + stark::{StarkProof, StarkProofTrait}, tests::stone_proof_fibonacci_keccak, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, +}; fn bench_stark_proof_verify() { let SECURITY_BITS: u32 = 50; @@ -11,7 +14,12 @@ fn bench_stark_proof_verify() { witness: stone_proof_fibonacci_keccak::stark::witness::get(), }; + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; let security_bits = stark_proof - .verify(ContractAddressZero::zero(), ContractAddressZero::zero()); + .verify(ContractAddressZero::zero(), ContractAddressZero::zero(), settings); assert(security_bits >= SECURITY_BITS, 'Security bits too low'); } diff --git a/src/benches/stark/verify.cairo b/src/benches/stark/verify.cairo index b117610b6..0ca6eb405 100644 --- a/src/benches/stark/verify.cairo +++ b/src/benches/stark/verify.cairo @@ -2,6 +2,7 @@ use cairo_verifier::{ stark::stark_verify::stark_verify, air::layouts::recursive::constants::{NUM_COLUMNS_FIRST, NUM_COLUMNS_SECOND}, tests::stone_proof_fibonacci_keccak, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; fn bench_stark_verify() { @@ -10,6 +11,11 @@ fn bench_stark_verify() { let witness = stone_proof_fibonacci_keccak::stark::witness::get(); let stark_domains = stone_proof_fibonacci_keccak::stark::domains::get(); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; stark_verify( NUM_COLUMNS_FIRST, NUM_COLUMNS_SECOND, @@ -17,6 +23,7 @@ fn bench_stark_verify() { commitment, witness, stark_domains, - 0.try_into().unwrap() + 0.try_into().unwrap(), + settings, ); } diff --git a/src/common/hasher.cairo b/src/common/hasher.cairo index 7c2acb2df..75c6c1758 100644 --- a/src/common/hasher.cairo +++ b/src/common/hasher.cairo @@ -1,72 +1,50 @@ -use cairo_verifier::common::{ - blake2s::blake2s, blake2s_u8::blake2s as blake2s_u8, flip_endianness::FlipEndiannessTrait +use cairo_verifier::{ + common::{ + blake2s::blake2s, blake2s_u8::blake2s as blake2s_u8, flip_endianness::FlipEndiannessTrait, + }, + settings::{VerifierSettings, HasherBitLength}, }; -#[cfg(feature: 'blake2s_160_lsb')] -fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { - if hash_len { - data.append(n); - } - blake2s_u8(data) -} - -#[cfg(feature: 'blake2s_160_lsb')] -fn hash_truncated(data: Array) -> felt252 { - (blake2s(data).flip_endianness() - & 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - .try_into() - .unwrap() -} -#[cfg(feature: 'blake2s_160_lsb')] +#[cfg(feature: 'blake2s')] fn hash(data: Array) -> u256 { blake2s(data) } -#[cfg(feature: 'blake2s_248_lsb')] -fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { - if hash_len { - data.append(n); - } - blake2s_u8(data) +#[cfg(feature: 'keccak')] +fn hash(mut data: Array) -> u256 { + keccak::cairo_keccak(ref data, 0, 0) } -#[cfg(feature: 'blake2s_248_lsb')] -fn hash_truncated(data: Array) -> felt252 { - (blake2s(data).flip_endianness() - & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - .try_into() - .unwrap() +#[cfg(feature: 'blake2s')] +fn hash_truncated(data: Array, settings: VerifierSettings) -> felt252 { + let mask = if settings.hasher_bit_length == HasherBitLength::Lsb160 { + 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + } else { + 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + }; + (blake2s(data).flip_endianness() & mask).try_into().unwrap() } -#[cfg(feature: 'blake2s_248_lsb')] -fn hash(data: Array) -> u256 { - blake2s(data) +#[cfg(feature: 'keccak')] +fn hash_truncated(mut data: Array, settings: VerifierSettings) -> felt252 { + let mask = if settings.hasher_bit_length == HasherBitLength::Lsb160 { + 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + } else { + 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + }; + (keccak::cairo_keccak(ref data, 0, 0).flip_endianness() & mask).try_into().unwrap() } -#[cfg(feature: 'keccak_160_lsb')] -fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { +#[cfg(feature: 'blake2s')] +fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { if hash_len { - keccak::cairo_keccak(ref data, n.into(), 1) - } else { - keccak::cairo_keccak(ref data, 0, 0) + data.append(n); } + blake2s_u8(data) } -#[cfg(feature: 'keccak_160_lsb')] -fn hash_truncated(mut data: Array) -> felt252 { - (keccak::cairo_keccak(ref data, 0, 0).flip_endianness() - & 0x0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - .try_into() - .unwrap() -} - -#[cfg(feature: 'keccak_160_lsb')] -fn hash(mut data: Array) -> u256 { - keccak::cairo_keccak(ref data, 0, 0) -} - -#[cfg(feature: 'keccak_248_lsb')] +#[cfg(feature: 'keccak')] fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { if hash_len { keccak::cairo_keccak(ref data, n.into(), 1) @@ -74,16 +52,3 @@ fn hash_n_bytes(mut data: Array, n: u8, hash_len: bool) -> u256 { keccak::cairo_keccak(ref data, 0, 0) } } - -#[cfg(feature: 'keccak_248_lsb')] -fn hash_truncated(mut data: Array) -> felt252 { - (keccak::cairo_keccak(ref data, 0, 0).flip_endianness() - & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - .try_into() - .unwrap() -} - -#[cfg(feature: 'keccak_248_lsb')] -fn hash(mut data: Array) -> u256 { - keccak::cairo_keccak(ref data, 0, 0) -} diff --git a/src/fact_registry.cairo b/src/fact_registry.cairo index 0ab70e4dd..e429aa281 100644 --- a/src/fact_registry.cairo +++ b/src/fact_registry.cairo @@ -1,38 +1,90 @@ use cairo_verifier::{ - StarkProofWithSerde, CairoVersion, + StarkProofWithSerde, fri::fri::{FriLayerWitness, FriVerificationStateConstant, FriVerificationStateVariable}, - verifier::InitResult, + verifier::InitResult, settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; use starknet::ContractAddress; +// settings that identify the verifier (hardcoded in verifier) #[derive(Drop, Copy, Serde)] -struct VerifierSettings { +struct VerifierPreset { layout: felt252, hasher: felt252, - version: felt252, } -fn settings_to_struct(tuple: (felt252, felt252, felt252)) -> VerifierSettings { - let (layout, hasher, version) = tuple; - VerifierSettings { layout, hasher, version } +// both hardcoded settings and parameters merged together +#[derive(Drop, Copy, Serde)] +struct VerifierConfiguration { + layout: felt252, // string encoded as hex + hasher: felt252, // function and number of bits + stone_version: felt252, // stone5 or stone6 + cairo_version: felt252, // cairo0 or cairo1 +} + +fn verifier_configuration_to_tuple( + verifier_config: VerifierConfiguration +) -> (felt252, felt252, felt252, felt252) { + ( + verifier_config.layout, + verifier_config.hasher, + verifier_config.stone_version, + verifier_config.cairo_version, + ) } -fn settings_from_struct(settings: VerifierSettings) -> (felt252, felt252, felt252) { - (settings.layout, settings.hasher, settings.version) +fn verifier_configuration_from_tuple( + tuple: (felt252, felt252, felt252, felt252) +) -> VerifierConfiguration { + let (layout, hasher, stone_version, cairo_version) = tuple; + VerifierConfiguration { layout, hasher, stone_version, cairo_version, } +} + +fn split_settings(verifier_config: VerifierConfiguration) -> (VerifierSettings, VerifierPreset) { + let layout = verifier_config.layout; + + let cairo_version = if verifier_config.cairo_version == 'cairo0' { + CairoVersion::Cairo0 + } else { + assert(verifier_config.cairo_version == 'cairo1', 'Unsupported variant'); + CairoVersion::Cairo1 + }; + + let (hasher, hasher_bit_length) = if verifier_config.hasher == 'keccak_160_lsb' { + ('keccak', HasherBitLength::Lsb160) + } else if verifier_config.hasher == 'keccak_248_lsb' { + ('keccak', HasherBitLength::Lsb248) + } else if verifier_config.hasher == 'blake2s_160_lsb' { + ('blake2s', HasherBitLength::Lsb248) + } else { + assert(verifier_config.hasher == 'blake2s_248_lsb', 'Unsupported variant'); + ('blake2s', HasherBitLength::Lsb248) + }; + + let stone_version = if verifier_config.stone_version == 'stone5' { + StoneVersion::Stone5 + } else { + assert(verifier_config.stone_version == 'stone6', 'Unsupported variant'); + StoneVersion::Stone6 + }; + + ( + VerifierSettings { cairo_version, hasher_bit_length, stone_version }, + VerifierPreset { layout, hasher } + ) } #[derive(Drop, Copy, Serde)] struct VerificationListElement { verification_hash: felt252, security_bits: u32, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, } #[derive(Drop, Copy, Serde)] struct Verification { fact_hash: felt252, security_bits: u32, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, } #[derive(Drop, Copy, Serde, starknet::Event)] @@ -44,7 +96,7 @@ struct FactRegistered { #[key] security_bits: u32, #[key] - settings: VerifierSettings, + verifier_config: VerifierConfiguration, #[key] verification_hash: felt252, } @@ -54,16 +106,14 @@ trait IFactRegistry { fn verify_proof_full_and_register_fact( ref self: TContractState, stark_proof: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, ) -> FactRegistered; fn verify_proof_initial( ref self: TContractState, job_id: felt252, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + stark_proof: StarkProofWithSerde, + verifier_config: VerifierConfiguration, ) -> InitResult; fn verify_proof_step( @@ -72,7 +122,6 @@ trait IFactRegistry { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, witness: FriLayerWitness, - settings: VerifierSettings, ) -> (FriVerificationStateVariable, u32); fn verify_proof_final_and_register_fact( @@ -81,7 +130,6 @@ trait IFactRegistry { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - settings: VerifierSettings, ) -> FactRegistered; fn get_all_verifications_for_fact_hash( @@ -89,9 +137,9 @@ trait IFactRegistry { ) -> Array; fn get_verification(self: @TContractState, verification_hash: felt252) -> Option; - fn get_verifier_address(self: @TContractState, settings: VerifierSettings) -> ContractAddress; + fn get_verifier_address(self: @TContractState, preset: VerifierPreset) -> ContractAddress; fn register_verifier( - ref self: TContractState, settings: VerifierSettings, address: ContractAddress + ref self: TContractState, address: ContractAddress, preset: VerifierPreset ); fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); } @@ -109,8 +157,9 @@ mod FactRegistry { starknet::event::EventEmitter }; use super::{ - VerifierSettings, VerificationListElement, Verification, IFactRegistry, FactRegistered, - settings_from_struct, settings_to_struct + VerifierPreset, VerificationListElement, Verification, IFactRegistry, FactRegistered, + VerifierConfiguration, split_settings, verifier_configuration_from_tuple, + verifier_configuration_to_tuple }; #[storage] @@ -122,8 +171,11 @@ mod FactRegistry { (felt252, u32), felt252 >, // fact_hash, index => verification_hash verification_hashes: LegacyMap< - felt252, Option<(felt252, u32, (felt252, felt252, felt252))> - >, // verification_hash => (fact_hash, security_bits, settings) + felt252, Option<(felt252, u32, (felt252, felt252, felt252, felt252))> + >, // verification_hash => (fact_hash, security_bits, VerifierConfiguration) + verifier_configs: LegacyMap< + felt252, Option<(felt252, felt252, felt252, felt252)> + >, // job_id => VerifierConfiguration } #[event] @@ -136,10 +188,10 @@ mod FactRegistry { #[derive(Drop, starknet::Event)] struct VerifierRegistered { - #[key] - settings: VerifierSettings, #[key] address: ContractAddress, + #[key] + preset: VerifierPreset, } #[derive(Drop, starknet::Event)] @@ -158,27 +210,34 @@ mod FactRegistry { fn verify_proof_full_and_register_fact( ref self: ContractState, stark_proof: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, ) -> FactRegistered { - let verifier_address = self.get_verifier_address(settings); - let (fact_hash, security_bits) = ICairoVerifierDispatcher { - contract_address: verifier_address - } - .verify_proof_full(stark_proof.into(), cairo_version); + let (verifier_settings, verifier_preset) = split_settings(verifier_config); - self._register_fact(fact_hash, verifier_address, security_bits, settings) + let verifier_address = self.get_verifier_address(verifier_preset); + let result = ICairoVerifierDispatcher { contract_address: verifier_address } + .verify_proof_full(stark_proof.into(), verifier_settings); + + self + ._register_fact( + result.fact, verifier_address, result.security_bits, verifier_config + ) } fn verify_proof_initial( ref self: ContractState, job_id: felt252, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + stark_proof: StarkProofWithSerde, + verifier_config: VerifierConfiguration, ) -> InitResult { - ICairoVerifierDispatcher { contract_address: self.get_verifier_address(settings) } - .verify_proof_initial(job_id, stark_proof_serde, cairo_version) + self + .verifier_configs + .write(job_id, Option::Some(verifier_configuration_to_tuple(verifier_config))); + let (verifier_settings, verifier_preset) = split_settings(verifier_config); + ICairoVerifierDispatcher { + contract_address: self.get_verifier_address(verifier_preset) + } + .verify_proof_initial(job_id, stark_proof, verifier_settings) } fn verify_proof_step( @@ -187,9 +246,13 @@ mod FactRegistry { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, witness: FriLayerWitness, - settings: VerifierSettings, ) -> (FriVerificationStateVariable, u32) { - ICairoVerifierDispatcher { contract_address: self.get_verifier_address(settings) } + let verifier_config = verifier_configuration_from_tuple( + self.verifier_configs.read(job_id).expect('Job id not found') + ); + let (_, verifier_preset) = split_settings(verifier_config); + let verifier_address = self.get_verifier_address(verifier_preset); + ICairoVerifierDispatcher { contract_address: verifier_address } .verify_proof_step(job_id, state_constant, state_variable, witness) } @@ -199,18 +262,21 @@ mod FactRegistry { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - settings: VerifierSettings, ) -> FactRegistered { - let verifier_address = self.get_verifier_address(settings); - assert(verifier_address.into() != 0, 'VERIFIER_NOT_FOUND'); - let (fact_hash, security_bits) = ICairoVerifierDispatcher { - contract_address: verifier_address - } + let verifier_config = verifier_configuration_from_tuple( + self.verifier_configs.read(job_id).expect('Job id not found') + ); + let (_, verifier_preset) = split_settings(verifier_config); + let verifier_address = self.get_verifier_address(verifier_preset); + let result = ICairoVerifierDispatcher { contract_address: verifier_address } .verify_proof_final( job_id, state_constant, state_variable, last_layer_coefficients ); - self._register_fact(fact_hash, verifier_address, security_bits, settings) + self + ._register_fact( + result.fact, verifier_address, result.security_bits, verifier_config + ) } fn get_all_verifications_for_fact_hash( @@ -224,12 +290,17 @@ mod FactRegistry { break; } let verification_hash = self.fact_verifications.read((fact_hash, i)); - let (_, security_bits, settings_tuple) = self + let (_, security_bits, verifier_config_tuple) = self .verification_hashes .read(verification_hash) .unwrap(); - let settings = settings_to_struct(settings_tuple); - arr.append(VerificationListElement { verification_hash, security_bits, settings }); + let verifier_config = verifier_configuration_from_tuple(verifier_config_tuple); + arr + .append( + VerificationListElement { + verification_hash, security_bits, verifier_config + } + ); i += 1; }; arr @@ -240,31 +311,29 @@ mod FactRegistry { ) -> Option { match self.verification_hashes.read(verification_hash) { Option::Some(x) => { - let (fact_hash, security_bits, settings_tuple) = x; - let settings = settings_to_struct(settings_tuple); - Option::Some(Verification { fact_hash, security_bits, settings }) + let (fact_hash, security_bits, verifier_config_tuple) = x; + let verifier_config = verifier_configuration_from_tuple(verifier_config_tuple); + Option::Some(Verification { fact_hash, security_bits, verifier_config }) }, Option::None => { Option::None } } } - fn get_verifier_address( - self: @ContractState, settings: VerifierSettings - ) -> ContractAddress { - let verifier_address = self.verifiers.read(self._hash_settings(settings)); + fn get_verifier_address(self: @ContractState, preset: VerifierPreset) -> ContractAddress { + let verifier_address = self.verifiers.read(self._hash_preset(preset)); assert(verifier_address.into() != 0, 'VERIFIER_NOT_FOUND'); verifier_address } fn register_verifier( - ref self: ContractState, settings: VerifierSettings, address: ContractAddress + ref self: ContractState, address: ContractAddress, preset: VerifierPreset ) { assert(self.owner.read() == get_caller_address(), 'ONLY_OWNER'); assert(address.into() != 0, 'INVALID_VERIFIER_ADDRESS'); - let settings_hash = self._hash_settings(settings); - assert(self.verifiers.read(settings_hash).into() == 0, 'VERIFIER_ALREADY_EXISTS'); - self.verifiers.write(settings_hash, address); - self.emit(Event::VerifierRegistered(VerifierRegistered { settings, address })); + let preset_hash = self._hash_preset(preset); + assert(self.verifiers.read(preset_hash).into() == 0, 'VERIFIER_ALREADY_EXISTS'); + self.verifiers.write(preset_hash, address); + self.emit(Event::VerifierRegistered(VerifierRegistered { address, preset })); } fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { @@ -283,30 +352,35 @@ mod FactRegistry { #[generate_trait] impl InternalFactRegistry of InternalFactRegistryTrait { - fn _hash_settings(self: @ContractState, settings: VerifierSettings) -> felt252 { + fn _hash_configuration(self: @ContractState, config: VerifierConfiguration) -> felt252 { PoseidonImpl::new() - .update(settings.layout) - .update(settings.hasher) - .update(settings.version) + .update(config.layout) + .update(config.hasher) + .update(config.stone_version) + .update(config.cairo_version) .finalize() } + fn _hash_preset(self: @ContractState, preset: VerifierPreset) -> felt252 { + PoseidonImpl::new().update(preset.layout).update(preset.hasher).finalize() + } + fn _register_fact( ref self: ContractState, fact_hash: felt252, verifier_address: ContractAddress, security_bits: u32, - settings: VerifierSettings + verifier_config: VerifierConfiguration, ) -> FactRegistered { - let settings_hash = self._hash_settings(settings); + let verifier_config_hash = self._hash_configuration(verifier_config); let verification_hash = PoseidonImpl::new() .update(fact_hash) - .update(settings_hash) + .update(verifier_config_hash) .update(security_bits.into()) .finalize(); let event = FactRegistered { - fact_hash, verifier_address, security_bits, settings, verification_hash + fact_hash, verifier_address, security_bits, verifier_config, verification_hash }; self.emit(Event::FactRegistered(event)); @@ -317,7 +391,13 @@ mod FactRegistry { .verification_hashes .write( verification_hash, - Option::Some((fact_hash, security_bits, settings_from_struct(settings))) + Option::Some( + ( + fact_hash, + security_bits, + verifier_configuration_to_tuple(verifier_config) + ) + ) ); self.facts.write(fact_hash, next_index + 1); } diff --git a/src/fri/fri.cairo b/src/fri/fri.cairo index cdd998a33..66026f088 100644 --- a/src/fri/fri.cairo +++ b/src/fri/fri.cairo @@ -9,7 +9,8 @@ use cairo_verifier::{ table_commitment::table_commitment::{ TableCommitmentWitness, TableDecommitment, TableCommitment, TableCommitmentConfig, table_commit, table_decommit - } + }, + settings::VerifierSettings, }; use core::poseidon::{Poseidon, PoseidonImpl, HashStateImpl}; @@ -145,6 +146,7 @@ fn fri_verify_layer_step( eval_point: felt252, commitment: TableCommitment, layer_witness: FriLayerWitness, + settings: VerifierSettings, ) -> Array { // Compute fri_group. let fri_group = get_fri_group().span(); @@ -163,7 +165,8 @@ fn fri_verify_layer_step( commitment, verify_indices.span(), TableDecommitment { values: verify_y_values.span() }, - layer_witness.table_witness + layer_witness.table_witness, + settings, ); next_queries @@ -207,7 +210,8 @@ fn fri_verify_initial( fn fri_verify_step( stateConstant: FriVerificationStateConstant, stateVariable: FriVerificationStateVariable, - witness: FriLayerWitness + witness: FriLayerWitness, + settings: VerifierSettings ) -> (FriVerificationStateConstant, FriVerificationStateVariable) { assert(stateVariable.iter <= stateConstant.n_layers, 'Too many fri steps called'); @@ -218,6 +222,7 @@ fn fri_verify_step( *stateConstant.eval_points.at(stateVariable.iter), *stateConstant.commitment.at(stateVariable.iter), witness, + settings, ); ( diff --git a/src/lib.cairo b/src/lib.cairo index a2c83960b..ad29f2d2b 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -10,6 +10,7 @@ mod queries; mod stark; mod table_commitment; mod vector_commitment; +mod settings; mod verifier; mod fact_registry; @@ -21,8 +22,8 @@ mod benches; mod tests; use cairo_verifier::{ - air::public_input::CairoVersion, deserialization::stark::StarkProofWithSerde, - stark::{StarkProof, StarkProofImpl}, + deserialization::stark::StarkProofWithSerde, stark::{StarkProof, StarkProofImpl}, + settings::{VerifierSettings, CairoVersion}, }; use starknet::contract_address::ContractAddressZero; @@ -43,15 +44,15 @@ use cairo_verifier::air::layouts::starknet_with_keccak::public_input::StarknetWi const SECURITY_BITS: u32 = 50; #[cfg(feature: 'monolith')] -fn main(mut serialized: Span, cairo_version: CairoVersion) -> (felt252, felt252) { +fn main(mut serialized: Span, settings: VerifierSettings) -> (felt252, felt252) { let stark_proof_serde = Serde::::deserialize(ref serialized).unwrap(); let stark_proof: StarkProof = stark_proof_serde.into(); let security_bits = stark_proof - .verify(ContractAddressZero::zero(), ContractAddressZero::zero()); + .verify(ContractAddressZero::zero(), ContractAddressZero::zero(), settings); assert(security_bits >= SECURITY_BITS, 'Security bits are too low'); - let (program_hash, output_hash) = match cairo_version { + let (program_hash, output_hash) = match settings.cairo_version { CairoVersion::Cairo0 => stark_proof.public_input.verify_cairo0(), CairoVersion::Cairo1 => stark_proof.public_input.verify_cairo1(), }; diff --git a/src/proxy.cairo b/src/proxy.cairo index 41f0d0160..5c375daff 100644 --- a/src/proxy.cairo +++ b/src/proxy.cairo @@ -2,34 +2,25 @@ use cairo_verifier::{ StarkProofWithSerde, CairoVersion, fri::fri::{FriLayerWitness, FriVerificationStateConstant, FriVerificationStateVariable}, verifier::InitResult, - fact_registry::{FactRegistered, VerifierSettings, VerificationListElement, Verification}, + fact_registry::{ + FactRegistered, VerifierConfiguration, VerificationListElement, Verification, VerifierPreset + }, }; use starknet::{ContractAddress, ClassHash}; -fn settings_to_struct(tuple: (felt252, felt252, felt252)) -> VerifierSettings { - let (layout, hasher, version) = tuple; - VerifierSettings { layout, hasher, version } -} - -fn settings_from_struct(settings: VerifierSettings) -> (felt252, felt252, felt252) { - (settings.layout, settings.hasher, settings.version) -} - #[starknet::interface] trait IProxy { fn verify_proof_full_and_register_fact( ref self: TContractState, stark_proof: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, ) -> FactRegistered; fn verify_proof_initial( ref self: TContractState, job_id: felt252, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + stark_proof: StarkProofWithSerde, + verifier_config: VerifierConfiguration, ) -> InitResult; fn verify_proof_step( @@ -38,7 +29,6 @@ trait IProxy { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, witness: FriLayerWitness, - settings: VerifierSettings, ) -> (FriVerificationStateVariable, u32); fn verify_proof_final_and_register_fact( @@ -47,7 +37,6 @@ trait IProxy { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - settings: VerifierSettings, ) -> FactRegistered; fn get_all_verifications_for_fact_hash( @@ -55,9 +44,9 @@ trait IProxy { ) -> Array; fn get_verification(self: @TContractState, verification_hash: felt252) -> Option; - fn get_verifier_address(self: @TContractState, settings: VerifierSettings) -> ContractAddress; + fn get_verifier_address(self: @TContractState, preset: VerifierPreset) -> ContractAddress; fn register_verifier( - ref self: TContractState, settings: VerifierSettings, address: ContractAddress + ref self: TContractState, address: ContractAddress, preset: VerifierPreset ); fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); @@ -70,7 +59,9 @@ mod Proxy { use cairo_verifier::{ fact_registry::{ IFactRegistryDispatcher, IFactRegistryDispatcherTrait, - FactRegistry::{VerifierRegistered, OwnershipTransferred}, + FactRegistry::{VerifierRegistered, OwnershipTransferred}, VerifierSettings, + VerifierConfiguration, FactRegistered, VerificationListElement, Verification, + VerifierPreset }, StarkProofWithSerde, StarkProof, CairoVersion, verifier::{InitResult, ICairoVerifierDispatcher, ICairoVerifierDispatcherTrait}, @@ -81,10 +72,7 @@ mod Proxy { poseidon::{Poseidon, PoseidonImpl, HashStateImpl}, keccak::keccak_u256s_be_inputs, starknet::event::EventEmitter }; - use super::{ - VerifierSettings, VerificationListElement, Verification, IProxy, FactRegistered, - settings_from_struct, settings_to_struct - }; + use super::IProxy; #[event] #[derive(Drop, starknet::Event)] @@ -110,11 +98,10 @@ mod Proxy { fn verify_proof_full_and_register_fact( ref self: ContractState, stark_proof: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + verifier_config: VerifierConfiguration, ) -> FactRegistered { let fact = IFactRegistryDispatcher { contract_address: self.fact_registry.read() } - .verify_proof_full_and_register_fact(stark_proof, cairo_version, settings); + .verify_proof_full_and_register_fact(stark_proof, verifier_config); self.emit(fact); fact @@ -123,12 +110,11 @@ mod Proxy { fn verify_proof_initial( ref self: ContractState, job_id: felt252, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - settings: VerifierSettings, + stark_proof: StarkProofWithSerde, + verifier_config: VerifierConfiguration, ) -> InitResult { IFactRegistryDispatcher { contract_address: self.fact_registry.read() } - .verify_proof_initial(job_id, stark_proof_serde, cairo_version, settings) + .verify_proof_initial(job_id, stark_proof, verifier_config) } fn verify_proof_step( @@ -137,10 +123,9 @@ mod Proxy { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, witness: FriLayerWitness, - settings: VerifierSettings, ) -> (FriVerificationStateVariable, u32) { IFactRegistryDispatcher { contract_address: self.fact_registry.read() } - .verify_proof_step(job_id, state_constant, state_variable, witness, settings) + .verify_proof_step(job_id, state_constant, state_variable, witness) } fn verify_proof_final_and_register_fact( @@ -149,11 +134,10 @@ mod Proxy { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - settings: VerifierSettings, ) -> FactRegistered { let fact = IFactRegistryDispatcher { contract_address: self.fact_registry.read() } .verify_proof_final_and_register_fact( - job_id, state_constant, state_variable, last_layer_coefficients, settings + job_id, state_constant, state_variable, last_layer_coefficients ); self.emit(fact); @@ -174,19 +158,17 @@ mod Proxy { .get_verification(verification_hash) } - fn get_verifier_address( - self: @ContractState, settings: VerifierSettings - ) -> ContractAddress { + fn get_verifier_address(self: @ContractState, preset: VerifierPreset) -> ContractAddress { IFactRegistryDispatcher { contract_address: self.fact_registry.read() } - .get_verifier_address(settings) + .get_verifier_address(preset) } fn register_verifier( - ref self: ContractState, settings: VerifierSettings, address: ContractAddress + ref self: ContractState, address: ContractAddress, preset: VerifierPreset ) { IFactRegistryDispatcher { contract_address: self.fact_registry.read() } - .register_verifier(settings, address); - self.emit(Event::VerifierRegistered(VerifierRegistered { settings, address })); + .register_verifier(address, preset); + self.emit(Event::VerifierRegistered(VerifierRegistered { address, preset })); } fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { diff --git a/src/settings.cairo b/src/settings.cairo new file mode 100644 index 000000000..860d3a33a --- /dev/null +++ b/src/settings.cairo @@ -0,0 +1,70 @@ +#[derive(Drop, Copy, PartialEq, Serde)] +enum CairoVersion { + Cairo0, + Cairo1, +} + +#[derive(Drop, Copy, PartialEq, Serde)] +enum HasherBitLength { + Lsb160, + Lsb248, +} + +#[derive(Drop, Copy, PartialEq, Serde)] +enum StoneVersion { + Stone5, + Stone6, +} + +// settings accepted by verifier (parameters for verification) +#[derive(Drop, Copy, Serde)] +struct VerifierSettings { + cairo_version: CairoVersion, + hasher_bit_length: HasherBitLength, + stone_version: StoneVersion, +} + +fn verifier_settings_to_tuple(settings: VerifierSettings) -> (felt252, felt252, felt252) { + let cairo_version = match settings.cairo_version { + CairoVersion::Cairo0 => 0, + CairoVersion::Cairo1 => 1, + }; + let hasher_bit_length = match settings.hasher_bit_length { + HasherBitLength::Lsb160 => 0, + HasherBitLength::Lsb248 => 1, + }; + let stone_version = match settings.stone_version { + StoneVersion::Stone5 => 0, + StoneVersion::Stone6 => 1, + }; + (cairo_version, hasher_bit_length, stone_version) +} + +fn tuple_to_verifier_settings(tuple: (felt252, felt252, felt252)) -> VerifierSettings { + let (cairo_verifier, hasher_bit_length, stone_version) = tuple; + let cairo_version = match cairo_verifier { + 0 => CairoVersion::Cairo0, + 1 => CairoVersion::Cairo1, + _ => { + assert(false, 'invalid cairo_version'); + CairoVersion::Cairo0 + }, + }; + let hasher_bit_length = match hasher_bit_length { + 0 => HasherBitLength::Lsb160, + 1 => HasherBitLength::Lsb248, + _ => { + assert(false, 'invalid hasher_bit_length'); + HasherBitLength::Lsb160 + } + }; + let stone_version = match stone_version { + 0 => StoneVersion::Stone5, + 1 => StoneVersion::Stone6, + _ => { + assert(false, 'invalid stone_version'); + StoneVersion::Stone5 + } + }; + VerifierSettings { cairo_version, hasher_bit_length, stone_version, } +} diff --git a/src/stark.cairo b/src/stark.cairo index 62174466a..789e5caf4 100644 --- a/src/stark.cairo +++ b/src/stark.cairo @@ -22,7 +22,7 @@ use cairo_verifier::{ config::{ProofOfWorkConfig, ProofOfWorkConfigTrait}, proof_of_work::ProofOfWorkUnsentCommitment }, - vector_commitment::vector_commitment::VectorCommitmentConfigTrait, + vector_commitment::vector_commitment::VectorCommitmentConfigTrait, settings::VerifierSettings, }; use starknet::ContractAddress; #[cfg(feature: 'dex')] @@ -75,7 +75,8 @@ impl StarkProofImpl of StarkProofTrait { fn verify_initial( self: @StarkProof, composition_contract_address: ContractAddress, - oods_contract_address: ContractAddress + oods_contract_address: ContractAddress, + settings: VerifierSettings, ) -> (FriVerificationStateConstant, FriVerificationStateVariable, Span, u32) { // Validate config. let security_bits = self.config.validate(); @@ -88,7 +89,7 @@ impl StarkProofImpl of StarkProofTrait { // Compute the initial hash seed for the Fiat-Shamir channel. let digest = get_public_input_hash( - self.public_input, *self.config.n_verifier_friendly_commitment_layers + self.public_input, *self.config.n_verifier_friendly_commitment_layers, settings ); // Construct the channel. @@ -121,7 +122,8 @@ impl StarkProofImpl of StarkProofTrait { stark_commitment, *self.witness, stark_domains, - oods_contract_address + oods_contract_address, + settings, ); (con, var, last_layer_coefficients, security_bits) } @@ -129,9 +131,10 @@ impl StarkProofImpl of StarkProofTrait { fn verify_step( stateConstant: FriVerificationStateConstant, stateVariable: FriVerificationStateVariable, - witness: FriLayerWitness + witness: FriLayerWitness, + settings: VerifierSettings, ) -> (FriVerificationStateConstant, FriVerificationStateVariable) { - fri_verify_step(stateConstant, stateVariable, witness) + fri_verify_step(stateConstant, stateVariable, witness, settings) } fn verify_final( @@ -145,10 +148,11 @@ impl StarkProofImpl of StarkProofTrait { fn verify( self: @StarkProof, composition_contract_address: ContractAddress, - oods_contract_address: ContractAddress + oods_contract_address: ContractAddress, + settings: VerifierSettings, ) -> u32 { let (mut con, mut var, last_layer_coefficients, security_bits) = self - .verify_initial(composition_contract_address, oods_contract_address); + .verify_initial(composition_contract_address, oods_contract_address, settings); let n = con.n_layers; let mut i = 0; @@ -158,7 +162,7 @@ impl StarkProofImpl of StarkProofTrait { } let (new_con, new_var) = Self::verify_step( - con, var, *(*self.witness.fri_witness.layers).at(i) + con, var, *(*self.witness.fri_witness.layers).at(i), settings ); var = new_var; con = new_con; diff --git a/src/stark/stark_verify.cairo b/src/stark/stark_verify.cairo index 223da6644..d48fb50f7 100644 --- a/src/stark/stark_verify.cairo +++ b/src/stark/stark_verify.cairo @@ -6,7 +6,7 @@ use cairo_verifier::{ }, stark::{StarkUnsentCommitment, StarkWitness, StarkCommitment}, table_commitment::table_commitment::table_decommit, - oods::{OodsEvaluationInfo, eval_oods_boundary_poly_at_points}, + oods::{OodsEvaluationInfo, eval_oods_boundary_poly_at_points}, settings::VerifierSettings, }; use starknet::ContractAddress; #[cfg(feature: 'dex')] @@ -32,10 +32,11 @@ fn stark_verify( witness: StarkWitness, stark_domains: StarkDomains, contract_address_2: ContractAddress, + settings: VerifierSettings, ) -> (FriVerificationStateConstant, FriVerificationStateVariable) { // First layer decommit. traces_decommit( - queries, commitment.traces, witness.traces_decommitment, witness.traces_witness + queries, commitment.traces, witness.traces_decommitment, witness.traces_witness, settings, ); table_decommit( @@ -43,6 +44,7 @@ fn stark_verify( queries, witness.composition_decommitment, witness.composition_witness, + settings, ); // Compute query points. diff --git a/src/stark/tests/test_stark_proof_verify.cairo b/src/stark/tests/test_stark_proof_verify.cairo index 9ef89c4e1..368025fb3 100644 --- a/src/stark/tests/test_stark_proof_verify.cairo +++ b/src/stark/tests/test_stark_proof_verify.cairo @@ -1,7 +1,8 @@ use starknet::contract_address::ContractAddressZero; use cairo_verifier::{ stark::{StarkProof, StarkProofTrait}, - tests::{stone_proof_fibonacci, stone_proof_fibonacci_keccak} + tests::{stone_proof_fibonacci, stone_proof_fibonacci_keccak}, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; #[cfg(feature: 'blake2s')] @@ -17,8 +18,13 @@ fn test_stark_proof_fibonacci_verify() { witness: stone_proof_fibonacci::stark::witness::get(), }; + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; let security_bits = stark_proof - .verify(ContractAddressZero::zero(), ContractAddressZero::zero()); + .verify(ContractAddressZero::zero(), ContractAddressZero::zero(), settings); assert(security_bits >= SECURITY_BITS, 'Security bits too low'); } @@ -35,7 +41,12 @@ fn test_stark_proof_fibonacci_verify() { witness: stone_proof_fibonacci_keccak::stark::witness::get(), }; + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; let security_bits = stark_proof - .verify(ContractAddressZero::zero(), ContractAddressZero::zero()); + .verify(ContractAddressZero::zero(), ContractAddressZero::zero(), settings); assert(security_bits >= SECURITY_BITS, 'Security bits too low'); } diff --git a/src/stark/tests/test_stark_verify.cairo b/src/stark/tests/test_stark_verify.cairo index b95366fab..3e1113a25 100644 --- a/src/stark/tests/test_stark_verify.cairo +++ b/src/stark/tests/test_stark_verify.cairo @@ -1,7 +1,8 @@ use cairo_verifier::{ stark::stark_verify::stark_verify, air::layouts::recursive::constants::{NUM_COLUMNS_FIRST, NUM_COLUMNS_SECOND}, - tests::{stone_proof_fibonacci, stone_proof_fibonacci_keccak} + tests::{stone_proof_fibonacci, stone_proof_fibonacci_keccak}, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; #[cfg(feature: 'blake2s')] @@ -13,6 +14,11 @@ fn test_stark_verify() { let witness = stone_proof_fibonacci::stark::witness::get(); let stark_domains = stone_proof_fibonacci::stark::domains::get(); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; stark_verify( NUM_COLUMNS_FIRST, NUM_COLUMNS_SECOND, @@ -20,7 +26,8 @@ fn test_stark_verify() { commitment, witness, stark_domains, - 0.try_into().unwrap() + 0.try_into().unwrap(), + settings ); } @@ -33,6 +40,11 @@ fn test_stark_verify() { let witness = stone_proof_fibonacci_keccak::stark::witness::get(); let stark_domains = stone_proof_fibonacci_keccak::stark::domains::get(); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; stark_verify( NUM_COLUMNS_FIRST, NUM_COLUMNS_SECOND, @@ -40,7 +52,8 @@ fn test_stark_verify() { commitment, witness, stark_domains, - 0.try_into().unwrap() + 0.try_into().unwrap(), + settings ); // TODO: next steps } diff --git a/src/table_commitment/table_commitment.cairo b/src/table_commitment/table_commitment.cairo index 3ea069f3f..15d3dfe7a 100644 --- a/src/table_commitment/table_commitment.cairo +++ b/src/table_commitment/table_commitment.cairo @@ -7,7 +7,7 @@ use cairo_verifier::{ VectorCommitmentConfig, VectorCommitment, VectorCommitmentWitness, vector_commit, VectorQuery, vector_commitment_decommit }, - channel::channel::Channel + channel::channel::Channel, settings::VerifierSettings, }; use poseidon::poseidon_hash_span; @@ -59,6 +59,7 @@ fn table_decommit( queries: Span, decommitment: TableDecommitment, witness: TableCommitmentWitness, + settings: VerifierSettings, ) { let n_queries: felt252 = queries.len().into(); @@ -90,10 +91,13 @@ fn table_decommit( queries, montgomery_values.span(), n_columns.try_into().unwrap(), - is_bottom_layer_verifier_friendly + is_bottom_layer_verifier_friendly, + settings, ); - vector_commitment_decommit(commitment.vector_commitment, vector_queries.span(), witness.vector); + vector_commitment_decommit( + commitment.vector_commitment, vector_queries.span(), witness.vector, settings + ); } fn to_montgomery(mut arr: Span) -> Array { @@ -108,7 +112,11 @@ fn to_montgomery(mut arr: Span) -> Array { } fn generate_vector_queries( - queries: Span, values: Span, n_columns: u32, is_verifier_friendly: bool + queries: Span, + values: Span, + n_columns: u32, + is_verifier_friendly: bool, + settings: VerifierSettings ) -> Array { let queries_len = queries.len(); let mut vector_queries = ArrayTrait::new(); @@ -129,7 +137,7 @@ fn generate_vector_queries( let slice = values.slice(i * n_columns, n_columns); let mut data = ArrayTrait::new(); // u32 for blake, u64 for keccak data.append_big_endian(slice); - hash_truncated(data) + hash_truncated(data, settings) }; vector_queries.append(VectorQuery { index: *queries[i], value: hash }); i += 1; diff --git a/src/table_commitment/tests/test_table_commitment_decommit.cairo b/src/table_commitment/tests/test_table_commitment_decommit.cairo index 69755a9f5..7466ef5b2 100644 --- a/src/table_commitment/tests/test_table_commitment_decommit.cairo +++ b/src/table_commitment/tests/test_table_commitment_decommit.cairo @@ -6,7 +6,8 @@ use cairo_verifier::{ table_decommit, TableCommitment, TableCommitmentConfig, TableDecommitment, TableCommitmentWitness }, - tests::{stone_proof_fibonacci_keccak, stone_proof_fibonacci} + tests::{stone_proof_fibonacci_keccak, stone_proof_fibonacci}, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; #[cfg(feature: 'blake2s')] @@ -18,7 +19,12 @@ fn test_table_commitment_decommit() { let decommitment = stone_proof_fibonacci::traces::decommitment::get().original; let witness = stone_proof_fibonacci::traces::witness::get().original; - table_decommit(commitment, queries, decommitment, witness); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; + table_decommit(commitment, queries, decommitment, witness, settings); } #[cfg(feature: 'keccak')] @@ -30,5 +36,10 @@ fn test_table_commitment_decommit() { let decommitment = stone_proof_fibonacci_keccak::traces::decommitment::get().original; let witness = stone_proof_fibonacci_keccak::traces::witness::get().original; - table_decommit(commitment, queries, decommitment, witness); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; + table_decommit(commitment, queries, decommitment, witness, settings); } diff --git a/src/vector_commitment/tests/test_vector_commitment_decommit.cairo b/src/vector_commitment/tests/test_vector_commitment_decommit.cairo index 09f44f301..2e81a23d4 100644 --- a/src/vector_commitment/tests/test_vector_commitment_decommit.cairo +++ b/src/vector_commitment/tests/test_vector_commitment_decommit.cairo @@ -1,6 +1,9 @@ -use cairo_verifier::vector_commitment::vector_commitment::{ - VectorCommitment, VectorCommitmentConfig, VectorCommitmentWitness, vector_commit, VectorQuery, - vector_commitment_decommit, +use cairo_verifier::{ + vector_commitment::vector_commitment::{ + VectorCommitment, VectorCommitmentConfig, VectorCommitmentWitness, vector_commit, + VectorQuery, vector_commitment_decommit, + }, + settings::{VerifierSettings, HasherBitLength, StoneVersion, CairoVersion}, }; #[cfg(feature: 'blake2s')] @@ -104,7 +107,12 @@ fn test_vector_commitment_decommit_1() { .span(), }; - vector_commitment_decommit(commitment, queries, witness); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; + vector_commitment_decommit(commitment, queries, witness, settings); } #[cfg(feature: 'keccak')] @@ -208,5 +216,10 @@ fn test_vector_commitment_decommit() { .span(), }; - vector_commitment_decommit(commitment, queries, witness); + let settings = VerifierSettings { + cairo_version: CairoVersion::Cairo0, + hasher_bit_length: HasherBitLength::Lsb160, + stone_version: StoneVersion::Stone5, + }; + vector_commitment_decommit(commitment, queries, witness, settings); } diff --git a/src/vector_commitment/vector_commitment.cairo b/src/vector_commitment/vector_commitment.cairo index 5e1b9b7b1..8b6bd6498 100644 --- a/src/vector_commitment/vector_commitment.cairo +++ b/src/vector_commitment/vector_commitment.cairo @@ -3,7 +3,7 @@ use cairo_verifier::{ array_append::ArrayAppendTrait, math::pow, hasher::hash_truncated, math::DivRemFelt252, math::Felt252PartialOrd, }, - channel::channel::{Channel, ChannelImpl} + channel::channel::{Channel, ChannelImpl}, settings::VerifierSettings, }; use poseidon::hades_permutation; @@ -70,7 +70,10 @@ fn vector_commit( // Decommits a VectorCommitment at multiple indices. // Indices must be sorted and unique. fn vector_commitment_decommit( - commitment: VectorCommitment, queries: Span, witness: VectorCommitmentWitness, + commitment: VectorCommitment, + queries: Span, + witness: VectorCommitmentWitness, + settings: VerifierSettings ) { let shift = pow(2, commitment.config.height); let shifted_queries = shift_queries(queries, shift, commitment.config.height); @@ -80,7 +83,8 @@ fn vector_commitment_decommit( 0, commitment.config.n_verifier_friendly_commitment_layers, witness.authentications, - 0 + 0, + settings ); assert(expected_commitment == commitment.commitment_hash, 'decommitment failed'); @@ -94,7 +98,8 @@ fn compute_root_from_queries( start: u32, n_verifier_friendly_layers: felt252, authentications: Span, - auth_start: u32 + auth_start: u32, + settings: VerifierSettings ) -> felt252 { let current: VectorQueryWithDepth = *queue[start]; @@ -112,7 +117,9 @@ fn compute_root_from_queries( let next: VectorQueryWithDepth = *queue[start + 1]; if current.index + 1 == next.index { // next is a sibling of current - let hash = hash_blake_or_poseidon(current.value, next.value, is_verifier_friendly); + let hash = hash_blake_or_poseidon( + current.value, next.value, is_verifier_friendly, settings + ); queue .append( VectorQueryWithDepth { @@ -120,19 +127,28 @@ fn compute_root_from_queries( } ); return compute_root_from_queries( - queue, start + 2, n_verifier_friendly_layers, authentications, auth_start + queue, + start + 2, + n_verifier_friendly_layers, + authentications, + auth_start, + settings ); } } assert(auth_start != authentications.len(), 'authentications is too short'); - hash_blake_or_poseidon(current.value, *authentications[auth_start], is_verifier_friendly) + hash_blake_or_poseidon( + current.value, *authentications[auth_start], is_verifier_friendly, settings + ) } else { assert(auth_start != authentications.len(), 'authentications is too short'); - hash_blake_or_poseidon(*authentications[auth_start], current.value, is_verifier_friendly) + hash_blake_or_poseidon( + *authentications[auth_start], current.value, is_verifier_friendly, settings + ) }; queue.append(VectorQueryWithDepth { index: parent, value: hash, depth: current.depth - 1, }); compute_root_from_queries( - queue, start + 1, n_verifier_friendly_layers, authentications, auth_start + 1 + queue, start + 1, n_verifier_friendly_layers, authentications, auth_start + 1, settings ) } @@ -158,7 +174,9 @@ fn shift_queries( shifted_queries } -fn hash_blake_or_poseidon(x: felt252, y: felt252, is_verifier_friendly: bool) -> felt252 { +fn hash_blake_or_poseidon( + x: felt252, y: felt252, is_verifier_friendly: bool, settings: VerifierSettings +) -> felt252 { if is_verifier_friendly { let (hash, _, _) = hades_permutation(x, y, 2); hash @@ -166,6 +184,6 @@ fn hash_blake_or_poseidon(x: felt252, y: felt252, is_verifier_friendly: bool) -> let mut data = ArrayTrait::new(); // u32 for blake, u64 for keccak data.append_big_endian(x); data.append_big_endian(y); - hash_truncated(data) + hash_truncated(data, settings) } } diff --git a/src/verifier.cairo b/src/verifier.cairo index b322f5c09..707dd1701 100644 --- a/src/verifier.cairo +++ b/src/verifier.cairo @@ -1,6 +1,7 @@ use cairo_verifier::{ StarkProof, CairoVersion, StarkProofWithSerde, - fri::fri::{FriLayerWitness, FriVerificationStateConstant, FriVerificationStateVariable} + fri::fri::{FriLayerWitness, FriVerificationStateConstant, FriVerificationStateVariable}, + settings::VerifierSettings, }; #[derive(Drop, Serde)] @@ -14,13 +15,31 @@ struct InitResult { layers_left: u32, } +#[derive(Drop, Copy, Serde, starknet::Event)] +struct ProofVerified { + #[key] + job_id: felt252, + #[key] + fact: felt252, + #[key] + security_bits: u32, + #[key] + settings: VerifierSettings, +} + #[starknet::interface] trait ICairoVerifier { + fn verify_proof_full( + ref self: TContractState, + stark_proof_serde: StarkProofWithSerde, + settings: VerifierSettings, + ) -> ProofVerified; + fn verify_proof_initial( ref self: TContractState, job_id: felt252, stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, + settings: VerifierSettings, ) -> InitResult; fn verify_proof_step( @@ -37,13 +56,7 @@ trait ICairoVerifier { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - ) -> (felt252, u32); - - fn verify_proof_full( - ref self: TContractState, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - ) -> (felt252, u32); + ) -> ProofVerified; } #[starknet::contract] @@ -55,9 +68,10 @@ mod CairoVerifier { FriLayerWitness, FriVerificationStateConstant, FriVerificationStateVariable, hash_constant, hash_variable }, + settings::{VerifierSettings, verifier_settings_to_tuple, tuple_to_verifier_settings}, }; use core::poseidon::{Poseidon, PoseidonImpl, HashStateImpl}; - use super::{InitResult, ICairoVerifier}; + use super::{ProofVerified, InitResult, ICairoVerifier}; #[storage] struct Storage { @@ -67,6 +81,9 @@ mod CairoVerifier { state_variable: LegacyMap>, // job_id => hash(variable state) state_fact: LegacyMap>, // job_id => fact_hash state_security_bits: LegacyMap>, // job_id => security_bits + state_settings: LegacyMap< + felt252, Option<(felt252, felt252, felt252)> + >, // job_id => verifier_settings } #[constructor] @@ -85,28 +102,42 @@ mod CairoVerifier { ProofVerified: ProofVerified, } - #[derive(Drop, starknet::Event)] - struct ProofVerified { - #[key] - job_id: felt252, - #[key] - fact: felt252, - #[key] - security_bits: u32, - } - #[abi(embed_v0)] impl CairoVerifier of ICairoVerifier { + fn verify_proof_full( + ref self: ContractState, + stark_proof_serde: StarkProofWithSerde, + settings: VerifierSettings, + ) -> ProofVerified { + let stark_proof: StarkProof = stark_proof_serde.into(); + let (program_hash, output_hash) = match settings.cairo_version { + CairoVersion::Cairo0 => stark_proof.public_input.verify_cairo0(), + CairoVersion::Cairo1 => stark_proof.public_input.verify_cairo1(), + }; + let security_bits = stark_proof + .verify( + self.composition_contract_address.read(), + self.oods_contract_address.read(), + settings + ); + + let fact = PoseidonImpl::new().update(program_hash).update(output_hash).finalize(); + + let event = ProofVerified { job_id: 0, fact, security_bits, settings }; + self.emit(event); + event + } + fn verify_proof_initial( ref self: ContractState, job_id: felt252, stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, + settings: VerifierSettings, ) -> InitResult { assert(self.state_constant.read(job_id).is_none(), 'job_id already exists'); let stark_proof: StarkProof = stark_proof_serde.into(); - let (program_hash, output_hash) = match cairo_version { + let (program_hash, output_hash) = match settings.cairo_version { CairoVersion::Cairo0 => stark_proof.public_input.verify_cairo0(), CairoVersion::Cairo1 => stark_proof.public_input.verify_cairo1(), }; @@ -115,12 +146,15 @@ mod CairoVerifier { let (con, var, last_layer_coefficients, security_bits) = stark_proof .verify_initial( - self.composition_contract_address.read(), self.oods_contract_address.read() + self.composition_contract_address.read(), + self.oods_contract_address.read(), + settings ); self.state_constant.write(job_id, Option::Some(hash_constant(@con))); self.state_variable.write(job_id, Option::Some(hash_variable(@var))); self.state_fact.write(job_id, Option::Some(fact)); self.state_security_bits.write(job_id, Option::Some(security_bits)); + self.state_settings.write(job_id, Option::Some(verifier_settings_to_tuple(settings))); let layers_left = con.n_layers - var.iter; @@ -156,8 +190,13 @@ mod CairoVerifier { .expect('No state (variable) saved'), 'Invalid state (variable)' ); + let settings = tuple_to_verifier_settings( + self.state_settings.read(job_id).expect('No settings saved') + ); - let (con, var) = StarkProofImpl::verify_step(state_constant, state_variable, witness); + let (con, var) = StarkProofImpl::verify_step( + state_constant, state_variable, witness, settings + ); self.state_variable.write(job_id, Option::Some(hash_variable(@var))); let layers_left = con.n_layers - var.iter; @@ -171,7 +210,7 @@ mod CairoVerifier { state_constant: FriVerificationStateConstant, state_variable: FriVerificationStateVariable, last_layer_coefficients: Span, - ) -> (felt252, u32) { + ) -> ProofVerified { assert( hash_constant(@state_constant) == self.state_constant.read(job_id).unwrap(), 'Invalid state (constant)' @@ -191,34 +230,19 @@ mod CairoVerifier { ); assert(new_var.iter.into() == new_con.n_layers + 1, 'Verification not finalized'); + let settings = tuple_to_verifier_settings( + self.state_settings.read(job_id).expect('No settings saved') + ); + self.state_variable.write(job_id, Option::None); self.state_constant.write(job_id, Option::None); self.state_fact.write(job_id, Option::None); self.state_security_bits.write(job_id, Option::None); + self.state_settings.write(job_id, Option::None); - self.emit(ProofVerified { job_id, fact, security_bits }); - (fact, security_bits) - } - - fn verify_proof_full( - ref self: ContractState, - stark_proof_serde: StarkProofWithSerde, - cairo_version: CairoVersion, - ) -> (felt252, u32) { - let stark_proof: StarkProof = stark_proof_serde.into(); - let (program_hash, output_hash) = match cairo_version { - CairoVersion::Cairo0 => stark_proof.public_input.verify_cairo0(), - CairoVersion::Cairo1 => stark_proof.public_input.verify_cairo1(), - }; - let security_bits = stark_proof - .verify( - self.composition_contract_address.read(), self.oods_contract_address.read() - ); - - let fact = PoseidonImpl::new().update(program_hash).update(output_hash).finalize(); - - self.emit(ProofVerified { job_id: 0, fact, security_bits }); - (fact, security_bits) + let event = ProofVerified { job_id, fact, security_bits, settings }; + self.emit(event); + event } } }