diff --git a/Cargo.toml b/Cargo.toml index 44505284b..e3aa0c131 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,12 +13,12 @@ cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo/", rev = "447 cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo/", rev = "4471a55923663eb8150ea6cd636d5c1038b137d1"} cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo/", rev = "4471a55923663eb8150ea6cd636d5c1038b137d1"} cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo/", rev = "4471a55923663eb8150ea6cd636d5c1038b137d1"} -cairo-proof-parser = { git = "https://github.com/Okm165/cairo-proof-parser", rev = "97a04bbee07330311b38d6f4cecfed3acb237626"} -cairo-vm = "0.9.2" +cairo-vm = "1.0.1" clap = { version = "4.5.2", features = ["derive"] } itertools = "0.13.0" num-bigint = "0.4.4" runner = { path = "runner" } serde = { version = "1", features = ["derive"] } serde_json = "1" +swiftness_proof_parser = { git = "https://github.com/iosis-tech/swiftness", rev = "a53d65ecbd7acf4611b0d587d815f4e9d4d493ed"} thiserror = "1.0" \ No newline at end of file diff --git a/examples/starknet/Cargo.toml b/examples/starknet/Cargo.toml index 7790022f1..dd0a6f7d8 100644 --- a/examples/starknet/Cargo.toml +++ b/examples/starknet/Cargo.toml @@ -7,9 +7,9 @@ edition = "2021" [dependencies] anyhow.workspace = true -cairo-proof-parser.workspace = true clap.workspace = true itertools.workspace = true runner.workspace = true serde_json.workspace = true -serde.workspace = true \ No newline at end of file +serde.workspace = true +swiftness_proof_parser.workspace = true \ No newline at end of file diff --git a/examples/starknet/src/main.rs b/examples/starknet/src/main.rs index 21febedc8..019221106 100644 --- a/examples/starknet/src/main.rs +++ b/examples/starknet/src/main.rs @@ -1,8 +1,8 @@ -use cairo_proof_parser::parse; use clap::Parser; use itertools::chain; -use runner::{CairoVersion, VecFelt252}; +use runner::{transform::StarkProofExprs, CairoVersion, VecFelt252}; use std::io::{stdin, Read}; +use swiftness_proof_parser::parse; #[derive(Parser)] #[command(author, version, about)] @@ -17,13 +17,13 @@ fn main() -> anyhow::Result<()> { let mut input = String::new(); stdin().read_to_string(&mut input)?; - let parsed = parse(input)?; - - let config: VecFelt252 = serde_json::from_str(&parsed.config.to_string()).unwrap(); - let public_input: VecFelt252 = serde_json::from_str(&parsed.public_input.to_string()).unwrap(); + let stark_proof: StarkProofExprs = parse(input)?.into(); + let config: VecFelt252 = serde_json::from_str(&stark_proof.config.to_string()).unwrap(); + let public_input: VecFelt252 = + serde_json::from_str(&stark_proof.public_input.to_string()).unwrap(); let unsent_commitment: VecFelt252 = - serde_json::from_str(&parsed.unsent_commitment.to_string()).unwrap(); - let witness: VecFelt252 = serde_json::from_str(&parsed.witness.to_string()).unwrap(); + serde_json::from_str(&stark_proof.unsent_commitment.to_string()).unwrap(); + let witness: VecFelt252 = serde_json::from_str(&stark_proof.witness.to_string()).unwrap(); let proof = chain!( config.into_iter(), @@ -32,9 +32,7 @@ fn main() -> anyhow::Result<()> { witness.into_iter() ); - let calldata = chain!(proof, vec![cli.cairo_version.into()].into_iter()); - - let calldata_string = calldata + let calldata_string = chain!(proof, vec![cli.cairo_version.into()].into_iter()) .map(|f| f.to_string()) .collect::>() .join(" "); diff --git a/runner/Cargo.toml b/runner/Cargo.toml index 7abb8a725..083db7100 100644 --- a/runner/Cargo.toml +++ b/runner/Cargo.toml @@ -12,11 +12,11 @@ cairo-lang-casm.workspace = true cairo-lang-runner.workspace = true cairo-lang-sierra.workspace = true cairo-lang-utils.workspace = true -cairo-proof-parser.workspace = true cairo-vm.workspace = true clap.workspace = true itertools.workspace = true num-bigint.workspace = true serde_json.workspace = true serde.workspace = true +swiftness_proof_parser.workspace = true thiserror.workspace = true \ No newline at end of file diff --git a/runner/src/lib.rs b/runner/src/lib.rs index 9c786dc84..7abca839a 100644 --- a/runner/src/lib.rs +++ b/runner/src/lib.rs @@ -1,4 +1,6 @@ +pub mod transform; pub mod vec252; + use cairo_felt::Felt252; use clap::ValueEnum; pub use vec252::VecFelt252; diff --git a/runner/src/main.rs b/runner/src/main.rs index 138e0ae75..d0f0a7d2b 100644 --- a/runner/src/main.rs +++ b/runner/src/main.rs @@ -1,10 +1,10 @@ +mod transform; mod vec252; -use crate::vec252::VecFelt252; +use crate::vec252::VecFelt252; use cairo_lang_runner::{Arg, ProfilingInfoCollectionConfig, RunResultValue, SierraCasmRunner}; use cairo_lang_sierra::program::VersionedProgram; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; -use cairo_proof_parser::parse; use clap::Parser; use itertools::{chain, Itertools}; use runner::CairoVersion; @@ -12,6 +12,10 @@ use std::{ fs, io::{stdin, Read}, }; +use swiftness_proof_parser::parse; +use transform::StarkProofExprs; + +const ENTRYPOINT: &str = "main"; #[derive(Parser)] #[command(author, version, about)] @@ -28,15 +32,14 @@ fn main() -> anyhow::Result<()> { let cli = Cli::parse(); let mut input = String::new(); stdin().read_to_string(&mut input)?; - let parsed = parse(input)?; - - let function = "main"; - let config: VecFelt252 = serde_json::from_str(&parsed.config.to_string()).unwrap(); - let public_input: VecFelt252 = serde_json::from_str(&parsed.public_input.to_string()).unwrap(); + let stark_proof: StarkProofExprs = parse(input)?.into(); + let config: VecFelt252 = serde_json::from_str(&stark_proof.config.to_string()).unwrap(); + let public_input: VecFelt252 = + serde_json::from_str(&stark_proof.public_input.to_string()).unwrap(); let unsent_commitment: VecFelt252 = - serde_json::from_str(&parsed.unsent_commitment.to_string()).unwrap(); - let witness: VecFelt252 = serde_json::from_str(&parsed.witness.to_string()).unwrap(); + serde_json::from_str(&stark_proof.unsent_commitment.to_string()).unwrap(); + let witness: VecFelt252 = serde_json::from_str(&stark_proof.witness.to_string()).unwrap(); let proof = chain!( config.into_iter(), @@ -59,16 +62,14 @@ fn main() -> anyhow::Result<()> { ) .unwrap(); - let func = runner.find_function(function).unwrap(); - let proof_arg = Arg::Array(proof.into_iter().map(Arg::Value).collect_vec()); - let cairo_version_arg = Arg::Value(cli.cairo_version.into()); - let args = &[proof_arg, cairo_version_arg]; + let func = runner.find_function(ENTRYPOINT).unwrap(); + let args = &[ + Arg::Array(proof.into_iter().map(Arg::Value).collect_vec()), + Arg::Value(cli.cairo_version.into()), + ]; let result = runner .run_function_with_starknet_context(func, args, Some(u32::MAX as usize), Default::default()) .unwrap(); - // let profiling_processor = - // ProfilingInfoProcessor::new(None, sierra_program.program, UnorderedHashMap::default()); - // let processed_profiling_info = profiling_processor.process(&result.profiling_info.unwrap()); println!("gas_counter: {}", result.gas_counter.unwrap()); println!("n_steps: {}", result.memory.len()); diff --git a/runner/src/transform.rs b/runner/src/transform.rs new file mode 100644 index 000000000..0fa063b39 --- /dev/null +++ b/runner/src/transform.rs @@ -0,0 +1,400 @@ +use num_bigint::BigUint; +use swiftness_proof_parser::*; + +pub trait IntoAst { + fn into_ast(self) -> Vec; +} + +impl IntoAst for u32 { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{self}"))] + } +} + +impl IntoAst for usize { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{self}"))] + } +} + +impl IntoAst for BigUint { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{self}"))] + } +} + +impl IntoAst for &BigUint { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{self}"))] + } +} + +impl IntoAst for StarkProof { + fn into_ast(self) -> Vec { + [ + self.config.into_ast(), + self.public_input.into_ast(), + self.unsent_commitment.into_ast(), + self.witness.into_ast(), + ] + .concat() + } +} + +impl IntoAst for StarkConfig { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.traces.into_ast()); + exprs.append(&mut self.composition.into_ast()); + exprs.append(&mut self.fri.into_ast()); + exprs.append(&mut self.proof_of_work.into_ast()); + exprs.append(&mut self.log_trace_domain_size.into_ast()); + exprs.append(&mut self.n_queries.into_ast()); + exprs.append(&mut self.log_n_cosets.into_ast()); + exprs.append(&mut self.n_verifier_friendly_commitment_layers.into_ast()); + exprs + } +} + +impl IntoAst for TracesConfig { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.original.into_ast()); + exprs.append(&mut self.interaction.into_ast()); + exprs + } +} + +impl IntoAst for TableCommitmentConfig { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.n_columns.into_ast()); + exprs.append(&mut self.vector.into_ast()); + exprs + } +} + +impl IntoAst for VectorCommitmentConfig { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.height.into_ast()); + exprs.append(&mut self.n_verifier_friendly_commitment_layers.into_ast()); + exprs + } +} + +impl IntoAst for FriConfig { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.log_input_size.into_ast()); + exprs.append(&mut self.n_layers.into_ast()); + exprs.append(&mut self.inner_layers.into_ast()); + exprs.append(&mut self.fri_step_sizes.into_ast()); + exprs.append(&mut self.log_last_layer_degree_bound.into_ast()); + exprs + } +} + +impl IntoAst for StarkUnsentCommitment { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.traces.into_ast()); + exprs.append(&mut self.composition.into_ast()); + exprs.append(&mut self.oods_values.into_ast()); + exprs.append(&mut self.fri.into_ast()); + exprs.append(&mut self.proof_of_work.into_ast()); + exprs + } +} + +impl IntoAst for TracesUnsentCommitment { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.original.into_ast()); + exprs.append(&mut self.interaction.into_ast()); + exprs + } +} + +impl IntoAst for FriUnsentCommitment { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.inner_layers.into_ast()); + exprs.append(&mut self.last_layer_coefficients.into_ast()); + exprs + } +} + +impl IntoAst for ProofOfWorkUnsentCommitment { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{}", self.nonce))] + } +} + +impl IntoAst for ProofOfWorkConfig { + fn into_ast(self) -> Vec { + vec![Expr::Value(format!("{}", self.n_bits))] + } +} + +impl IntoAst for StarkWitness { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.traces_decommitment.into_ast()); + exprs.append(&mut self.traces_witness.into_ast()); + exprs.append(&mut self.composition_decommitment.into_ast()); + exprs.append(&mut self.composition_witness.into_ast()); + exprs.append(&mut self.fri_witness.into_ast()); + exprs + } +} + +impl IntoAst for TracesDecommitment { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.original.into_ast()); + exprs.append(&mut self.interaction.into_ast()); + exprs + } +} + +impl IntoAst for TableDecommitment { + fn into_ast(self) -> Vec { + let mut exprs = vec![Expr::Value(format!("{}", self.n_values))]; + exprs.append(&mut self.values.into_ast()); + exprs + } +} + +impl IntoAst for TracesWitness { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.original.into_ast()); + exprs.append(&mut self.interaction.into_ast()); + exprs + } +} + +impl IntoAst for TableCommitmentWitness { + fn into_ast(self) -> Vec { + self.vector.into_ast() + } +} + +impl IntoAst for TableCommitmentWitnessFlat { + fn into_ast(self) -> Vec { + self.vector.into_ast() + } +} + +impl IntoAst for VectorCommitmentWitness { + fn into_ast(self) -> Vec { + let mut exprs = vec![Expr::Value(format!("{}", self.n_authentications))]; + exprs.append(&mut self.authentications.into_ast()); + exprs + } +} + +impl IntoAst for VectorCommitmentWitnessFlat { + fn into_ast(self) -> Vec { + let mut exprs = vec![Expr::Value(format!("{}", self.n_authentications))]; + exprs.append( + &mut self + .authentications + .iter() + .flat_map(|x| x.into_ast()) + .collect::>(), + ); + exprs + } +} + +impl IntoAst for FriWitness { + fn into_ast(self) -> Vec { + self.layers.into_ast() + } +} + +impl IntoAst for FriLayerWitness { + fn into_ast(self) -> Vec { + let mut exprs = vec![Expr::Value(format!("{}", self.n_leaves))]; + exprs.append( + &mut self + .leaves + .iter() + .flat_map(|x| x.into_ast()) + .collect::>(), + ); + exprs.append(&mut self.table_witness.into_ast()); + exprs + } +} + +impl IntoAst for PublicInput { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.log_n_steps.into_ast()); + exprs.append(&mut self.range_check_min.into_ast()); + exprs.append(&mut self.range_check_max.into_ast()); + exprs.append(&mut self.layout.into_ast()); + exprs.push(Expr::Array( + self.dynamic_params + .values() + .map(|v| Expr::Value(format!("{v}"))) + .collect(), + )); + exprs.append(&mut self.n_segments.into_ast()); + exprs.append(&mut self.segments.into_ast()); + exprs.append(&mut self.padding_addr.into_ast()); + exprs.append(&mut self.padding_value.into_ast()); + exprs.append(&mut self.main_page_len.into_ast()); + exprs.append(&mut self.main_page.into_ast()); + exprs.append(&mut self.n_continuous_pages.into_ast()); + exprs.append(&mut self.continuous_page_headers.into_ast()); + exprs + } +} + +impl IntoAst for SegmentInfo { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.begin_addr.into_ast()); + exprs.append(&mut self.stop_ptr.into_ast()); + exprs + } +} + +impl IntoAst for PubilcMemoryCell { + fn into_ast(self) -> Vec { + let mut exprs = vec![]; + exprs.append(&mut self.address.into_ast()); + exprs.append(&mut self.value.into_ast()); + exprs + } +} + +impl IntoAst for Vec +where + T: IntoAst, +{ + fn into_ast(self) -> Vec { + vec![Expr::Array( + self.into_iter().flat_map(|x| x.into_ast()).collect(), + )] + } +} + +impl From for Exprs { + fn from(v: StarkConfig) -> Self { + Exprs(v.into_ast()) + } +} + +impl From for Exprs { + fn from(v: PublicInput) -> Self { + Exprs(v.into_ast()) + } +} + +impl From for Exprs { + fn from(v: StarkUnsentCommitment) -> Self { + Exprs(v.into_ast()) + } +} + +impl From for Exprs { + fn from(v: StarkWitness) -> Self { + Exprs(v.into_ast()) + } +} + +impl From for Exprs { + fn from(proof: StarkProof) -> Self { + Exprs(proof.into_ast()) + } +} + +use std::{ + fmt::Display, + ops::{Deref, DerefMut}, +}; + +#[derive(Debug, Clone)] +pub enum Expr { + Value(String), + Array(Vec), +} + +impl Display for Expr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Expr::Value(v) => write!(f, "\"{v}\""), + Expr::Array(v) => { + write!(f, "[")?; + + for (i, expr) in v.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{expr}")?; + } + + write!(f, "]")?; + + Ok(()) + } + } + } +} + +#[derive(Debug, Clone)] +pub struct Exprs(pub Vec); + +impl Display for Exprs { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "[")?; + + for (i, expr) in self.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{expr}")?; + } + + write!(f, "]")?; + + Ok(()) + } +} + +impl Deref for Exprs { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Exprs { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub struct StarkProofExprs { + pub config: Exprs, + pub public_input: Exprs, + pub unsent_commitment: Exprs, + pub witness: Exprs, +} + +impl From for StarkProofExprs { + fn from(value: StarkProof) -> Self { + Self { + config: Exprs::from(value.config), + public_input: Exprs::from(value.public_input), + unsent_commitment: Exprs::from(value.unsent_commitment), + witness: Exprs::from(value.witness), + } + } +} diff --git a/runner/src/vec252.rs b/runner/src/vec252.rs index 0321a251d..b6e69540c 100644 --- a/runner/src/vec252.rs +++ b/runner/src/vec252.rs @@ -1,8 +1,7 @@ -use std::{ops::Deref, str::FromStr}; - use cairo_felt::Felt252; use serde::{de::Visitor, Deserialize}; use serde_json::Value; +use std::{ops::Deref, str::FromStr}; use thiserror::Error; #[derive(Error, Debug)] diff --git a/src/air/layouts/dex/public_input.cairo b/src/air/layouts/dex/public_input.cairo index 616ab8437..772fe53e9 100644 --- a/src/air/layouts/dex/public_input.cairo +++ b/src/air/layouts/dex/public_input.cairo @@ -97,7 +97,7 @@ impl DexPublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/layouts/recursive/public_input.cairo b/src/air/layouts/recursive/public_input.cairo index ab73b9456..5a997cf31 100644 --- a/src/air/layouts/recursive/public_input.cairo +++ b/src/air/layouts/recursive/public_input.cairo @@ -97,7 +97,7 @@ impl RecursivePublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/layouts/recursive_with_poseidon/public_input.cairo b/src/air/layouts/recursive_with_poseidon/public_input.cairo index 7f53bfa84..b33b8879a 100644 --- a/src/air/layouts/recursive_with_poseidon/public_input.cairo +++ b/src/air/layouts/recursive_with_poseidon/public_input.cairo @@ -98,7 +98,7 @@ impl RecursiveWithPoseidonPublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/layouts/small/public_input.cairo b/src/air/layouts/small/public_input.cairo index 06dba89e7..677536c87 100644 --- a/src/air/layouts/small/public_input.cairo +++ b/src/air/layouts/small/public_input.cairo @@ -97,7 +97,7 @@ impl SmallPublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/layouts/starknet/public_input.cairo b/src/air/layouts/starknet/public_input.cairo index edfb424ec..a82997643 100644 --- a/src/air/layouts/starknet/public_input.cairo +++ b/src/air/layouts/starknet/public_input.cairo @@ -98,7 +98,7 @@ impl StarknetPublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/layouts/starknet_with_keccak/public_input.cairo b/src/air/layouts/starknet_with_keccak/public_input.cairo index 9b477ddeb..0a730575e 100644 --- a/src/air/layouts/starknet_with_keccak/public_input.cairo +++ b/src/air/layouts/starknet_with_keccak/public_input.cairo @@ -98,7 +98,7 @@ impl StarknetWithKeccakPublicInputImpl of PublicInputTrait { ref memory_index ); - // 3. Output segment + // 3. Output segment let output_len = output_stop - output_start; let output = memory .extract_range( diff --git a/src/air/public_input.cairo b/src/air/public_input.cairo index dba5f5c7c..a405b0c68 100644 --- a/src/air/public_input.cairo +++ b/src/air/public_input.cairo @@ -163,16 +163,18 @@ fn verify_cairo1_public_input(public_input: @PublicInput) -> (felt252, felt252) assert(initial_ap < MAX_ADDRESS, 'Invalid initial_ap'); assert(final_ap < MAX_ADDRESS, 'Invalid final_ap'); + + // TODO support continuous memory pages assert(public_input.continuous_page_headers.len() == 0, 'Invalid continuous_page_headers'); + let memory = public_input.main_page; // 1. Program segment assert(initial_pc == INITIAL_PC, 'Invalid initial_pc'); - let program = memory - .extract_range_unchecked(initial_pc.try_into().unwrap(), memory.len() - output_len); + let program = memory.extract_range_unchecked(0, memory.len() - output_len); let program_hash = poseidon_hash_span(program); - // 2. Output segment + // 2. Output segment let output = memory.extract_range_unchecked(memory.len() - output_len, output_len); let output_hash = poseidon_hash_span(output); (program_hash, output_hash) @@ -194,4 +196,3 @@ mod tests { ) } } -// === RECURSIVE END === diff --git a/src/air/public_memory.cairo b/src/air/public_memory.cairo index af58c1e28..55f3a2427 100644 --- a/src/air/public_memory.cairo +++ b/src/air/public_memory.cairo @@ -56,7 +56,7 @@ impl PageImpl of PageTrait { let current = *self.at(offset); - // TODO is this needed? If not we can just use slice directly + // TODO is this needed? If not we can just use slice directly assert(current.address == (addr + i).into(), 'Invalid address'); arr.append(current.value); i += 1; diff --git a/src/common/blake2s.cairo b/src/common/blake2s.cairo index d4174f236..063e40f09 100644 --- a/src/common/blake2s.cairo +++ b/src/common/blake2s.cairo @@ -18,52 +18,28 @@ fn truncated_blake2s(data: Array) -> felt252 { // internals: -fn load32(p0: u8, p1: u8, p2: u8, p3: u8) -> u32 { - let mut x: u32 = p3.into(); - x = x * 256 + p2.into(); - x = x * 256 + p1.into(); - x = x * 256 + p0.into(); - x -} - -fn get_sigma(r: u32) -> Array { - if r == 0 { - array![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] - } else if r == 1 { - array![14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3] - } else if r == 2 { - array![11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4] - } else if r == 3 { - array![7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8] - } else if r == 4 { - array![9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13] - } else if r == 5 { - array![2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9] - } else if r == 6 { - array![12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11] - } else if r == 7 { - array![13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10] - } else if r == 8 { - array![6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5] - } else { // r == 9 - array![10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0] - } -} - +#[inline(always)] fn rotr16(n: u32) -> u32 { - n / 65536 + (n % 65536) * 65536 + let (high, low) = DivRem::div_rem(n, 65536); + TryInto::::try_into(high.into() + low.into() * 65536).unwrap() } +#[inline(always)] fn rotr12(n: u32) -> u32 { - n / 4096 + (n % 4096) * 1048576 + let (high, low) = DivRem::div_rem(n, 4096); + TryInto::::try_into(high.into() + low.into() * 1048576).unwrap() } +#[inline(always)] fn rotr8(n: u32) -> u32 { - n / 256 + (n % 256) * 16777216 + let (high, low) = DivRem::div_rem(n, 256); + TryInto::::try_into(high.into() + low.into() * 16777216).unwrap() } +#[inline(always)] fn rotr7(n: u32) -> u32 { - n / 128 + (n % 128) * 33554432 + let (high, low) = DivRem::div_rem(n, 128); + TryInto::::try_into(high.into() + low.into() * 33554432).unwrap() } #[derive(Drop, Clone)] @@ -113,98 +89,256 @@ fn blake2s_compress(mut s: blake2s_state, m: Array) -> blake2s_state { let mut v15: u32 = 0x5BE0CD19; // f1 is always 0 let m_span = m.span(); + let mut sigma = array![ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 10, + 4, + 8, + 9, + 15, + 13, + 6, + 1, + 12, + 0, + 2, + 11, + 7, + 5, + 3, + 11, + 8, + 12, + 0, + 5, + 2, + 15, + 13, + 10, + 14, + 3, + 6, + 7, + 1, + 9, + 4, + 7, + 9, + 3, + 1, + 13, + 12, + 11, + 14, + 2, + 6, + 5, + 10, + 4, + 0, + 15, + 8, + 9, + 0, + 5, + 7, + 2, + 4, + 10, + 15, + 14, + 1, + 11, + 12, + 6, + 8, + 3, + 13, + 2, + 12, + 6, + 10, + 0, + 11, + 8, + 3, + 4, + 13, + 7, + 5, + 15, + 14, + 1, + 9, + 12, + 5, + 1, + 15, + 14, + 13, + 4, + 10, + 0, + 7, + 6, + 3, + 9, + 2, + 8, + 11, + 13, + 11, + 7, + 14, + 12, + 1, + 3, + 9, + 5, + 0, + 15, + 4, + 8, + 6, + 2, + 10, + 6, + 15, + 14, + 9, + 11, + 3, + 0, + 8, + 12, + 2, + 13, + 7, + 1, + 4, + 10, + 5, + 10, + 2, + 8, + 4, + 7, + 6, + 1, + 5, + 15, + 11, + 9, + 14, + 3, + 12, + 13, + 0, + ] + .span(); - let mut r = 0; loop { - if r == 10 { + if sigma.is_empty() { break; } - let sigma = get_sigma(r); - // ROUND function begin // 0 - 0,4,8,12 - v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[0])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr16(v12 ^ v0); v8 = u32_wrapping_add(v8, v12); v4 = rotr12(v4 ^ v8); - v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[1])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr8(v12 ^ v0); v8 = u32_wrapping_add(v8, v12); v4 = rotr7(v4 ^ v8); // 1 - 1,5,9,13 - v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[2])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr16(v13 ^ v1); v9 = u32_wrapping_add(v9, v13); v5 = rotr12(v5 ^ v9); - v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[3])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr8(v13 ^ v1); v9 = u32_wrapping_add(v9, v13); v5 = rotr7(v5 ^ v9); // 2 - 2,6,10,14 - v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[4])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr16(v14 ^ v2); v10 = u32_wrapping_add(v10, v14); v6 = rotr12(v6 ^ v10); - v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[5])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr8(v14 ^ v2); v10 = u32_wrapping_add(v10, v14); v6 = rotr7(v6 ^ v10); // 3 - 3,7,11,15 - v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[6])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr16(v15 ^ v3); v11 = u32_wrapping_add(v11, v15); v7 = rotr12(v7 ^ v11); - v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[7])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr8(v15 ^ v3); v11 = u32_wrapping_add(v11, v15); v7 = rotr7(v7 ^ v11); // 4 - 0,5,10,15 - v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[8])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr16(v15 ^ v0); v10 = u32_wrapping_add(v10, v15); v5 = rotr12(v5 ^ v10); - v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[9])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr8(v15 ^ v0); v10 = u32_wrapping_add(v10, v15); v5 = rotr7(v5 ^ v10); // 5 - 1,6,11,12 - v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[10])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr16(v12 ^ v1); v11 = u32_wrapping_add(v11, v12); v6 = rotr12(v6 ^ v11); - v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[11])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr8(v12 ^ v1); v11 = u32_wrapping_add(v11, v12); v6 = rotr7(v6 ^ v11); // 6 - 2,7,8,13 - v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[12])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr16(v13 ^ v2); v8 = u32_wrapping_add(v8, v13); v7 = rotr12(v7 ^ v8); - v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[13])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr8(v13 ^ v2); v8 = u32_wrapping_add(v8, v13); v7 = rotr7(v7 ^ v8); // 7 - 3,4,9,14 - v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[14])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr16(v14 ^ v3); v9 = u32_wrapping_add(v9, v14); v4 = rotr12(v4 ^ v9); - v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[15])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr8(v14 ^ v3); v9 = u32_wrapping_add(v9, v14); v4 = rotr7(v4 ^ v9); - - r += 1; }; let mut new_h = ArrayTrait::new(); @@ -324,7 +458,7 @@ fn blake2s_update(mut s: blake2s_state, in: Array) -> blake2s_state { fn blake2s_final(mut s: blake2s_state) -> u256 { assert(s.f0 == 0, 'blake2s_is_lastblock'); - // blake2s_increment_counter + // blake2s_increment_counter s.t0 = u32_wrapping_add(s.t0, s.buflen * 4); if s.t0 < s.buflen { s.t1 = u32_wrapping_add(s.t1, 1); diff --git a/src/common/blake2s_u8.cairo b/src/common/blake2s_u8.cairo index 71be4cf98..57fb8c31d 100644 --- a/src/common/blake2s_u8.cairo +++ b/src/common/blake2s_u8.cairo @@ -20,53 +20,34 @@ fn truncated_blake2s(data: Array) -> felt252 { // internals: fn load32(p0: u8, p1: u8, p2: u8, p3: u8) -> u32 { - let mut x: u32 = p3.into(); + let mut x: felt252 = p3.into(); x = x * 256 + p2.into(); x = x * 256 + p1.into(); x = x * 256 + p0.into(); - x -} - -fn get_sigma(r: u32) -> Array { - if r == 0 { - array![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] - } else if r == 1 { - array![14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3] - } else if r == 2 { - array![11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4] - } else if r == 3 { - array![7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8] - } else if r == 4 { - array![9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13] - } else if r == 5 { - array![2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9] - } else if r == 6 { - array![12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11] - } else if r == 7 { - array![13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10] - } else if r == 8 { - array![6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5] - } else { // r == 9 - array![10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0] - } + x.try_into().unwrap() } fn rotr16(n: u32) -> u32 { - n / 65536 + (n % 65536) * 65536 + let (high, low) = DivRem::div_rem(n, 65536); + TryInto::::try_into(high.into() + low.into() * 65536).unwrap() } fn rotr12(n: u32) -> u32 { - n / 4096 + (n % 4096) * 1048576 + let (high, low) = DivRem::div_rem(n, 4096); + TryInto::::try_into(high.into() + low.into() * 1048576).unwrap() } fn rotr8(n: u32) -> u32 { - n / 256 + (n % 256) * 16777216 + let (high, low) = DivRem::div_rem(n, 256); + TryInto::::try_into(high.into() + low.into() * 16777216).unwrap() } fn rotr7(n: u32) -> u32 { - n / 128 + (n % 128) * 33554432 + let (high, low) = DivRem::div_rem(n, 128); + TryInto::::try_into(high.into() + low.into() * 33554432).unwrap() } + #[derive(Drop, Clone)] struct blake2s_state { h: Array, // length: 8 @@ -125,100 +106,257 @@ fn blake2s_compress(mut s: blake2s_state, in: Array) -> blake2s_state { let mut v15: u32 = 0x5BE0CD19; // f1 is always 0 let m_span = m.span(); + let mut sigma = array![ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 10, + 4, + 8, + 9, + 15, + 13, + 6, + 1, + 12, + 0, + 2, + 11, + 7, + 5, + 3, + 11, + 8, + 12, + 0, + 5, + 2, + 15, + 13, + 10, + 14, + 3, + 6, + 7, + 1, + 9, + 4, + 7, + 9, + 3, + 1, + 13, + 12, + 11, + 14, + 2, + 6, + 5, + 10, + 4, + 0, + 15, + 8, + 9, + 0, + 5, + 7, + 2, + 4, + 10, + 15, + 14, + 1, + 11, + 12, + 6, + 8, + 3, + 13, + 2, + 12, + 6, + 10, + 0, + 11, + 8, + 3, + 4, + 13, + 7, + 5, + 15, + 14, + 1, + 9, + 12, + 5, + 1, + 15, + 14, + 13, + 4, + 10, + 0, + 7, + 6, + 3, + 9, + 2, + 8, + 11, + 13, + 11, + 7, + 14, + 12, + 1, + 3, + 9, + 5, + 0, + 15, + 4, + 8, + 6, + 2, + 10, + 6, + 15, + 14, + 9, + 11, + 3, + 0, + 8, + 12, + 2, + 13, + 7, + 1, + 4, + 10, + 5, + 10, + 2, + 8, + 4, + 7, + 6, + 1, + 5, + 15, + 11, + 9, + 14, + 3, + 12, + 13, + 0, + ] + .span(); - let mut r = 0; loop { - if r == 10 { + if sigma.is_empty() { break; } - let sigma = get_sigma(r); - // ROUND function begin // 0 - 0,4,8,12 - v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[0])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr16(v12 ^ v0); v8 = u32_wrapping_add(v8, v12); v4 = rotr12(v4 ^ v8); - v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma[1])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v4), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr8(v12 ^ v0); v8 = u32_wrapping_add(v8, v12); v4 = rotr7(v4 ^ v8); // 1 - 1,5,9,13 - v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[2])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr16(v13 ^ v1); v9 = u32_wrapping_add(v9, v13); v5 = rotr12(v5 ^ v9); - v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma[3])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v5), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr8(v13 ^ v1); v9 = u32_wrapping_add(v9, v13); v5 = rotr7(v5 ^ v9); // 2 - 2,6,10,14 - v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[4])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr16(v14 ^ v2); v10 = u32_wrapping_add(v10, v14); v6 = rotr12(v6 ^ v10); - v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma[5])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v6), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr8(v14 ^ v2); v10 = u32_wrapping_add(v10, v14); v6 = rotr7(v6 ^ v10); // 3 - 3,7,11,15 - v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[6])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr16(v15 ^ v3); v11 = u32_wrapping_add(v11, v15); v7 = rotr12(v7 ^ v11); - v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma[7])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v7), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr8(v15 ^ v3); v11 = u32_wrapping_add(v11, v15); v7 = rotr7(v7 ^ v11); // 4 - 0,5,10,15 - v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[8])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr16(v15 ^ v0); v10 = u32_wrapping_add(v10, v15); v5 = rotr12(v5 ^ v10); - v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma[9])); + v0 = u32_wrapping_add(u32_wrapping_add(v0, v5), *m_span.at(*sigma.pop_front().unwrap())); v15 = rotr8(v15 ^ v0); v10 = u32_wrapping_add(v10, v15); v5 = rotr7(v5 ^ v10); // 5 - 1,6,11,12 - v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[10])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr16(v12 ^ v1); v11 = u32_wrapping_add(v11, v12); v6 = rotr12(v6 ^ v11); - v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma[11])); + v1 = u32_wrapping_add(u32_wrapping_add(v1, v6), *m_span.at(*sigma.pop_front().unwrap())); v12 = rotr8(v12 ^ v1); v11 = u32_wrapping_add(v11, v12); v6 = rotr7(v6 ^ v11); // 6 - 2,7,8,13 - v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[12])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr16(v13 ^ v2); v8 = u32_wrapping_add(v8, v13); v7 = rotr12(v7 ^ v8); - v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma[13])); + v2 = u32_wrapping_add(u32_wrapping_add(v2, v7), *m_span.at(*sigma.pop_front().unwrap())); v13 = rotr8(v13 ^ v2); v8 = u32_wrapping_add(v8, v13); v7 = rotr7(v7 ^ v8); // 7 - 3,4,9,14 - v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[14])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr16(v14 ^ v3); v9 = u32_wrapping_add(v9, v14); v4 = rotr12(v4 ^ v9); - v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma[15])); + v3 = u32_wrapping_add(u32_wrapping_add(v3, v4), *m_span.at(*sigma.pop_front().unwrap())); v14 = rotr8(v14 ^ v3); v9 = u32_wrapping_add(v9, v14); v4 = rotr7(v4 ^ v9); - - // ROUND function end - - r += 1; + // ROUND function end }; let mut new_h = ArrayTrait::new(); @@ -338,7 +476,7 @@ fn blake2s_update(mut s: blake2s_state, in: Array) -> blake2s_state { fn blake2s_final(mut s: blake2s_state) -> u256 { assert(s.f0 == 0, 'blake2s_is_lastblock'); - // blake2s_increment_counter + // blake2s_increment_counter s.t0 = u32_wrapping_add(s.t0, s.buflen); if s.t0 < s.buflen { s.t1 = u32_wrapping_add(s.t1, 1); diff --git a/src/common/tests/test_blake2s.cairo b/src/common/tests/test_blake2s.cairo index 84f51f4ab..18f9cbac6 100644 --- a/src/common/tests/test_blake2s.cairo +++ b/src/common/tests/test_blake2s.cairo @@ -1,5 +1,5 @@ use cairo_verifier::common::{ - array_append::ArrayAppendTrait, blake2s::{blake2s, truncated_blake2s, load32} + array_append::ArrayAppendTrait, blake2s::{blake2s, truncated_blake2s}, blake2s_u8::load32, }; fn get_arr_v1(n: u32) -> Array { diff --git a/src/stark/tests/test_stark_commit.cairo b/src/stark/tests/test_stark_commit.cairo index 2cf800a73..2e013acb0 100644 --- a/src/stark/tests/test_stark_commit.cairo +++ b/src/stark/tests/test_stark_commit.cairo @@ -18,7 +18,7 @@ fn test_stark_commit() { assert( stark_commit( - ref channel, @public_input, @unsent_commitment, @config, @stark_domains, 0.try_into().unwrap() + ref channel, @public_input, @unsent_commitment, @config, @stark_domains ) == stone_proof_fibonacci::stark::commitment::get(), 'Invalid value' );