From 757467db7de443343118e6a963c166412de6cf80 Mon Sep 17 00:00:00 2001 From: Ilya Lesokhin Date: Tue, 10 Feb 2026 09:09:05 +0200 Subject: [PATCH 1/3] Add proving_service based on stwo_run_and_prove. First step toward an HTTP proving service. Future PRs will evolve this crate into a standalone service. --- crates/proving_service/Cargo.toml | 35 +++++++++++++ crates/proving_service/src/lib.rs | 55 +++++++++++++++++++++ crates/proving_service/src/main.rs | 79 ++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 crates/proving_service/Cargo.toml create mode 100644 crates/proving_service/src/lib.rs create mode 100644 crates/proving_service/src/main.rs diff --git a/crates/proving_service/Cargo.toml b/crates/proving_service/Cargo.toml new file mode 100644 index 00000000..42c5a1b5 --- /dev/null +++ b/crates/proving_service/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "proving_service" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +description = "Proving service for Cairo programs" + +[dependencies] +anyhow.workspace = true +cairo-air.workspace = true +cairo-program-runner-lib.workspace = true +cairo-vm.workspace = true +clap.workspace = true +env_logger.workspace = true +log.workspace = true +serde.workspace = true +serde_json.workspace = true +sonic-rs.workspace = true +starknet-ff.workspace = true +stwo-cairo-prover.workspace = true +stwo-cairo-utils.workspace = true +stwo-cairo-adapter.workspace = true +stwo-cairo-serialize.workspace = true +circuit-cairo-air.workspace = true +circuit-prover.workspace = true +stwo-run-and-prove = { path = "../stwo_run_and_prove" } +thiserror.workspace = true +tracing.workspace = true + +[dev-dependencies] +ctor.workspace = true +mockall.workspace = true +rstest.workspace = true +tempfile.workspace = true diff --git a/crates/proving_service/src/lib.rs b/crates/proving_service/src/lib.rs new file mode 100644 index 00000000..afd5938e --- /dev/null +++ b/crates/proving_service/src/lib.rs @@ -0,0 +1,55 @@ +use cairo_air::utils::ProofFormat; +use tracing::{Level, span}; + +use std::{fs::read_to_string, path::PathBuf}; +use stwo_cairo_adapter::ProverInput; +use stwo_cairo_prover::prover::prove_cairo; +use stwo_cairo_prover::stwo::core::vcs_lifted::blake2_merkle::Blake2sM31MerkleChannel; + +use circuit_cairo_air::verify::verify_cairo; +use circuit_prover::prover::prove_circuit; +pub use stwo_run_and_prove::{ + ProveConfig, ProverTrait, RunConfig, StwoProverEntryPoint, StwoRunAndProveError, + stwo_run_and_prove, +}; + +pub struct ProvingServiceEntryPoint; + +impl ProverTrait for ProvingServiceEntryPoint { + fn create_and_serialize_proof( + &self, + prover_input: ProverInput, + _verify: bool, + _proof_path: PathBuf, + _proof_format: ProofFormat, + proof_params_json: Option, + ) -> Result<(), StwoRunAndProveError> { + let proof_params = if let Some(proof_params_json) = proof_params_json { + let s = read_to_string(&proof_params_json) + .map_err(|e| StwoRunAndProveError::PathIO(e, proof_params_json.clone()))?; + serde_json::from_str(&s) + .map_err(|e| StwoRunAndProveError::Anyhow(anyhow::Error::from(e)))? + } else { + panic!("Proof parameters JSON file is required"); + }; + + let span = span!(Level::INFO, "proving cairo").entered(); + let cairo_proof = prove_cairo::(prover_input, proof_params) + .map_err(|e| StwoRunAndProveError::Anyhow(anyhow::Error::from(e)))?; + span.exit(); + + println!("finished proving"); + + let span = span!(Level::INFO, "building verification context").entered(); + let mut context = verify_cairo(&cairo_proof).unwrap(); + span.exit(); + + let span = span!(Level::INFO, "proving verification circuit").entered(); + let _proof = prove_circuit(&mut context); + span.exit(); + + // TODO: Serialize the proof to a file. + + Ok(()) + } +} diff --git a/crates/proving_service/src/main.rs b/crates/proving_service/src/main.rs new file mode 100644 index 00000000..c84773a2 --- /dev/null +++ b/crates/proving_service/src/main.rs @@ -0,0 +1,79 @@ +use cairo_air::utils::ProofFormat; +use cairo_program_runner_lib::utils::get_program_input_from_path; +use clap::Parser; +use proving_service::ProvingServiceEntryPoint; +use std::path::PathBuf; +use std::process::ExitCode; +use stwo_cairo_utils::binary_utils::run_binary; +use stwo_run_and_prove::{ProveConfig, RunConfig, StwoRunAndProveError, stwo_run_and_prove}; +use tracing::{Level, span}; + +/// This binary runs a cairo program and generates a Stwo proof for it. +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[clap(long = "program", help = "Absolute path to the compiled program.")] + program: PathBuf, + #[clap( + long = "program_input", + help = "Absolute path to the program input file." + )] + program_input: Option, + #[clap( + long = "prover_params_json", + help = "Absolute path to the JSON file containing the prover parameters." + )] + prover_params_json: Option, + #[clap( + long = "proof_path", + help = "Absolute path where the generated proof will be saved." + )] + proof_path: PathBuf, + #[clap(long, value_enum, default_value_t = ProofFormat::CairoSerde, help = "Json or cairo-serde.")] + proof_format: ProofFormat, + #[clap(long = "verify", help = "Should verify the generated proof.")] + verify: bool, + #[clap( + long = "program_output", + help = "Optional absolute path where the program's output will be saved." + )] + program_output: Option, + #[clap( + long = "save_debug_data", + help = "Should save the ProverInput to a file in `debug_data_dir` for both success and failure." + )] + save_debug_data: bool, + #[clap( + long = "debug_data_dir", + help = "Absolute path to the output directory where the ProverInput will be saved in the + case of a proving error, or when the save_debug_data flag is enabled." + )] + debug_data_dir: Option, +} + +fn main() -> ExitCode { + run_binary(run, "proving_service") +} + +fn run() -> Result<(), StwoRunAndProveError> { + let _span = span!(Level::INFO, "run").entered(); + let args = Args::parse(); + let prove_config = ProveConfig { + verify: args.verify, + proof_path: args.proof_path, + proof_format: args.proof_format, + prover_params_json: args.prover_params_json, + }; + + let prover = Box::new(ProvingServiceEntryPoint); + let run_config = RunConfig { + program_path: args.program, + program_input: get_program_input_from_path(&args.program_input)?, + program_output: args.program_output, + debug_data_dir: args.debug_data_dir, + save_debug_data: args.save_debug_data, + extra_hint_processor: None, + }; + stwo_run_and_prove(run_config, prove_config, prover)?; + Ok(()) +} From b61ba5780a9872b354eb4f0d4b9378208ce67cb6 Mon Sep 17 00:00:00 2001 From: Ilya Lesokhin Date: Thu, 26 Feb 2026 09:45:10 +0200 Subject: [PATCH 2/3] Add preprocessing --- Cargo.toml | 23 +++++++++++--- crates/proving_service/Cargo.toml | 4 +++ crates/proving_service/src/lib.rs | 49 ++++++++++++++++++++++++------ crates/proving_service/src/main.rs | 14 ++++++++- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 856a151a..fd4f45ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,10 +3,14 @@ members = [ "crates/cairo-program-runner", "crates/cairo-program-runner-lib", "crates/stwo_run_and_prove", + "crates/proving_service", "crates/vm_runner", ] resolver = "2" +[profile.release] +debug = true + [workspace.package] version = "1.1.0" edition = "2024" @@ -16,7 +20,7 @@ repository = "https://github.com/starkware-libs/proving-utils" [workspace.dependencies] anyhow = "1.0.98" bincode = { version = "2.0.1", features = ["serde"] } -cairo-air = "1.1.0" +cairo-air = { git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } cairo-lang-executable = "2.16.0" cairo-lang-runner = "2.16.0" cairo-lang-casm = "2.16.0" @@ -40,13 +44,22 @@ sonic-rs = "0.3.17" starknet-crypto = "=0.8.1" starknet-ff = "0.3.7" starknet-types-core = "=0.2.4" -stwo-cairo-utils = "1.1.0" -stwo-cairo-adapter = "1.1.0" -stwo-cairo-prover = "1.1.0" -stwo-cairo-serialize = "1.1.0" +stwo = { git = "https://github.com/starkware-libs/stwo", rev = "f117d487", features = [ + "parallel", +], default-features = false } +stwo-cairo-utils = { package = "stwo-cairo-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } +stwo-cairo-adapter = { package = "stwo-cairo-adapter", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } +stwo-cairo-prover = { package = "stwo-cairo-prover", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } +stwo-cairo-serialize = { package = "stwo-cairo-serialize", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } +circuit-cairo-air = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } +circuit-prover = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } +circuits = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } +circuits-stark-verifier = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } tempfile = "3.10.1" thiserror = "1.0.61" thiserror-no-std = "2.0.2" + tracing = "0.1.40" mockall = "0.13.1" rstest = "0.21" + diff --git a/crates/proving_service/Cargo.toml b/crates/proving_service/Cargo.toml index 42c5a1b5..fc136ed5 100644 --- a/crates/proving_service/Cargo.toml +++ b/crates/proving_service/Cargo.toml @@ -24,6 +24,10 @@ stwo-cairo-adapter.workspace = true stwo-cairo-serialize.workspace = true circuit-cairo-air.workspace = true circuit-prover.workspace = true +circuits.workspace = true +circuits-stark-verifier.workspace = true +itertools = "0.12" +stwo.workspace = true stwo-run-and-prove = { path = "../stwo_run_and_prove" } thiserror.workspace = true tracing.workspace = true diff --git a/crates/proving_service/src/lib.rs b/crates/proving_service/src/lib.rs index afd5938e..567ed8c0 100644 --- a/crates/proving_service/src/lib.rs +++ b/crates/proving_service/src/lib.rs @@ -1,19 +1,34 @@ use cairo_air::utils::ProofFormat; -use tracing::{Level, span}; - +use circuit_cairo_air::statement::MEMORY_VALUES_LIMBS; +use circuit_cairo_air::verify::{ + prepare_cairo_proof_for_circuit_verifier, verify_fixed_cairo_circuit, CairoVerifierConfig, +}; +use circuit_prover::finalize::finalize_context; +use circuit_prover::prover::prove_circuit_assignment; +use circuit_prover::witness::preprocessed::PreprocessedCircuit; +use itertools::Itertools; +use stwo_cairo_prover::prover::prove_cairo; +use stwo_cairo_prover::witness::prelude::SimdBackend; +use std::array; use std::{fs::read_to_string, path::PathBuf}; +use stwo::core::fields::m31::M31; use stwo_cairo_adapter::ProverInput; -use stwo_cairo_prover::prover::prove_cairo; use stwo_cairo_prover::stwo::core::vcs_lifted::blake2_merkle::Blake2sM31MerkleChannel; +use circuit_prover::prover::BaseColumnPool; + +use tracing::{Level, span}; -use circuit_cairo_air::verify::verify_cairo; -use circuit_prover::prover::prove_circuit; pub use stwo_run_and_prove::{ ProveConfig, ProverTrait, RunConfig, StwoProverEntryPoint, StwoRunAndProveError, stwo_run_and_prove, }; -pub struct ProvingServiceEntryPoint; + +pub struct ProvingServiceEntryPoint { + pub base_column_pool: BaseColumnPool, + pub preprocessed_circuit: PreprocessedCircuit, + pub privacy_verifier_config: CairoVerifierConfig, +} impl ProverTrait for ProvingServiceEntryPoint { fn create_and_serialize_proof( @@ -38,14 +53,30 @@ impl ProverTrait for ProvingServiceEntryPoint { .map_err(|e| StwoRunAndProveError::Anyhow(anyhow::Error::from(e)))?; span.exit(); - println!("finished proving"); + let (proof, public_data) = prepare_cairo_proof_for_circuit_verifier(&cairo_proof, &self.privacy_verifier_config.proof_config); + + let (public_claim, outputs, _program) = public_data.pack_into_u32s(); + let outputs: Vec<[M31; 28]> = outputs + .chunks_exact(MEMORY_VALUES_LIMBS) + .map(|chunk| array::from_fn(|i| M31::from_u32_unchecked(chunk[i]))) + .collect_vec(); + let span = span!(Level::INFO, "building verification context").entered(); - let mut context = verify_cairo(&cairo_proof).unwrap(); + + let mut context = verify_fixed_cairo_circuit(&self.privacy_verifier_config, proof, public_claim, outputs).unwrap(); span.exit(); + + finalize_context(&mut context); + let context_values = context.values(); + let span = span!(Level::INFO, "proving verification circuit").entered(); - let _proof = prove_circuit(&mut context); + + + let _proof = prove_circuit_assignment(context_values, &self.preprocessed_circuit, &self.base_column_pool); + + span.exit(); // TODO: Serialize the proof to a file. diff --git a/crates/proving_service/src/main.rs b/crates/proving_service/src/main.rs index c84773a2..fc2c3222 100644 --- a/crates/proving_service/src/main.rs +++ b/crates/proving_service/src/main.rs @@ -1,5 +1,10 @@ use cairo_air::utils::ProofFormat; use cairo_program_runner_lib::utils::get_program_input_from_path; +use circuit_cairo_air::privacy::privacy_cairo_verifier_config; +use circuit_cairo_air::verify::build_cairo_verifier_circuit; +use circuit_prover::prover::BaseColumnPool; +use circuit_prover::witness::preprocessed::PreprocessedCircuit; +use stwo_cairo_prover::witness::prelude::SimdBackend; use clap::Parser; use proving_service::ProvingServiceEntryPoint; use std::path::PathBuf; @@ -65,7 +70,12 @@ fn run() -> Result<(), StwoRunAndProveError> { prover_params_json: args.prover_params_json, }; - let prover = Box::new(ProvingServiceEntryPoint); + let privacy_verifier_config = privacy_cairo_verifier_config(); + let mut novalue_context = build_cairo_verifier_circuit(&privacy_verifier_config); + let preprocessed_circuit = PreprocessedCircuit::preprocess_circuit(&mut novalue_context); + + + let prover = Box::new(ProvingServiceEntryPoint { base_column_pool: BaseColumnPool::::new(), preprocessed_circuit, privacy_verifier_config }); let run_config = RunConfig { program_path: args.program, program_input: get_program_input_from_path(&args.program_input)?, @@ -74,6 +84,8 @@ fn run() -> Result<(), StwoRunAndProveError> { save_debug_data: args.save_debug_data, extra_hint_processor: None, }; + // Sleep for 1 second to create a seperation between the preproccessing and the proving. + std::thread::sleep(std::time::Duration::from_secs(1)); stwo_run_and_prove(run_config, prove_config, prover)?; Ok(()) } From 5a13ad9ebc1e53d0cf98dcf720e3c63a9dc47fba Mon Sep 17 00:00:00 2001 From: Ilya Lesokhin Date: Thu, 5 Mar 2026 09:52:15 +0200 Subject: [PATCH 3/3] wip --- Cargo.toml | 21 ++++---- crates/proving_service/Cargo.toml | 1 + crates/proving_service/src/lib.rs | 79 +++++++++++++++++++++++------- crates/proving_service/src/main.rs | 76 ++++++++++++++++++++++++++-- 4 files changed, 145 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fd4f45ab..b3926b75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ repository = "https://github.com/starkware-libs/proving-utils" [workspace.dependencies] anyhow = "1.0.98" bincode = { version = "2.0.1", features = ["serde"] } -cairo-air = { git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } +cairo-air = { git = "https://github.com/starkware-libs/stwo-cairo", rev = "319e2e96" } cairo-lang-executable = "2.16.0" cairo-lang-runner = "2.16.0" cairo-lang-casm = "2.16.0" @@ -44,17 +44,18 @@ sonic-rs = "0.3.17" starknet-crypto = "=0.8.1" starknet-ff = "0.3.7" starknet-types-core = "=0.2.4" -stwo = { git = "https://github.com/starkware-libs/stwo", rev = "f117d487", features = [ +stwo = { git = "https://github.com/starkware-libs/stwo", rev = "3428a95e", features = [ "parallel", ], default-features = false } -stwo-cairo-utils = { package = "stwo-cairo-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } -stwo-cairo-adapter = { package = "stwo-cairo-adapter", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } -stwo-cairo-prover = { package = "stwo-cairo-prover", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } -stwo-cairo-serialize = { package = "stwo-cairo-serialize", git = "https://github.com/starkware-libs/stwo-cairo", rev = "fa4c727d" } -circuit-cairo-air = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } -circuit-prover = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } -circuits = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } -circuits-stark-verifier = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "0f6ac85" } +stwo-cairo-utils = { package = "stwo-cairo-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "319e2e96" } +stwo-cairo-adapter = { package = "stwo-cairo-adapter", git = "https://github.com/starkware-libs/stwo-cairo", rev = "319e2e96" } +stwo-cairo-prover = { package = "stwo-cairo-prover", git = "https://github.com/starkware-libs/stwo-cairo", rev = "319e2e96" } +stwo-cairo-serialize = { package = "stwo-cairo-serialize", git = "https://github.com/starkware-libs/stwo-cairo", rev = "319e2e96" } +circuit-air = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "c6aea41" } +circuit-cairo-air = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "c6aea41" } +circuit-prover = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "c6aea41" } +circuits = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "c6aea41" } +circuits-stark-verifier = { git = "https://github.com/starkware-libs/stwo-circuits", rev = "c6aea41" } tempfile = "3.10.1" thiserror = "1.0.61" thiserror-no-std = "2.0.2" diff --git a/crates/proving_service/Cargo.toml b/crates/proving_service/Cargo.toml index fc136ed5..cb4e3838 100644 --- a/crates/proving_service/Cargo.toml +++ b/crates/proving_service/Cargo.toml @@ -22,6 +22,7 @@ stwo-cairo-prover.workspace = true stwo-cairo-utils.workspace = true stwo-cairo-adapter.workspace = true stwo-cairo-serialize.workspace = true +circuit-air.workspace = true circuit-cairo-air.workspace = true circuit-prover.workspace = true circuits.workspace = true diff --git a/crates/proving_service/src/lib.rs b/crates/proving_service/src/lib.rs index 567ed8c0..f17b066e 100644 --- a/crates/proving_service/src/lib.rs +++ b/crates/proving_service/src/lib.rs @@ -1,20 +1,29 @@ use cairo_air::utils::ProofFormat; +use circuit_air::statement::all_circuit_components; use circuit_cairo_air::statement::MEMORY_VALUES_LIMBS; use circuit_cairo_air::verify::{ - prepare_cairo_proof_for_circuit_verifier, verify_fixed_cairo_circuit, CairoVerifierConfig, + CairoVerifierConfig, build_fixed_cairo_circuit, prepare_cairo_proof_for_circuit_verifier, }; use circuit_prover::finalize::finalize_context; -use circuit_prover::prover::prove_circuit_assignment; +use circuit_prover::prover::BaseColumnPool; +use circuit_prover::prover::preprare_circuit_proof_for_circuit_verifier; +use circuit_prover::prover::{SimdBackend, prove_circuit_with_precompute}; use circuit_prover::witness::preprocessed::PreprocessedCircuit; +use circuits_stark_verifier::proof::ProofConfig; use itertools::Itertools; -use stwo_cairo_prover::prover::prove_cairo; -use stwo_cairo_prover::witness::prelude::SimdBackend; use std::array; +use std::sync::Arc; use std::{fs::read_to_string, path::PathBuf}; use stwo::core::fields::m31::M31; +use stwo::core::fields::qm31::QM31; +use stwo::core::pcs::PcsConfig; +use stwo::core::utils::MaybeOwned; +use stwo::prover::CommitmentTreeProver; +use stwo::prover::poly::twiddles::TwiddleTree; use stwo_cairo_adapter::ProverInput; +use stwo_cairo_prover::prover::{ProverParameters, prove_cairo_with_precompute}; use stwo_cairo_prover::stwo::core::vcs_lifted::blake2_merkle::Blake2sM31MerkleChannel; -use circuit_prover::prover::BaseColumnPool; +use stwo_cairo_prover::witness::prelude::PreProcessedTrace; use tracing::{Level, span}; @@ -23,11 +32,14 @@ pub use stwo_run_and_prove::{ stwo_run_and_prove, }; - pub struct ProvingServiceEntryPoint { pub base_column_pool: BaseColumnPool, pub preprocessed_circuit: PreprocessedCircuit, pub privacy_verifier_config: CairoVerifierConfig, + pub twiddles: TwiddleTree, + pub cairo_preprocessed_trace: Arc, + pub cairo_preprocessed_tree: CommitmentTreeProver, + pub circuit_preprocessed_tree: CommitmentTreeProver, } impl ProverTrait for ProvingServiceEntryPoint { @@ -39,7 +51,7 @@ impl ProverTrait for ProvingServiceEntryPoint { _proof_format: ProofFormat, proof_params_json: Option, ) -> Result<(), StwoRunAndProveError> { - let proof_params = if let Some(proof_params_json) = proof_params_json { + let proof_params: ProverParameters = if let Some(proof_params_json) = proof_params_json { let s = read_to_string(&proof_params_json) .map_err(|e| StwoRunAndProveError::PathIO(e, proof_params_json.clone()))?; serde_json::from_str(&s) @@ -49,36 +61,67 @@ impl ProverTrait for ProvingServiceEntryPoint { }; let span = span!(Level::INFO, "proving cairo").entered(); - let cairo_proof = prove_cairo::(prover_input, proof_params) - .map_err(|e| StwoRunAndProveError::Anyhow(anyhow::Error::from(e)))?; + let cairo_proof = prove_cairo_with_precompute::( + &self.base_column_pool, + &self.twiddles, + self.cairo_preprocessed_trace.clone(), + MaybeOwned::Borrowed(&self.cairo_preprocessed_tree), + prover_input, + proof_params, + ) + .map_err(|e| StwoRunAndProveError::Anyhow(anyhow::Error::from(e)))?; span.exit(); - let (proof, public_data) = prepare_cairo_proof_for_circuit_verifier(&cairo_proof, &self.privacy_verifier_config.proof_config); + let (proof, public_data) = prepare_cairo_proof_for_circuit_verifier( + &cairo_proof, + &self.privacy_verifier_config.proof_config, + ); let (public_claim, outputs, _program) = public_data.pack_into_u32s(); let outputs: Vec<[M31; 28]> = outputs .chunks_exact(MEMORY_VALUES_LIMBS) .map(|chunk| array::from_fn(|i| M31::from_u32_unchecked(chunk[i]))) .collect_vec(); - let span = span!(Level::INFO, "building verification context").entered(); - - let mut context = verify_fixed_cairo_circuit(&self.privacy_verifier_config, proof, public_claim, outputs).unwrap(); - span.exit(); + let mut context = + build_fixed_cairo_circuit(&self.privacy_verifier_config, proof, public_claim, outputs); + span.exit(); finalize_context(&mut context); let context_values = context.values(); - + let span = span!(Level::INFO, "proving verification circuit").entered(); - - let _proof = prove_circuit_assignment(context_values, &self.preprocessed_circuit, &self.base_column_pool); + let mut pcs_config = PcsConfig::default(); + let lifting_log_size = self.preprocessed_circuit.params.trace_log_size + + pcs_config.fri_config.log_blowup_factor; + pcs_config.lifting_log_size = Some(lifting_log_size); - + let circuit_proof = prove_circuit_with_precompute( + &self.base_column_pool, + &self.twiddles, + &self.preprocessed_circuit, + MaybeOwned::Borrowed(&self.circuit_preprocessed_tree), + context_values, + pcs_config, + ); span.exit(); + let preprocessed_column_ids = self.preprocessed_circuit.preprocessed_trace.ids(); + let proof_config = ProofConfig::from_components( + &all_circuit_components::(), + preprocessed_column_ids.len(), + &circuit_proof.pcs_config, + circuit_air::statement::INTERACTION_POW_BITS, + ); + let (_proof, _public_data) = + preprare_circuit_proof_for_circuit_verifier(circuit_proof, proof_config); + + // Sleep for 1 second to create a seperation between the proving and clean up. + std::thread::sleep(std::time::Duration::from_secs(1)); + // TODO: Serialize the proof to a file. Ok(()) diff --git a/crates/proving_service/src/main.rs b/crates/proving_service/src/main.rs index fc2c3222..a3ff1dbb 100644 --- a/crates/proving_service/src/main.rs +++ b/crates/proving_service/src/main.rs @@ -1,14 +1,21 @@ -use cairo_air::utils::ProofFormat; +use cairo_air::{PreProcessedTraceVariant, utils::ProofFormat}; use cairo_program_runner_lib::utils::get_program_input_from_path; use circuit_cairo_air::privacy::privacy_cairo_verifier_config; use circuit_cairo_air::verify::build_cairo_verifier_circuit; use circuit_prover::prover::BaseColumnPool; use circuit_prover::witness::preprocessed::PreprocessedCircuit; -use stwo_cairo_prover::witness::prelude::SimdBackend; use clap::Parser; use proving_service::ProvingServiceEntryPoint; -use std::path::PathBuf; use std::process::ExitCode; +use std::{cmp::max, path::PathBuf, sync::Arc}; +use stwo::{ + core::vcs_lifted::blake2_merkle::Blake2sM31MerkleChannel, + prover::{CommitmentTreeProver, poly::circle::PolyOps}, +}; +use stwo_cairo_prover::witness::{ + prelude::{CanonicCoset, SimdBackend}, + preprocessed_trace::gen_trace, +}; use stwo_cairo_utils::binary_utils::run_binary; use stwo_run_and_prove::{ProveConfig, RunConfig, StwoRunAndProveError, stwo_run_and_prove}; use tracing::{Level, span}; @@ -71,11 +78,72 @@ fn run() -> Result<(), StwoRunAndProveError> { }; let privacy_verifier_config = privacy_cairo_verifier_config(); + let proof_config = &privacy_verifier_config.proof_config; let mut novalue_context = build_cairo_verifier_circuit(&privacy_verifier_config); let preprocessed_circuit = PreprocessedCircuit::preprocess_circuit(&mut novalue_context); + let cairo_evaluation_domain_log_size = proof_config + .log_evaluation_domain_size() + .try_into() + .unwrap(); - let prover = Box::new(ProvingServiceEntryPoint { base_column_pool: BaseColumnPool::::new(), preprocessed_circuit, privacy_verifier_config }); + let circuit_proof_log_blowup_factor = 1; + let max_domain_size = max( + preprocessed_circuit.params.trace_log_size + circuit_proof_log_blowup_factor, + cairo_evaluation_domain_log_size, + ); + + // Precompute twiddles. + // Account for blowup factor and for composition polynomial calculation (taking the max since + // the composition polynomial is split prior to LDE). + let twiddles = SimdBackend::precompute_twiddles( + CanonicCoset::new(max_domain_size) + .circle_domain() + .half_coset, + ); + + let preprocessed_trace = + Arc::new(PreProcessedTraceVariant::CanonicalSmall.to_preprocessed_trace()); + let preprocessed_trace_polys = + SimdBackend::interpolate_columns(gen_trace(preprocessed_trace.clone()), &twiddles); + + let store_polynomials_coefficients = true; + + let base_column_pool = BaseColumnPool::::new(); + let cairo_preprocessed_tree = CommitmentTreeProver::::new( + preprocessed_trace_polys, + proof_config.fri.log_blowup_factor.try_into().unwrap(), + &twiddles, + store_polynomials_coefficients, + Some(cairo_evaluation_domain_log_size), + &base_column_pool, + ); + + let circuit_preprocessed_trace = preprocessed_circuit + .preprocessed_trace + .get_trace::(); + let circuit_preprocessed_trace_polys = + SimdBackend::interpolate_columns(circuit_preprocessed_trace, &twiddles); + + let circuit_preprocessed_tree = + CommitmentTreeProver::::new( + circuit_preprocessed_trace_polys, + circuit_proof_log_blowup_factor, + &twiddles, + store_polynomials_coefficients, + None, + &base_column_pool, + ); + + let prover = Box::new(ProvingServiceEntryPoint { + base_column_pool, + preprocessed_circuit, + privacy_verifier_config, + twiddles, + cairo_preprocessed_trace: preprocessed_trace, + cairo_preprocessed_tree, + circuit_preprocessed_tree, + }); let run_config = RunConfig { program_path: args.program, program_input: get_program_input_from_path(&args.program_input)?,