Skip to content

Generating Proofs

Generating a proof using the CLI is simple - first generate a key, then generate your proof. Using command defaults, this looks like:

cargo openvm keygen         # generate proving and verification keys for app proofs
cargo openvm prove app      # generate the app proof
 
cargo openvm setup          # generate proving and verification keys for STARK aggregation
cargo openvm prove stark    # generate the STARK proof
 
cargo openvm setup --evm    # generate proving and verification keys for EVM proofs
cargo openvm prove evm      # generate the EVM proof

Note that if your program takes inputs, you will have to pass them to the cargo openvm prove command using the --input option.

Application Key Generation

The keygen command generates both an application proving and verification key.

cargo openvm keygen --config <path_to_app_config>

Similarly to build, run, and prove, options --manifest-path, --target-dir, and --output-dir are provided.

If --config is not specified, the command will search for openvm.toml in the manifest directory. If the file isn't found, a default configuration will be used.

The proving and verification key will be written to ${target_dir}/openvm/ (and --output-dir if specified).

Generating App Commitments

Once you have built the guest program and generated an app proving key, you can extract commitments to the program binary and the VM configuration using the following CLI command:

cargo openvm commit
    --app-pk <path_to_app_pk>
    --exe <path_to_transpiled_program>

This will generate a *.commit.json file in ${target_dir}/openvm/${profile}/ (and --output-dir if specified) containing:

  • app_exe_commit: A commitment to the OpenVM program binary.
  • app_vm_commit: A commitment to the OpenVM configuration used for the program binary.

These values will be used later when verifying proofs generated by OpenVM for this program.

Note if --app-pk is not provided, the command will search for a proving key at ${target_dir}/openvm/app.pk. If --exe is not provided, the command will call build before generating the commits. Many of the Cargo options available to cargo openvm run are available to commit too, for more information on the available options see Run Flags.

STARK and EVM Key Generation

The setup command generates proving and verification keys for STARK aggregation and EVM proofs.

cargo openvm setup [--evm]

If called without the --evm flag, it will generate keys for the leaf, internal, and root STARK verifiers as detailed in the specs. If called with the --evm flag, it will also generate keys for the static verifier wrapper.

Details on EVM Verification

In addition to generating EVM proving and verification keys, cargo openvm setup --evm also generates a smart contract verifier for EVM chains. Upon a successful run, the command will write the files

  • agg_stark.pk
  • agg_stark.vk
  • root.asm
  • agg_halo2.pk
  • halo2/src/[OPENVM_VERSION]/Halo2Verifier.sol
  • halo2/src/[OPENVM_VERSION]/OpenVmHalo2Verifier.sol
  • halo2/src/[OPENVM_VERSION]/interfaces/IOpenVmHalo2Verifier.sol
  • halo2/src/[OPENVM_VERSION]/verifier.bytecode.json
  • params/

to ~/.openvm/, where ~ is the directory specified by environment variable $HOME and OPENVM_VERSION is the version of OpenVM. Every command that requires these files will look for them in this directory. The smart contract verifier is also available via the OpenVM Solidity SDK for released versions of OpenVM.

The files agg_stark.pk and agg_halo2.pk are the STARK and Halo2 aggregation proving keys necessary to aggregate to a final EVM proof. The file agg_stark.vk is the STARK aggregation verification key. The file root.asm contains instructions to verify STARK proofs. The params directory contains various trusted setup KZG parameters needed to guarantee Halo2's cryptographic security. The OpenVmHalo2Verifier.sol file contains a Solidity contract to verify the final EVM proof. The contract is named OpenVmHalo2Verifier and it implements the IOpenVmHalo2Verifier interface.

IOpenVmHalo2Verifier.sol
interface IOpenVmHalo2Verifier {
    function verify(bytes calldata publicValues, bytes calldata proofData, bytes32 appExeCommit, bytes32 appVmCommit)
        external
        view;
}

In addition, the command outputs a JSON file verifier.bytecode.json of the form

verifier.bytecode.json
{
    "sol_compiler_version": "0.8.19",
    "sol_compiler_options": "..",
    "bytecode": ".."
}

where sol_compiler_version is the Solidity compiler version used to compile the contract (currently 0.8.19), sol_compiler_options are additional compiler options used, and bytecode is the compiled EVM bytecode as a hex string (without the 0x prefix).

Click here to view the download script
#!/bin/bash
 
# Download ~/.openvm setup artifacts
HALO2_DIR="halo2/src/v1.4"
mkdir -p ~/.openvm
mkdir -p ~/.openvm/$HALO2_DIR
mkdir -p ~/.openvm/$HALO2_DIR/interfaces
mkdir -p ~/.openvm/params
 
BASE_URL="https://openvm-public-artifacts-us-east-1.s3.us-east-1.amazonaws.com/v1.4.0"
 
for file in "agg_stark.pk" "agg_stark.vk" "agg_halo2.pk" "root.asm"; do
    URL="$BASE_URL/$file"
    LOCAL=~/.openvm/$file
    wget "$URL" -O "$LOCAL" || curl -L "$URL" -o "$LOCAL"
done
 
for file in "Halo2Verifier.sol" "interfaces/IOpenVmHalo2Verifier.sol" "OpenVmHalo2Verifier.sol" "verifier.bytecode.json"; do
    URL="$BASE_URL/$HALO2_DIR/$file"
    LOCAL=~/.openvm/$HALO2_DIR/$file
    wget "$URL" -O "$LOCAL" || curl -L "$URL" -o "$LOCAL"
done
 
for k in {10..23}; do
    file="kzg_bn254_${k}.srs"
    URL="$BASE_URL/params/$file"
    LOCAL=~/.openvm/params/$file
    wget "$URL" -O "$LOCAL" || curl -L "$URL" -o "$LOCAL"
done

Proof Generation

The prove CLI command, at its core, uses the options below. prove gets access to all of the options that run has (see Running a Program for more information).

cargo openvm prove <app | stark | evm>
    --app-pk <path_to_app_pk>
    --exe <path_to_transpiled_program>
    --input <path_to_input>
    --proof <path_to_proof_output>

If --app-pk is not provided, the command will search for a proving key at ${target_dir}/openvm/app.pk.

If --exe is not provided, the command will call build before generating a proof.

If your program doesn't require inputs, you can (and should) omit the --input flag.

If --proof is not provided then the command will write the proof to ./${bin_name}.<app | stark | evm>.proof by default, where bin_name is the file stem of the executable run.

The app subcommand generates an application-level proof, the stark command generates an aggregated root-level proof, while the evm command generates an end-to-end EVM proof. For more information on aggregation, see the specification. See Verifying EVM Proofs for details on the output format for cargo openvm prove evm.