diff --git a/Cargo.lock b/Cargo.lock index 0897a93..dfc431a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,7 +120,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] @@ -131,7 +131,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] @@ -350,14 +350,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -411,7 +411,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] @@ -423,7 +423,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.92" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -646,7 +646,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.92", + "syn 2.0.95", ] [[package]] diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 87cce83..10a58b5 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -90,6 +90,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "blake2" version = "0.10.6" @@ -549,6 +555,9 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ + "base64 0.22.1", + "chrono", + "hex", "serde", "serde_derive", "serde_with_macros 3.12.0", @@ -618,6 +627,25 @@ dependencies = [ "starknet-types-core", ] +[[package]] +name = "starknet-core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538240cbe6663c673fe77465f294da707080f39678dd7066761554899e46100" +dependencies = [ + "base64 0.21.7", + "crypto-bigint", + "flate2", + "hex", + "serde", + "serde_json", + "serde_json_pythonic", + "serde_with 3.9.0", + "sha3", + "starknet-crypto", + "starknet-types-core", +] + [[package]] name = "starknet-crypto" version = "0.7.3" @@ -677,6 +705,7 @@ name = "swiftness" version = "0.1.3" dependencies = [ "clap", + "starknet-core 0.12.0", "swiftness_air", "swiftness_commitment", "swiftness_fri", @@ -710,7 +739,7 @@ dependencies = [ "serde", "serde_with 3.12.0", "sha3", - "starknet-core", + "starknet-core 0.11.1", "starknet-crypto", "starknet-types-core", "swiftness_transcript", @@ -726,7 +755,7 @@ dependencies = [ "serde", "serde_with 3.12.0", "sha3", - "starknet-core", + "starknet-core 0.11.1", "starknet-crypto", "swiftness_commitment", "swiftness_transcript", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 307771f..7e1bd6b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.3" [dependencies] clap = { version = "4.4.4", features = ["derive"] } +starknet-core = "0.12.0" swiftness_air = { path = "../crates/air", default-features = false, features = [ "std", @@ -68,4 +69,4 @@ blake2s_160_lsb = [ blake2s_248_lsb = [ "swiftness_air/blake2s_248_lsb", "swiftness_stark/blake2s_248_lsb", -] \ No newline at end of file +] diff --git a/cli/src/main.rs b/cli/src/main.rs index 0b1e4c0..2d22694 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -27,13 +27,24 @@ struct CairoVMVerifier { /// Path to proof JSON file #[clap(short, long)] proof: PathBuf, + /// Whether to print the pedersen hash of the output instead of the full output. + #[clap(short = 'o', long, num_args=0..=1, default_missing_value = "true")] + print_output_hash: Option, } fn main() -> Result<(), Box> { let cli = CairoVMVerifier::parse(); let stark_proof = parse(std::fs::read_to_string(cli.proof)?)?.transform_to(); let security_bits = stark_proof.config.security_bits(); - let result = stark_proof.verify::(security_bits)?; - println!("{:?}", result); + let (program_hash, program_output) = stark_proof.verify::(security_bits)?; + + println!("program hash: {:#x}", program_hash); + if let Some(true) = cli.print_output_hash { + let hash = starknet_core::crypto::compute_hash_on_elements(&program_output); + println!("program output hash: {:#x}", hash); + } else { + println!("program output: {:x?}", program_output); + } + Ok(()) } diff --git a/crates/air/src/layout/dex/mod.rs b/crates/air/src/layout/dex/mod.rs index 80de416..b831b08 100644 --- a/crates/air/src/layout/dex/mod.rs +++ b/crates/air/src/layout/dex/mod.rs @@ -353,7 +353,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -405,10 +407,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/dynamic/mod.rs b/crates/air/src/layout/dynamic/mod.rs index 91eaad5..cab12a5 100644 --- a/crates/air/src/layout/dynamic/mod.rs +++ b/crates/air/src/layout/dynamic/mod.rs @@ -726,7 +726,9 @@ impl LayoutTrait for Layout { Ok(autogenerated::check_asserts(&dynamic_params, stark_domains)?) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -778,10 +780,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &felt!(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &felt!(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/mod.rs b/crates/air/src/layout/mod.rs index 757ca34..2cf85df 100644 --- a/crates/air/src/layout/mod.rs +++ b/crates/air/src/layout/mod.rs @@ -1,4 +1,5 @@ use crate::{domains::StarkDomains, public_memory::PublicInput}; +use alloc::vec::Vec; use num_bigint::{BigInt, TryFromBigIntError}; use starknet_core::types::NonZeroFelt; use starknet_crypto::Felt; @@ -84,7 +85,9 @@ pub trait LayoutTrait { witness: crate::trace::Witness, ) -> Result<(), crate::trace::decommit::Error>; - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError>; + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError>; } pub trait StaticLayoutTrait { diff --git a/crates/air/src/layout/recursive/mod.rs b/crates/air/src/layout/recursive/mod.rs index bfb7e55..e4999f8 100644 --- a/crates/air/src/layout/recursive/mod.rs +++ b/crates/air/src/layout/recursive/mod.rs @@ -353,7 +353,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -405,10 +407,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/recursive_with_poseidon/mod.rs b/crates/air/src/layout/recursive_with_poseidon/mod.rs index c948227..216dfa6 100644 --- a/crates/air/src/layout/recursive_with_poseidon/mod.rs +++ b/crates/air/src/layout/recursive_with_poseidon/mod.rs @@ -410,7 +410,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -462,10 +464,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/small/mod.rs b/crates/air/src/layout/small/mod.rs index 99952cb..bf1a9c3 100644 --- a/crates/air/src/layout/small/mod.rs +++ b/crates/air/src/layout/small/mod.rs @@ -353,7 +353,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -405,10 +407,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/starknet/mod.rs b/crates/air/src/layout/starknet/mod.rs index bf239e1..4f62e72 100644 --- a/crates/air/src/layout/starknet/mod.rs +++ b/crates/air/src/layout/starknet/mod.rs @@ -480,7 +480,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -532,10 +534,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into()?; - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/air/src/layout/starknet_with_keccak/mod.rs b/crates/air/src/layout/starknet_with_keccak/mod.rs index 5c91c87..d487b41 100644 --- a/crates/air/src/layout/starknet_with_keccak/mod.rs +++ b/crates/air/src/layout/starknet_with_keccak/mod.rs @@ -529,7 +529,9 @@ impl LayoutTrait for Layout { Ok(()) } - fn verify_public_input(public_input: &PublicInput) -> Result<(Felt, Felt), PublicInputError> { + fn verify_public_input( + public_input: &PublicInput, + ) -> Result<(Felt, Vec), PublicInputError> { let public_segments = &public_input.segments; let initial_pc = public_segments @@ -581,10 +583,9 @@ impl LayoutTrait for Layout { let program_hash = pedersen_hash(&hash, &Felt::from(program.len())); let output_len: usize = (output_stop - output_start).to_bigint().try_into().unwrap(); - let output = &memory[memory.len() - output_len * 2..]; - let hash = output.iter().skip(1).step_by(2).fold(FELT_0, |acc, e| pedersen_hash(&acc, e)); - let output_hash = pedersen_hash(&hash, &Felt::from(output_len)); + let output = + memory[memory.len() - output_len * 2..].iter().skip(1).step_by(2).cloned().collect(); - Ok((program_hash, output_hash)) + Ok((program_hash, output)) } } diff --git a/crates/stark/src/stark.rs b/crates/stark/src/stark.rs index 52d7dd4..fe4b8df 100644 --- a/crates/stark/src/stark.rs +++ b/crates/stark/src/stark.rs @@ -1,6 +1,7 @@ use crate::{ commit::stark_commit, queries::generate_queries, types::StarkProof, verify::stark_verify, }; +use alloc::vec::Vec; use starknet_crypto::Felt; use swiftness_air::{ domains::StarkDomains, @@ -12,7 +13,7 @@ impl StarkProof { pub fn verify( &self, security_bits: Felt, - ) -> Result<(Felt, Felt), Error> { + ) -> Result<(Felt, Vec), Error> { let n_original_columns = Layout::get_num_columns_first(&self.public_input).ok_or(Error::ColumnMissing)?; let n_interaction_columns =