8000 add dev_utils craate and vm_adapter_prover binary by Stavbe · Pull Request #909 · starkware-libs/stwo-cairo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

add dev_utils craate and vm_adapter_prover binary #909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions stwo_cairo_prover/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion stwo_cairo_prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
"crates/utils",
"crates/common",
"crates/cairo-air",
]
"crates/dev_utils"]
resolver = "2"

[workspace.package]
Expand Down
20 changes: 20 additions & 0 deletions stwo_cairo_prover/crates/dev_utils/Cargo.toml
8000
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "dev-utils"
version.workspace = true
edition.workspace = true

[dependencies]
cairo-air.workspace = true
clap.workspace = true
serde.workspace = true
starknet-ff.workspace = true
sonic-rs = "0.3.17"
stwo-cairo-adapter = {path= "../adapter", features = ["std"]}
stwo-cairo-serialize.workspace = true
stwo-prover.workspace = true
stwo_cairo_prover.workspace = true
tracing-subscriber.workspace = true
thiserror.workspace = true
tracing.workspace = true
log.workspace = true

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::path::PathBuf;

use clap::Parser;
use dev_utils::utils::{create_and_serialize_proof, Error, ProofFormat};
use stwo_cairo_adapter::test_utils::{read_compiled_cairo_program, run_program_and_adapter};
use tracing::{span, Level};
use tracing_subscriber::fmt::format::FmtSpan;

// Command line arguments for 'prove_from_compiled_program'.
/// Example command line:
/// ```
/// cargo run --bin prove_from_compiled_program -- --compiled_program
/// absolute/path/to/compiled.json --proof_path path/to/proof
/// ```
///
/// For optimal performance compile with:
/// ```
/// RUSTFLAGS="-C target-cpu=native -C opt-level=3"
/// ```
///
/// Standard library features is off by default, to enable it, further improving performance, use:
/// ```
/// --features=std
/// ```
#[derive(Parser, Debug)]
struct Args {
#[structopt(long = "compiled_program")]
compiled_program: PathBuf,
/// The path to the JSON file containing the prover parameters (optional).
/// The expected file format is:
/// {
/// "channel_hash":"blake2s",Sd
/// "pcs_config": {
/// "pow_bits": 26,
/// "fri_config": {
/// "log_last_layer_degree_bound": 0,
/// "log_blowup_factor": 1,
/// "n_queries": 70
/// }
/// },
/// "preprocessed_trace": "canonical_without_pedersen"
/// }
///
/// Default parameters are chosen to ensure 96 bits of security.
#[structopt(long = "params_json")]
params_json: Option<PathBuf>,
/// The output file path for the proof.
#[structopt(long = "proof_path")]
proof_path: PathBuf,
/// The format of the proof output.
/// - json: Standard JSON format (default)
/// - cairo_serde: Array of field elements serialized as hex strings, ex. `["0x1", "0x2"]`
#[arg(long, value_enum, default_value_t = ProofFormat::Json)]
proof_format: ProofFormat,
/// Verify the generated proof.
#[structopt(long = "verify")]
verify: bool,
}

fn main() -> Result<(), Error> {
tracing_subscriber::fmt()
.with_span_events(FmtSpan::ENTER | FmtSpan::CLOSE)
.init();

let _span = span!(Level::INFO, "run").entered();
let args = Args::try_parse_from(std::env::args())?;

let compiled_program = read_compiled_cairo_program(&args.compiled_program);
let input = run_program_and_adapter(&compiled_program);

create_and_serialize_proof(
input,
args.verify,
args.proof_path,
args.proof_format,
args.params_json,
)
}
1 change: 1 addition & 0 deletions stwo_cairo_prover/crates/dev_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod utils;
133 changes: 133 additions & 0 deletions stwo_cairo_prover/crates/dev_utils/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

use cairo_air::verifier::{verify_cairo, CairoVerificationError};
use cairo_air::PreProcessedTraceVariant;
use serde::Serialize;
use stwo_cairo_adapter::vm_import::VmImportError;
use stwo_cairo_adapter::ProverInput;
use stwo_cairo_prover::prover::{
default_prod_prover_parameters, prove_cairo, ChannelHash, ProverParameters,
};
use stwo_cairo_serialize::CairoSerialize;
use stwo_prover::core::backend::simd::SimdBackend;
use stwo_prover::core::backend::BackendForChannel;
use stwo_prover::core::channel::MerkleChannel;
use stwo_prover::core::pcs::PcsConfig;
use stwo_prover::core::prover::ProvingError;
use stwo_prover::core::vcs::blake2_merkle::Blake2sMerkleChannel;
use stwo_prover::core::vcs::ops::MerkleHasher;
use stwo_prover::core::vcs::poseidon252_merkle::Poseidon252MerkleChannel;
use thiserror::Error;
use tracing::{span, Level};

#[derive(Debug, Clone, clap::ValueEnum)]
pub enum ProofFormat {
/// Standard JSON format.
Json,
/// Array of field elements serialized as hex strings.
/// Compatible with `scarb execute`
CairoSerde,
}

#[derive(Debug, Error)]
pub enum Error {
#[error("Invalid arguments: {0}")]
Cli(#[from] clap::Error),
#[error("IO failed: {0}")]
IO(#[from] std::io::Error),
#[error("Proving failed: {0}")]
Proving(#[from] ProvingError),
#[error("Serialization failed: {0}")]
Serializing(#[from] sonic_rs::error::Error),
#[error("Verification failed: {0}")]
Verification(#[from] CairoVerificationError),
#[error("VM import failed: {0}")]
VmImport(#[from] VmImportError),
}

/// Generates proof given the Cairo VM output and prover config/parameters.
/// Serializes the proof as JSON and write to the output path.
/// Verifies the proof in case the respective flag is set.
pub fn create_and_serialize_generic_proof<MC: MerkleChannel>(
input: ProverInput,
pcs_config: PcsConfig,
preprocessed_trace: PreProcessedTraceVariant,
verify: bool,
proof_path: PathBuf,
proof_format: ProofFormat,
) -> Result<(), Error>
where
SimdBackend: BackendForChannel<MC>,
MC::H: Serialize,
<MC::H as MerkleHasher>::Hash: CairoSerialize,
{
let proof = prove_cairo::<MC>(input, pcs_config, preprocessed_trace)?;
let mut proof_file = File::create(proof_path)?;

let span = span!(Level::INFO, "Serialize proof").entered();
match proof_format {
ProofFormat::Json => {
proof_file.write_all(sonic_rs::to_string_pretty(&proof)?.as_bytes())?;
}
ProofFormat::CairoSerde => {
let mut serialized: Vec<starknet_ff::FieldElement> = Vec::new();
CairoSerialize::serialize(&proof, &mut serialized);

let hex_strings: Vec<String> = serialized
.into_iter()
.map(|felt| format!("0x{:x}", felt))
.collect();

proof_file.write_all(sonic_rs::to_string_pretty(&hex_strings)?.as_bytes())?;
}
}
span.exit();
if verify {
verify_cairo::<MC>(proof, pcs_config, preprocessed_trace)?;
log::info!("Proof verified successfully");
}

Ok(())
}

pub fn create_and_serialize_proof(
input: ProverInput,
verify: bool,
proof_path: PathBuf,
proof_format: ProofFormat,
proof_params_json: Option<PathBuf>,
) -> Result<(), Error> {
let ProverParameters {
channel_hash,
pcs_config,
preprocessed_trace,
} = match proof_params_json {
Some(path) => sonic_rs::from_str(&std::fs::read_to_string(&path)?)?,
None => default_prod_prover_parameters(),
};

let create_and_serialize_generic_proof: fn(
ProverInput,
PcsConfig,
PreProcessedTraceVariant,
bool,
PathBuf,
ProofFormat,
) -> Result<(), Error> = match channel_hash {
ChannelHash::Blake2s => create_and_serialize_generic_proof::<Blake2sMerkleChannel>,
ChannelHash::Poseidon252 => create_and_serialize_generic_proof::<Poseidon252MerkleChannel>,
};

create_and_serialize_generic_proof(
input,
pcs_config,
preprocessed_trace,
verify,
proof_path,
proof_format,
)?;

Ok(())
}
Loading
0