diff --git a/crates/air/Cargo.toml b/crates/air/Cargo.toml index c333298..f1ccdda 100644 --- a/crates/air/Cargo.toml +++ b/crates/air/Cargo.toml @@ -22,6 +22,7 @@ recursive_with_poseidon = [] small = [] starknet = [] starknet_with_keccak = [] +dynamic = [] keccak_160_lsb = ["swiftness_commitment/keccak_160_lsb"] keccak_248_lsb = ["swiftness_commitment/keccak_248_lsb"] blake2s_160_lsb = ["swiftness_commitment/blake2s_160_lsb"] diff --git a/crates/air/src/layout/dynamic/mod.rs b/crates/air/src/layout/dynamic/mod.rs index c0609ab..df88840 100644 --- a/crates/air/src/layout/dynamic/mod.rs +++ b/crates/air/src/layout/dynamic/mod.rs @@ -1,9 +1,8 @@ pub mod autogenerated; pub mod global_values; -use std::borrow::ToOwned; - use crate::{ + alloc::borrow::ToOwned, diluted::get_diluted_product, layout::stark_curve, periodic_columns::{ diff --git a/crates/air/src/layout/mod.rs b/crates/air/src/layout/mod.rs index de70306..4dd805c 100644 --- a/crates/air/src/layout/mod.rs +++ b/crates/air/src/layout/mod.rs @@ -84,6 +84,8 @@ pub trait StaticLayoutTrait { const NUM_COLUMNS_SECOND: usize; } +pub trait DynamicLayoutTrait {} + pub fn safe_div(value: Felt, divisor: Felt) -> Result { Ok(value.floor_div(&NonZeroFelt::try_from(divisor)?)) } @@ -148,6 +150,12 @@ use thiserror_no_std::Error; #[cfg(not(feature = "std"))] #[derive(Error, Debug)] pub enum CompositionPolyEvalError { + #[error("segment not present {segment}")] + SegmentMissing { segment: usize }, + + #[error("value out of range")] + ValueOutOfRange, + #[error("dynamic params missing")] DynamicParamsMissing, diff --git a/crates/air/src/trace/config.rs b/crates/air/src/trace/config.rs index 07938e7..b1816bb 100644 --- a/crates/air/src/trace/config.rs +++ b/crates/air/src/trace/config.rs @@ -1,4 +1,3 @@ -use crate::layout::StaticLayoutTrait; use serde::{Deserialize, Serialize}; use starknet_crypto::Felt; use swiftness_commitment::vector; @@ -13,10 +12,12 @@ pub struct Config { } impl Config { - pub fn validate( + pub fn validate( &self, log_eval_domain_size: Felt, n_verifier_friendly_commitment_layers: Felt, + n_columns_original: Felt, + n_columns_interaction: Felt, ) -> Result<(), Error> { if self.original.n_columns < Felt::ONE || self.original.n_columns > MAX_N_COLUMNS { return Err(Error::OutOfBounds { min: Felt::ONE, max: MAX_N_COLUMNS }); @@ -25,11 +26,11 @@ impl Config { return Err(Error::OutOfBounds { min: Felt::ONE, max: MAX_N_COLUMNS }); } - if self.original.n_columns != Layout::NUM_COLUMNS_FIRST.into() { + if self.original.n_columns != n_columns_original { return Err(Error::ColumnsNumInvalid); } - if self.interaction.n_columns != Layout::NUM_COLUMNS_SECOND.into() { + if self.interaction.n_columns != n_columns_interaction { return Err(Error::ColumnsNumInvalid); } diff --git a/crates/stark/Cargo.toml b/crates/stark/Cargo.toml index 43b32ce..d4f535f 100644 --- a/crates/stark/Cargo.toml +++ b/crates/stark/Cargo.toml @@ -27,9 +27,8 @@ recursive_with_poseidon = [ ] small = ["swiftness_air/small"] starknet = ["swiftness_air/starknet"] -starknet_with_keccak = [ - "swiftness_air/starknet_with_keccak", -] +starknet_with_keccak = ["swiftness_air/starknet_with_keccak"] +dynamic = ["swiftness_air/dynamic"] keccak_160_lsb = [ "swiftness_pow/keccak", "swiftness_commitment/keccak_160_lsb" diff --git a/crates/stark/src/config.rs b/crates/stark/src/config.rs index 06e33e0..4a75090 100644 --- a/crates/stark/src/config.rs +++ b/crates/stark/src/config.rs @@ -1,6 +1,12 @@ +use crate::alloc::borrow::ToOwned; use serde::{Deserialize, Serialize}; use serde_with::serde_as; use starknet_crypto::Felt; +use swiftness_air::{ + layout::{DynamicLayoutTrait, StaticLayoutTrait}, + public_memory::PublicInput, +}; +use swiftness_commitment::vector; #[serde_as] #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -41,15 +47,22 @@ impl StarkConfig { self.n_queries * self.log_n_cosets + Felt::from(self.proof_of_work.n_bits) } - pub fn validate(&self, security_bits: Felt) -> Result<(), Error> { + pub fn validate_static_layout( + &self, + security_bits: Felt, + ) -> Result<(), Error> { self.proof_of_work.validate()?; - assert!(security_bits <= self.security_bits()); + ensure!(security_bits <= self.security_bits(), Error::InsufficientSecurity); // Validate traces config. let log_eval_domain_size = self.log_trace_domain_size + self.log_n_cosets; - self.traces - .validate::(log_eval_domain_size, self.n_verifier_friendly_commitment_layers)?; + self.traces.validate( + log_eval_domain_size, + self.n_verifier_friendly_commitment_layers, + Layout::NUM_COLUMNS_FIRST.into(), + Layout::NUM_COLUMNS_SECOND.into(), + )?; // Validate composition config. self.composition @@ -60,11 +73,40 @@ impl StarkConfig { self.fri.validate(self.log_n_cosets, self.n_verifier_friendly_commitment_layers)?; Ok(()) } -} -use swiftness_air::layout::StaticLayoutTrait; -use swiftness_commitment::vector; + pub fn validate_dynamic_layout( + &self, + security_bits: Felt, + public_input: &PublicInput, + ) -> Result<(), Error> { + self.proof_of_work.validate()?; + + ensure!(security_bits <= self.security_bits(), Error::InsufficientSecurity); + + let dynamc_params = + public_input.dynamic_params.to_owned().ok_or(Error::DynamicParamsMissing)?; + + // Validate traces config. + let log_eval_domain_size = self.log_trace_domain_size + self.log_n_cosets; + self.traces.validate( + log_eval_domain_size, + self.n_verifier_friendly_commitment_layers, + dynamc_params.num_columns_first.into(), + dynamc_params.num_columns_second.into(), + )?; + + // Validate composition config. + self.composition + .vector + .validate(log_eval_domain_size, self.n_verifier_friendly_commitment_layers)?; + + // Validate Fri config. + self.fri.validate(self.log_n_cosets, self.n_verifier_friendly_commitment_layers)?; + Ok(()) + } +} +use swiftness_transcript::ensure; #[cfg(feature = "std")] use thiserror::Error; @@ -79,6 +121,10 @@ pub enum Error { Pow(#[from] swiftness_pow::config::Error), #[error("Trace Error")] Trace(#[from] swiftness_air::trace::config::Error), + #[error("dynamic params missing")] + DynamicParamsMissing, + #[error("insufficient number ofsecurity bits")] + InsufficientSecurity, } #[cfg(not(feature = "std"))] @@ -95,4 +141,8 @@ pub enum Error { Pow(#[from] swiftness_pow::config::Error), #[error("Trace Error")] Trace(#[from] swiftness_air::trace::config::Error), + #[error("dynamic params missing")] + DynamicParamsMissing, + #[error("insufficient number ofsecurity bits")] + InsufficientSecurity, } diff --git a/crates/stark/src/stark.rs b/crates/stark/src/stark.rs index aea43c5..7ed6992 100644 --- a/crates/stark/src/stark.rs +++ b/crates/stark/src/stark.rs @@ -37,7 +37,18 @@ impl StarkProof { &self, security_bits: Felt, ) -> Result<(Felt, Felt), Error> { - self.config.validate::(security_bits)?; + #[cfg(any( + feature = "dex", + feature = "recursive", + feature = "recursive_with_poseidon", + feature = "small", + feature = "starknet", + feature = "starknet_with_keccak" + ))] + self.config.validate_static_layout::(security_bits)?; + + #[cfg(feature = "dynamic")] + self.config.validate_dynamic_layout::(security_bits, &self.public_input)?; // Validate the public input. let stark_domains = diff --git a/crates/stark/src/verify.rs b/crates/stark/src/verify.rs index faa8d5a..dcba729 100644 --- a/crates/stark/src/verify.rs +++ b/crates/stark/src/verify.rs @@ -1,9 +1,6 @@ use alloc::borrow::ToOwned; use starknet_crypto::Felt; -use swiftness_air::{ - domains::StarkDomains, - layout::{LayoutTrait, StaticLayoutTrait}, public_memory::PublicInput, -}; +use swiftness_air::{domains::StarkDomains, layout::LayoutTrait, public_memory::PublicInput}; use swiftness_commitment::table::decommit::table_decommit; use swiftness_fri::{ fri::{self, fri_verify}, @@ -17,7 +14,7 @@ use crate::{ }; // STARK verify phase. -pub fn stark_verify( +pub fn stark_verify( n_original_columns: usize, n_interaction_columns: usize, public_input: &PublicInput,