Repository: openvm-org/openvm
Pull request #1649: refactor: CLI Build & Setup
Author: login: nyunyunyunyu
Created: 2025-05-14T00:53:56Z | Merged: 2025-05-15T23:09:27Z

- `cargo openvm setup` supports skipping halo2 proving keys.
- `cargo openvm setup` outputs halo2 PK and stark PK as separated files.
- `cargo openvm build` outputs `AppExecutionCommit` in json. The old output(`exe_commit.bytes`) was incorrect.

close INT-3950


Diff:
diff --git a/crates/cli/src/commands/build.rs b/crates/cli/src/commands/build.rs
index 576a9e044d..1d495b2bcf 100644
--- a/crates/cli/src/commands/build.rs
+++ b/crates/cli/src/commands/build.rs
@@ -12,18 +12,11 @@ use openvm_build::{
     GuestOptions,
 };
 use openvm_circuit::arch::{InitFileGenerator, OPENVM_DEFAULT_INIT_FILE_NAME};
-use openvm_sdk::{
-    commit::{commit_app_exe, committed_exe_as_bn254},
-    fs::write_exe_to_file,
-    Sdk,
-};
+use openvm_sdk::{commit::commit_app_exe, fs::write_exe_to_file, Sdk};
 use openvm_transpiler::{elf::Elf, openvm_platform::memory::MEM_SIZE};
 
 use crate::{
-    default::{
-        DEFAULT_APP_CONFIG_PATH, DEFAULT_APP_EXE_PATH, DEFAULT_COMMITTED_APP_EXE_PATH,
-        DEFAULT_EXE_COMMIT_PATH,
-    },
+    default::{DEFAULT_APP_CONFIG_PATH, DEFAULT_APP_EXE_PATH, DEFAULT_COMMITTED_APP_EXE_PATH},
     util::{find_manifest_dir, read_config_toml_or_default},
 };
 
@@ -78,14 +71,6 @@ pub struct BuildArgs {
     )]
     pub committed_exe_output: PathBuf,
 
-    #[arg(
-        long,
-        default_value = DEFAULT_EXE_COMMIT_PATH,
-        help = "Output path for the exe commit (bn254 commit of committed program)",
-        help_heading = "OpenVM Options"
-    )]
-    pub exe_commit_output: PathBuf,
-
     #[arg(
         long,
         default_value = OPENVM_DEFAULT_INIT_FILE_NAME,
@@ -428,13 +413,6 @@ pub fn build(build_args: &BuildArgs, cargo_args: &BuildCargoArgs) -> Result<Vec<
             let committed_exe = commit_app_exe(app_config.app_fri_params.fri_params, exe.clone());
             write_exe_to_file(exe, output_path)?;
 
-            if let Some(parent) = build_args.exe_commit_output.parent() {
-                create_dir_all(parent)?;
-            }
-            write(
-                &build_args.exe_commit_output,
-                committed_exe_as_bn254(&committed_exe).value.to_bytes(),
-            )?;
             if let Some(parent) = build_args.committed_exe_output.parent() {
                 create_dir_all(parent)?;
             }
diff --git a/crates/cli/src/commands/keygen.rs b/crates/cli/src/commands/keygen.rs
index 687e2f92a1..b3070a10de 100644
--- a/crates/cli/src/commands/keygen.rs
+++ b/crates/cli/src/commands/keygen.rs
@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 
 use clap::Parser;
 use eyre::Result;
@@ -37,10 +37,19 @@ pub struct KeygenCmd {
 
 impl KeygenCmd {
     pub fn run(&self) -> Result<()> {
-        let app_config = read_config_toml_or_default(&self.config)?;
-        let app_pk = Sdk::new().app_keygen(app_config)?;
-        write_app_vk_to_file(app_pk.get_app_vk(), &self.vk_output)?;
-        write_app_pk_to_file(app_pk, &self.output)?;
+        keygen(&self.config, &self.output, &self.vk_output)?;
         Ok(())
     }
 }
+
+pub(crate) fn keygen(
+    config: impl AsRef<Path>,
+    output: impl AsRef<Path>,
+    vk_output: impl AsRef<Path>,
+) -> Result<()> {
+    let app_config = read_config_toml_or_default(config)?;
+    let app_pk = Sdk::new().app_keygen(app_config)?;
+    write_app_vk_to_file(app_pk.get_app_vk(), vk_output.as_ref())?;
+    write_app_pk_to_file(app_pk, output.as_ref())?;
+    Ok(())
+}
diff --git a/crates/cli/src/commands/prove.rs b/crates/cli/src/commands/prove.rs
index db33cf766a..9c53e111f8 100644
--- a/crates/cli/src/commands/prove.rs
+++ b/crates/cli/src/commands/prove.rs
@@ -8,13 +8,15 @@ use openvm_sdk::{
     commit::AppExecutionCommit,
     config::{AggregationTreeConfig, SdkVmConfig},
     fs::{
-        encode_to_file, read_agg_pk_from_file, read_app_pk_from_file, read_exe_from_file,
+        encode_to_file, read_agg_stark_pk_from_file, read_app_pk_from_file, read_exe_from_file,
         write_app_proof_to_file,
     },
     keygen::AppProvingKey,
     NonRootCommittedExe, Sdk, StdIn,
 };
 
+#[cfg(feature = "evm-prove")]
+use crate::util::read_default_agg_pk;
 use crate::{
     default::*,
     input::{read_to_stdin, Input},
@@ -110,16 +112,11 @@ impl ProveCmd {
                 );
                 println!("exe commit: {:?}", commits.exe_commit);
                 println!("vm commit: {:?}", commits.vm_commit);
-
-                let agg_pk = read_agg_pk_from_file(default_agg_pk_path()).map_err(|e| {
+                let agg_stark_pk = read_agg_stark_pk_from_file(default_agg_stark_pk_path()).map_err(|e| {
                     eyre::eyre!("Failed to read aggregation proving key: {}\nPlease run 'cargo openvm setup' first", e)
                 })?;
-                let stark_proof = sdk.generate_e2e_stark_proof(
-                    app_pk,
-                    committed_exe,
-                    agg_pk.agg_stark_pk,
-                    input,
-                )?;
+                let stark_proof =
+                    sdk.generate_e2e_stark_proof(app_pk, committed_exe, agg_stark_pk, input)?;
                 encode_to_file(output, stark_proof)?;
             }
             #[cfg(feature = "evm-prove")]
@@ -146,7 +143,7 @@ impl ProveCmd {
                 println!("vm commit: {:?}", commits.vm_commit_to_bn254());
 
                 println!("Generating EVM proof, this may take a lot of compute and memory...");
-                let agg_pk = read_agg_pk_from_file(default_agg_pk_path()).map_err(|e| {
+                let agg_pk = read_default_agg_pk().map_err(|e| {
                     eyre::eyre!("Failed to read aggregation proving key: {}\nPlease run 'cargo openvm setup' first", e)
                 })?;
                 let evm_proof =
diff --git a/crates/cli/src/commands/setup.rs b/crates/cli/src/commands/setup.rs
index c617112707..d84255c7f4 100644
--- a/crates/cli/src/commands/setup.rs
+++ b/crates/cli/src/commands/setup.rs
@@ -9,16 +9,21 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
-use crate::default::{
-    default_agg_pk_path, default_asm_path, default_evm_halo2_verifier_path, default_params_dir,
+use crate::{
+    default::{
+        default_agg_halo2_pk_path, default_agg_stark_pk_path, default_asm_path,
+        default_evm_halo2_verifier_path, default_params_dir,
+    },
+    util::read_default_agg_pk,
 };
 
 #[derive(Parser)]
@@ -26,57 +31,100 @@ use crate::default::{
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --evm to also generate proving keys for EVM verifier"
+    )]
+    pub evm: bool,
+    #[arg(
+        long,
+        default_value = "false",
+        help = "force keygen even if the proving keys already exist"
+    )]
+    pub force_agg_keygen: bool,
+}
 
 impl EvmProvingSetupCmd {
     pub async fn run(&self) -> Result<()> {
-        let default_agg_pk_path = default_agg_pk_path();
+        let default_agg_stark_pk_path = default_agg_stark_pk_path();
         let default_params_dir = default_params_dir();
         let default_evm_halo2_verifier_path = default_evm_halo2_verifier_path();
+        let default_asm_path = default_asm_path();
+        if !self.evm {
+            if PathBuf::from(&default_agg_stark_pk_path).exists() {
+                println!("Aggregation stark proving key already exists");
+                return Ok(());
+            }
+            let agg_stark_config = AggStarkConfig::default();
+            let sdk = Sdk::new();
+            let agg_stark_pk = sdk.agg_stark_keygen(agg_stark_config)?;
+
+            println!("Writing stark proving key to file...");
+            write_agg_stark_pk_to_file(&agg_stark_pk, default_agg_stark_pk_path)?;
+
+            println!("Generating root verifier ASM...");
+            let root_verifier_asm = sdk.generate_root_verifier_asm(&agg_stark_pk);
+
+            println!("Writing root verifier ASM to file...");
+            write(&default_asm_path, root_verifier_asm)?;
+        } else {
+            let default_agg_halo2_pk_path = default_agg_halo2_pk_path();
+            if PathBuf::from(&default_agg_stark_pk_path).exists()
+                && PathBuf::from(&default_agg_halo2_pk_path).exists()
+                && PathBuf::from(&default_evm_halo2_verifier_path)
+                    .join(EVM_HALO2_VERIFIER_PARENT_NAME)
+                    .exists()
+                && PathBuf::from(&default_evm_halo2_verifier_path)
+                    .join(EVM_HALO2_VERIFIER_BASE_NAME)
+                    .exists()
+                && PathBuf::from(&default_evm_halo2_verifier_path)
+                    .join("interfaces")
+                    .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
+                    .exists()
+            {
+                println!("Aggregation proving key and verifier contract already exist");
+                return Ok(());
+            } else if !Self::check_solc_installed() {
+                return Err(eyre!(
+                    "solc is not installed, please install solc to continue"
+                ));
+            }
 
-        if PathBuf::from(&default_agg_pk_path).exists()
-            && PathBuf::from(&default_evm_halo2_verifier_path)
-                .join(EVM_HALO2_VERIFIER_PARENT_NAME)
-                .exists()
-            && PathBuf::from(&default_evm_halo2_verifier_path)
-                .join(EVM_HALO2_VERIFIER_BASE_NAME)
-                .exists()
-            && PathBuf::from(&default_evm_halo2_verifier_path)
-                .join("interfaces")
-                .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
-                .exists()
-        {
-            println!("Aggregation proving key and verifier contract already exist");
-            return Ok(());
-        } else if !Self::check_solc_installed() {
-            return Err(eyre!(
-                "solc is not installed, please install solc to continue"
-            ));
-        }
-
-        Self::download_params(10, 24).await?;
-        let params_reader = CacheHalo2ParamsReader::new(default_params_dir);
-        let agg_config = AggConfig::default();
-        let sdk = Sdk::new();
+            Self::download_params(10, 24).await?;
+            let params_reader = CacheHalo2ParamsReader::new(&default_params_dir);
+            let agg_config = AggConfig::default();
+            let sdk = Sdk::new();
 
-        println!("Generating proving key...");
-        let agg_pk = sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
+            let agg_pk = if !self.force_agg_keygen
+                && PathBuf::from(&default_agg_stark_pk_path).exists()
+                && PathBuf::from(&default_agg_halo2_pk_path).exists()
+            {
+                read_default_agg_pk()?
+            } else {
+                println!("Generating proving key...");
+                sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?
+            };
 
-        println!("Generating root verifier ASM...");
-        let root_verifier_asm = sdk.generate_root_verifier_asm(&agg_pk.agg_stark_pk);
+            println!("Generating root verifier ASM...");
+            let root_verifier_asm = sdk.generate_root_verifier_asm(&agg_pk.agg_stark_pk);
 
-        println!("Generating verifier contract...");
-        let verifier = sdk.generate_halo2_verifier_solidity(&params_reader, &agg_pk)?;
+            println!("Generating verifier contract...");
+            let verifier = sdk.generate_halo2_verifier_solidity(&params_reader, &agg_pk)?;
 
-        println!("Writing proving key to file...");
-        write_agg_pk_to_file(agg_pk, &default_agg_pk_path)?;
+            println!("Writing stark proving key to file...");
+            write_agg_stark_pk_to_file(&agg_pk.agg_stark_pk, &default_agg_stark_pk_path)?;
 
-        println!("Writing root verifier ASM to file...");
-        write(default_asm_path(), root_verifier_asm)?;
+            println!("Writing halo2 proving key to file...");
+            write_agg_halo2_pk_to_file(&agg_pk.halo2_pk, &default_agg_halo2_pk_path)?;
 
-        println!("Writing verifier contract to file...");
-        write_evm_halo2_verifier_to_folder(verifier, &default_evm_halo2_verifier_path)?;
+            println!("Writing root verifier ASM to file...");
+            write(&default_asm_path, root_verifier_asm)?;
 
+            println!("Writing verifier contract to file...");
+            write_evm_halo2_verifier_to_folder(verifier, &default_evm_halo2_verifier_path)?;
+        }
         Ok(())
     }
 
diff --git a/crates/cli/src/default.rs b/crates/cli/src/default.rs
index 224d3dc219..641c74b8ea 100644
--- a/crates/cli/src/default.rs
+++ b/crates/cli/src/default.rs
@@ -7,15 +7,18 @@ pub const DEFAULT_MANIFEST_DIR: &str = ".";
 
 pub const DEFAULT_APP_CONFIG_PATH: &str = "./openvm.toml";
 pub const DEFAULT_APP_EXE_PATH: &str = "./openvm/app.vmexe";
-pub const DEFAULT_EXE_COMMIT_PATH: &str = "./openvm/exe_commit.bytes";
 pub const DEFAULT_COMMITTED_APP_EXE_PATH: &str = "./openvm/committed_app_exe.bc";
 pub const DEFAULT_APP_PK_PATH: &str = "./openvm/app.pk";
 pub const DEFAULT_APP_VK_PATH: &str = "./openvm/app.vk";
 pub const DEFAULT_APP_PROOF_PATH: &str = "./openvm/app.proof";
 pub const DEFAULT_EVM_PROOF_PATH: &str = "./openvm/evm.proof";
 
-pub fn default_agg_pk_path() -> String {
-    env::var("HOME").unwrap() + "/.openvm/agg.pk"
+pub fn default_agg_stark_pk_path() -> String {
+    env::var("HOME").unwrap() + "/.openvm/agg_stark.pk"
+}
+
+pub fn default_agg_halo2_pk_path() -> String {
+    env::var("HOME").unwrap() + "/.openvm/agg_halo2.pk"
 }
 
 pub fn default_asm_path() -> String {
diff --git a/crates/cli/src/util.rs b/crates/cli/src/util.rs
index 8db24aa89e..aa4eaceba4 100644
--- a/crates/cli/src/util.rs
+++ b/crates/cli/src/util.rs
@@ -4,29 +4,42 @@ use std::{
 };
 
 use eyre::Result;
-use openvm_sdk::config::{AppConfig, SdkVmConfig};
+use openvm_sdk::{
+    config::{AppConfig, SdkVmConfig},
+    fs::{read_agg_halo2_pk_from_file, read_agg_stark_pk_from_file},
+    keygen::AggProvingKey,
+};
 use serde::de::DeserializeOwned;
 
-use crate::default::default_app_config;
+use crate::default::{default_agg_halo2_pk_path, default_agg_stark_pk_path, default_app_config};
 
-pub(crate) fn read_to_struct_toml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
-    let toml = read_to_string(path.as_ref() as &Path)?;
+pub(crate) fn read_to_struct_toml<T: DeserializeOwned>(path: impl AsRef<Path>) -> Result<T> {
+    let toml = read_to_string(path)?;
     let ret = toml::from_str(&toml)?;
     Ok(ret)
 }
 
-pub fn read_config_toml_or_default(config: &PathBuf) -> Result<AppConfig<SdkVmConfig>> {
-    if config.exists() {
+pub fn read_config_toml_or_default(config: impl AsRef<Path>) -> Result<AppConfig<SdkVmConfig>> {
+    if config.as_ref().exists() {
         read_to_struct_toml(config)
     } else {
         println!(
             "{:?} not found, using default application configuration",
-            config
+            config.as_ref()
         );
         Ok(default_app_config())
     }
 }
 
+pub fn read_default_agg_pk() -> Result<AggProvingKey> {
+    let agg_stark_pk = read_agg_stark_pk_from_file(default_agg_stark_pk_path())?;
+    let halo2_pk = read_agg_halo2_pk_from_file(default_agg_halo2_pk_path())?;
+    Ok(AggProvingKey {
+        agg_stark_pk,
+        halo2_pk,
+    })
+}
+
 pub fn find_manifest_dir(mut current_dir: PathBuf) -> Result<PathBuf> {
     current_dir = current_dir.canonicalize()?;
     while !current_dir.join("Cargo.toml").exists() {
diff --git a/crates/cli/tests/build.rs b/crates/cli/tests/build.rs
index 1037d07e2d..42d3f09ee6 100644
--- a/crates/cli/tests/build.rs
+++ b/crates/cli/tests/build.rs
@@ -2,7 +2,7 @@ use std::path::PathBuf;
 
 use cargo_openvm::{
     commands::{build, BuildArgs, BuildCargoArgs},
-    default::{DEFAULT_APP_EXE_PATH, DEFAULT_COMMITTED_APP_EXE_PATH, DEFAULT_EXE_COMMIT_PATH},
+    default::{DEFAULT_APP_EXE_PATH, DEFAULT_COMMITTED_APP_EXE_PATH},
 };
 use eyre::Result;
 use openvm_build::RUSTC_TARGET;
@@ -18,7 +18,6 @@ fn default_build_args(example: &str) -> BuildArgs {
             .join("openvm.toml"),
         exe_output: PathBuf::from(DEFAULT_APP_EXE_PATH),
         committed_exe_output: PathBuf::from(DEFAULT_COMMITTED_APP_EXE_PATH),
-        exe_commit_output: PathBuf::from(DEFAULT_EXE_COMMIT_PATH),
         init_file_name: OPENVM_DEFAULT_INIT_FILE_NAME.to_string(),
     }
 }
diff --git a/crates/sdk/src/commit.rs b/crates/sdk/src/commit.rs
index 931d44e4b3..4a9a43a9b9 100644
--- a/crates/sdk/src/commit.rs
+++ b/crates/sdk/src/commit.rs
@@ -85,7 +85,3 @@ pub fn commit_app_exe(
     let app_engine = BabyBearPoseidon2Engine::new(app_fri_params);
     Arc::new(VmCommittedExe::<SC>::commit(exe, app_engine.config.pcs()))
 }
-
-pub fn committed_exe_as_bn254(committed_exe: &NonRootCommittedExe) -> Bn254Fr {
-    babybear_digest_to_bn254(&committed_exe.get_program_commit().into())
-}
diff --git a/crates/sdk/src/fs.rs b/crates/sdk/src/fs.rs
index e2b11075bd..d212a899f1 100644
--- a/crates/sdk/src/fs.rs
+++ b/crates/sdk/src/fs.rs
@@ -11,7 +11,7 @@ use serde::{de::DeserializeOwned, Serialize};
 
 use crate::{
     codec::{Decode, Encode},
-    keygen::{AggProvingKey, AppProvingKey, AppVerifyingKey},
+    keygen::{AggStarkProvingKey, AppProvingKey, AppVerifyingKey, Halo2ProvingKey},
     types::{EvmHalo2Verifier, EvmProof},
     F, OPENVM_VERSION, SC,
 };
@@ -74,12 +74,19 @@ pub fn write_root_verifier_input_to_file<P: AsRef<Path>>(
     encode_to_file(path, input)
 }
 
-pub fn read_agg_pk_from_file<P: AsRef<Path>>(path: P) -> Result<AggProvingKey> {
+pub fn read_agg_stark_pk_from_file<P: AsRef<Path>>(path: P) -> Result<AggStarkProvingKey> {
     read_from_file_bitcode(path)
 }
+pub fn read_agg_halo2_pk_from_file<P: AsRef<Path>>(path: P) -> Result<Halo2ProvingKey> {
+    read_from_file_bitcode(path)
+}
+
+pub fn write_agg_halo2_pk_to_file<P: AsRef<Path>>(pk: &Halo2ProvingKey, path: P) -> Result<()> {
+    write_to_file_bitcode(path, pk)
+}
 
-pub fn write_agg_pk_to_file<P: AsRef<Path>>(agg_pk: AggProvingKey, path: P) -> Result<()> {
-    write_to_file_bitcode(path, agg_pk)
+pub fn write_agg_stark_pk_to_file<P: AsRef<Path>>(pk: &AggStarkProvingKey, path: P) -> Result<()> {
+    write_to_file_bitcode(path, pk)
 }
 
 pub fn read_evm_proof_from_file<P: AsRef<Path>>(path: P) -> Result<EvmProof> {


Reviews:
user: login: stephenh-axiom-xyz
body: Left a few comments, am overall OK with everything but want to iron out some details before approving. Thanks for the change!!
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T15:35:41Z
user: login: jonathanpwang
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T16:59:40Z
user: login: jonathanpwang
body: lgtm but address @stephenh-axiom-xyz 's comments

also I don't like `--stark-only` flag and it's better if `evm` setup is opt in
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T17:00:23Z
user: login: nyunyunyunyu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T20:19:31Z
user: login: jonathanpwang
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T21:23:40Z
user: login: nyunyunyunyu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T22:19:10Z
user: login: nyunyunyunyu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T22:19:27Z
user: login: nyunyunyunyu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T22:19:48Z
user: login: nyunyunyunyu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T23:09:02Z

Review comments:
diff_hunk: @@ -163,13 +164,20 @@ pub(crate) fn build(build_args: &BuildArgs) -> Result<Option<PathBuf>> {
         let committed_exe = commit_app_exe(app_config.app_fri_params.fri_params, exe.clone());
         write_exe_to_file(exe, output_path)?;
 
+        let app_pk = AppProvingKey::keygen(app_config.clone());
path: crates/cli/src/commands/build.rs
user: login: stephenh-axiom-xyz
body: Should `app_pk` be written to a file? I think it might be good to have `cargo openvm build` run `cargo openvm keygen` first if a proving key isn't present, similarly to how `cargo run` does a `cargo build` first. It seems like you already moved the `cargo openvm keygen` functionality to a crate-visible function below.
created_at: 2025-05-14T15:23:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
+}
 
 impl EvmProvingSetupCmd {
     pub async fn run(&self) -> Result<()> {
-        if PathBuf::from(DEFAULT_AGG_PK_PATH).exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join(EVM_HALO2_VERIFIER_PARENT_NAME)
-                .exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join(EVM_HALO2_VERIFIER_BASE_NAME)
-                .exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join("interfaces")
-                .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
-                .exists()
-        {
-            println!("Aggregation proving key and verifier contract already exist");
-            return Ok(());
-        } else if !Self::check_solc_installed() {
-            return Err(eyre!(
-                "solc is not installed, please install solc to continue"
-            ));
-        }
+        if self.stark_only {
+            if PathBuf::from(DEFAULT_AGG_STARK_PK_PATH).exists() {
+                println!("Aggregation stark proving key already exists");
+                return Ok(());
+            }
+            let agg_stark_config = AggStarkConfig::default();
+            let sdk = Sdk::new();
+            let agg_stark_pk = sdk.agg_stark_keygen(agg_stark_config)?;
+
+            println!("Writing stark proving key to file...");
+            write_agg_stark_pk_to_file(&agg_stark_pk, DEFAULT_AGG_STARK_PK_PATH)?;
+
+            println!("Generating root verifier ASM...");
+            let root_verifier_asm = sdk.generate_root_verifier_asm(&agg_stark_pk);
+
+            println!("Writing root verifier ASM to file...");
+            write(DEFAULT_ASM_PATH, root_verifier_asm)?;
+        } else {
+            if PathBuf::from(DEFAULT_AGG_STARK_PK_PATH).exists()
+                && PathBuf::from(DEFAULT_AGG_HALO2_PK_PATH).exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join(EVM_HALO2_VERIFIER_PARENT_NAME)
+                    .exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join(EVM_HALO2_VERIFIER_BASE_NAME)
+                    .exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join("interfaces")
+                    .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
+                    .exists()
+            {
+                println!("Aggregation proving key and verifier contract already exist");
+                return Ok(());
+            } else if !Self::check_solc_installed() {
+                return Err(eyre!(
+                    "solc is not installed, please install solc to continue"
+                ));
+            }
 
-        Self::download_params(10, 24).await?;
-        let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
-        let agg_config = AggConfig::default();
-        let sdk = Sdk::new();
+            Self::download_params(10, 24).await?;
+            let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
+            let agg_config = AggConfig::default();
+            let sdk = Sdk::new();
 
-        println!("Generating proving key...");
-        let agg_pk = sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
+            println!("Generating proving key...");
+            let agg_pk =
+                sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
path: crates/cli/src/commands/setup.rs
user: login: stephenh-axiom-xyz
body: Would it be worthwhile to check if the aggregation proving key already exists before calling `agg_keygen`? If I remember correctly this takes a lot of time and resources, and I can imagine a scenario where `cargo openvm setup` being interrupted halfway could be quite frustrating.

If we do go ahead with this though, we should probably add an option `--force-agg-keygen` or something as an override.
created_at: 2025-05-14T15:30:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -163,13 +164,20 @@ pub(crate) fn build(build_args: &BuildArgs) -> Result<Option<PathBuf>> {
         let committed_exe = commit_app_exe(app_config.app_fri_params.fri_params, exe.clone());
         write_exe_to_file(exe, output_path)?;
 
+        let app_pk = AppProvingKey::keygen(app_config.clone());
+        let app_exe_commit = AppExecutionCommit::compute(
+            &app_config.app_vm_config,
+            &committed_exe,
+            &app_pk.leaf_committed_exe,
+        );
         if let Some(parent) = build_args.exe_commit_output.parent() {
             create_dir_all(parent)?;
         }
-        write(
-            &build_args.exe_commit_output,
-            committed_exe_as_bn254(&committed_exe).value.to_bytes(),
+        serde_json::to_writer_pretty(
+            File::create(&build_args.exe_commit_output)?,
+            &app_exe_commit,
path: crates/cli/src/commands/build.rs
user: login: stephenh-axiom-xyz
body: Just want to confirm that whatever functions we have that will eventually read `exe_commit_output` will be able to read the JSON
created_at: 2025-05-14T15:35:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
path: crates/cli/src/commands/setup.rs
user: login: jonathanpwang
body: this is weird, I feel the cmd should be `setup` and `setup evm`, or `setup stark` and `setup evm`. I feel it's better if flags give additive behavior
created_at: 2025-05-15T16:59:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
path: crates/cli/src/commands/setup.rs
user: login: nyunyunyunyu
body: `setup stark` is a subset of `setup evm`. That's why I prefer a flag
created_at: 2025-05-15T20:19:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
path: crates/cli/src/commands/setup.rs
user: login: jonathanpwang
body: then I feel like it should be `setup` defaults to `stark` and `setup --evm` adds evm?
created_at: 2025-05-15T21:23:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -163,13 +164,20 @@ pub(crate) fn build(build_args: &BuildArgs) -> Result<Option<PathBuf>> {
         let committed_exe = commit_app_exe(app_config.app_fri_params.fri_params, exe.clone());
         write_exe_to_file(exe, output_path)?;
 
+        let app_pk = AppProvingKey::keygen(app_config.clone());
path: crates/cli/src/commands/build.rs
user: login: nyunyunyunyu
body: Discussed offline. Removed the commit json for now.
created_at: 2025-05-15T22:19:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
+}
 
 impl EvmProvingSetupCmd {
     pub async fn run(&self) -> Result<()> {
-        if PathBuf::from(DEFAULT_AGG_PK_PATH).exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join(EVM_HALO2_VERIFIER_PARENT_NAME)
-                .exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join(EVM_HALO2_VERIFIER_BASE_NAME)
-                .exists()
-            && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
-                .join("interfaces")
-                .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
-                .exists()
-        {
-            println!("Aggregation proving key and verifier contract already exist");
-            return Ok(());
-        } else if !Self::check_solc_installed() {
-            return Err(eyre!(
-                "solc is not installed, please install solc to continue"
-            ));
-        }
+        if self.stark_only {
+            if PathBuf::from(DEFAULT_AGG_STARK_PK_PATH).exists() {
+                println!("Aggregation stark proving key already exists");
+                return Ok(());
+            }
+            let agg_stark_config = AggStarkConfig::default();
+            let sdk = Sdk::new();
+            let agg_stark_pk = sdk.agg_stark_keygen(agg_stark_config)?;
+
+            println!("Writing stark proving key to file...");
+            write_agg_stark_pk_to_file(&agg_stark_pk, DEFAULT_AGG_STARK_PK_PATH)?;
+
+            println!("Generating root verifier ASM...");
+            let root_verifier_asm = sdk.generate_root_verifier_asm(&agg_stark_pk);
+
+            println!("Writing root verifier ASM to file...");
+            write(DEFAULT_ASM_PATH, root_verifier_asm)?;
+        } else {
+            if PathBuf::from(DEFAULT_AGG_STARK_PK_PATH).exists()
+                && PathBuf::from(DEFAULT_AGG_HALO2_PK_PATH).exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join(EVM_HALO2_VERIFIER_PARENT_NAME)
+                    .exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join(EVM_HALO2_VERIFIER_BASE_NAME)
+                    .exists()
+                && PathBuf::from(DEFAULT_EVM_HALO2_VERIFIER_PATH)
+                    .join("interfaces")
+                    .join(EVM_HALO2_VERIFIER_INTERFACE_NAME)
+                    .exists()
+            {
+                println!("Aggregation proving key and verifier contract already exist");
+                return Ok(());
+            } else if !Self::check_solc_installed() {
+                return Err(eyre!(
+                    "solc is not installed, please install solc to continue"
+                ));
+            }
 
-        Self::download_params(10, 24).await?;
-        let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
-        let agg_config = AggConfig::default();
-        let sdk = Sdk::new();
+            Self::download_params(10, 24).await?;
+            let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
+            let agg_config = AggConfig::default();
+            let sdk = Sdk::new();
 
-        println!("Generating proving key...");
-        let agg_pk = sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
+            println!("Generating proving key...");
+            let agg_pk =
+                sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
path: crates/cli/src/commands/setup.rs
user: login: nyunyunyunyu
body: The current implementation requires a dummy proof. It's non-trivial to just generate the dummy proof without keygen.. Added `--force-agg-keygen`
created_at: 2025-05-15T22:19:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -163,13 +164,20 @@ pub(crate) fn build(build_args: &BuildArgs) -> Result<Option<PathBuf>> {
         let committed_exe = commit_app_exe(app_config.app_fri_params.fri_params, exe.clone());
         write_exe_to_file(exe, output_path)?;
 
+        let app_pk = AppProvingKey::keygen(app_config.clone());
+        let app_exe_commit = AppExecutionCommit::compute(
+            &app_config.app_vm_config,
+            &committed_exe,
+            &app_pk.leaf_committed_exe,
+        );
         if let Some(parent) = build_args.exe_commit_output.parent() {
             create_dir_all(parent)?;
         }
-        write(
-            &build_args.exe_commit_output,
-            committed_exe_as_bn254(&committed_exe).value.to_bytes(),
+        serde_json::to_writer_pretty(
+            File::create(&build_args.exe_commit_output)?,
+            &app_exe_commit,
path: crates/cli/src/commands/build.rs
user: login: nyunyunyunyu
body: Discussed offline. Remove this logic for now.
created_at: 2025-05-15T22:19:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,70 +9,102 @@ use clap::Parser;
 use eyre::{eyre, Result};
 use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
 use openvm_sdk::{
-    config::AggConfig,
+    config::{AggConfig, AggStarkConfig},
     fs::{
-        write_agg_pk_to_file, write_evm_halo2_verifier_to_folder, EVM_HALO2_VERIFIER_BASE_NAME,
-        EVM_HALO2_VERIFIER_INTERFACE_NAME, EVM_HALO2_VERIFIER_PARENT_NAME,
+        write_agg_halo2_pk_to_file, write_agg_stark_pk_to_file, write_evm_halo2_verifier_to_folder,
+        EVM_HALO2_VERIFIER_BASE_NAME, EVM_HALO2_VERIFIER_INTERFACE_NAME,
+        EVM_HALO2_VERIFIER_PARENT_NAME,
     },
     DefaultStaticVerifierPvHandler, Sdk,
 };
 
 use crate::default::{
-    DEFAULT_AGG_PK_PATH, DEFAULT_ASM_PATH, DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
+    DEFAULT_AGG_HALO2_PK_PATH, DEFAULT_AGG_STARK_PK_PATH, DEFAULT_ASM_PATH,
+    DEFAULT_EVM_HALO2_VERIFIER_PATH, DEFAULT_PARAMS_DIR,
 };
 
 #[derive(Parser)]
 #[command(
     name = "evm-proving-setup",
     about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
 )]
-pub struct EvmProvingSetupCmd {}
+pub struct EvmProvingSetupCmd {
+    #[arg(
+        long,
+        default_value = "false",
+        help = "use --stark_only to only generate stark proving keys"
+    )]
+    pub stark_only: bool,
path: crates/cli/src/commands/setup.rs
user: login: nyunyunyunyu
body: sg. done
created_at: 2025-05-15T23:09:02Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-14T01:00:10Z
body: <!--Benchmark Results-->
| group | app.proof_time_ms | app.cycles | app.cells_used | leaf.proof_time_ms | leaf.cycles | leaf.cells_used |
| -- | -- | -- | -- | -- | -- | -- |
| [verify_fibair](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/verify_fibair-251c8e396f2b7f712ae67d7b58b8985b703cfbab.md) |<span style='color: green'>(-14 [-1.2%])</span> 1,192 |  334,008 |  17,675,690 |- | - | - |
| [fibonacci](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/fibonacci-251c8e396f2b7f712ae67d7b58b8985b703cfbab.md) |<span style='color: green'>(-25 [-1.0%])</span> 2,444 |  1,500,277 |  50,589,503 |- | - | - |
| [regex](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/regex-251c8e396f2b7f712ae67d7b58b8985b703cfbab.md) |<span style='color: green'>(-72 [-1.0%])</span> 7,408 |  4,165,226 |  166,511,152 |- | - | - |
| [ecrecover](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/ecrecover-251c8e396f2b7f712ae67d7b58b8985b703cfbab.md) |<span style='color: green'>(-52 [-3.8%])</span> 1,334 |  289,447 |  14,470,186 |- | - | - |
| [pairing](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/pairing-251c8e396f2b7f712ae67d7b58b8985b703cfbab.md) | 4,574 |  1,820,436 |  95,832,407 |- | - | - |


Commit: https://github.com/openvm-org/openvm/commit/251c8e396f2b7f712ae67d7b58b8985b703cfbab

[Benchmark Workflow](https://github.com/openvm-org/openvm/actions/runs/15009783911)

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-14T01:08:23Z
body: <!--Benchmark Results-->
| group | app.proof_time_ms | app.cycles | app.cells_used | leaf.proof_time_ms | leaf.cycles | leaf.cells_used |
| -- | -- | -- | -- | -- | -- | -- |
| [verify_fibair](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/verify_fibair-851ca1f22d0dd6b35413c5cf803e86c632bafd6f.md) |<span style='color: green'>(-17 [-1.4%])</span> 1,189 |  334,043 |  17,676,110 |- | - | - |
| [fibonacci](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/fibonacci-851ca1f22d0dd6b35413c5cf803e86c632bafd6f.md) |<span style='color: red'>(+39 [+1.6%])</span> 2,508 |  1,500,277 |  50,589,503 |- | - | - |
| [regex](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/regex-851ca1f22d0dd6b35413c5cf803e86c632bafd6f.md) | 7,481 |  4,165,226 |  166,511,152 |- | - | - |
| [ecrecover](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/ecrecover-851ca1f22d0dd6b35413c5cf803e86c632bafd6f.md) |<span style='color: green'>(-36 [-2.6%])</span> 1,350 |  289,447 |  14,470,186 |- | - | - |
| [pairing](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/pairing-851ca1f22d0dd6b35413c5cf803e86c632bafd6f.md) |<span style='color: red'>(+20 [+0.4%])</span> 4,592 |  1,820,436 |  95,832,407 |- | - | - |


Commit: https://github.com/openvm-org/openvm/commit/851ca1f22d0dd6b35413c5cf803e86c632bafd6f

[Benchmark Workflow](https://github.com/openvm-org/openvm/actions/runs/15009885027)

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-15T22:28:17Z
body: <!--Benchmark Results-->
| group | app.proof_time_ms | app.cycles | app.cells_used | leaf.proof_time_ms | leaf.cycles | leaf.cells_used |
| -- | -- | -- | -- | -- | -- | -- |
| [verify_fibair](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/verify_fibair-cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18.md) |<span style='color: green'>(-62 [-5.1%])</span> 1,144 |  334,008 |  17,675,690 |- | - | - |
| [fibonacci](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/fibonacci-cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18.md) |<span style='color: red'>(+6 [+0.2%])</span> 2,475 |  1,500,277 |  50,589,503 |- | - | - |
| [regex](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/regex-cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18.md) |<span style='color: green'>(-80 [-1.1%])</span> 7,400 |  4,165,226 |  166,511,152 |- | - | - |
| [ecrecover](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/ecrecover-cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18.md) |<span style='color: green'>(-44 [-3.2%])</span> 1,342 |  289,447 |  14,470,186 |- | - | - |
| [pairing](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/pairing-cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18.md) |<span style='color: green'>(-26 [-0.6%])</span> 4,546 |  1,820,436 |  95,832,407 |- | - | - |


Commit: https://github.com/openvm-org/openvm/commit/cf0bc8fb3fc2bb6521b5cfffd9c0536e3c9c0e18

[Benchmark Workflow](https://github.com/openvm-org/openvm/actions/runs/15056317122)

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-15T23:14:52Z
body: <!--Benchmark Results-->
| group | app.proof_time_ms | app.cycles | app.cells_used | leaf.proof_time_ms | leaf.cycles | leaf.cells_used |
| -- | -- | -- | -- | -- | -- | -- |
| [verify_fibair](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/verify_fibair-18e2b964d1c37586eea28da9cbcd306be6f70cd5.md) |<span style='color: green'>(-38 [-3.2%])</span> 1,168 |  334,067 |  17,676,398 |- | - | - |
| [fibonacci](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/fibonacci-18e2b964d1c37586eea28da9cbcd306be6f70cd5.md) |<span style='color: red'>(+42 [+1.7%])</span> 2,511 |  1,500,277 |  50,589,503 |- | - | - |
| [regex](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/regex-18e2b964d1c37586eea28da9cbcd306be6f70cd5.md) | 7,480 |  4,165,226 |  166,511,152 |- | - | - |
| [ecrecover](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/ecrecover-18e2b964d1c37586eea28da9cbcd306be6f70cd5.md) |<span style='color: red'>(+11 [+0.8%])</span> 1,397 | <span style='color: red'>(+20412 [+7.1%])</span> 309,859 | <span style='color: red'>(+672913 [+4.7%])</span> 15,143,099 |- | - | - |
| [pairing](https://github.com/openvm-org/openvm/blob/benchmark-results/benchmarks-pr/1649/pairing-18e2b964d1c37586eea28da9cbcd306be6f70cd5.md) |<span style='color: red'>(+53 [+1.2%])</span> 4,625 | <span style='color: red'>(+36796 [+2.0%])</span> 1,857,232 | <span style='color: red'>(+1223114 [+1.3%])</span> 97,055,521 |- | - | - |


Commit: https://github.com/openvm-org/openvm/commit/18e2b964d1c37586eea28da9cbcd306be6f70cd5

[Benchmark Workflow](https://github.com/openvm-org/openvm/actions/runs/15056915210)

author_association: NONE