From 36a1fd9b9b74df593f14d6a64ce3f35bdd3d057f Mon Sep 17 00:00:00 2001 From: Yu Jiang Tham Date: Fri, 3 Jan 2025 11:54:16 -0500 Subject: [PATCH] Address PR comments, update flow a bit --- book/src/SUMMARY.md | 4 +- book/src/advanced-usage/sdk.md | 118 +++++++++++++++++++++++ book/src/advanced-usage/sdk/app-proof.md | 53 ---------- book/src/advanced-usage/sdk/evm-proof.md | 72 -------------- book/src/advanced-usage/sdk/index.md | 20 ---- crates/sdk/examples/sdk_evm.rs | 22 ++--- 6 files changed, 128 insertions(+), 161 deletions(-) create mode 100644 book/src/advanced-usage/sdk.md delete mode 100644 book/src/advanced-usage/sdk/app-proof.md delete mode 100644 book/src/advanced-usage/sdk/evm-proof.md delete mode 100644 book/src/advanced-usage/sdk/index.md diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index a10e3c5fec..71d40b5535 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -28,7 +28,5 @@ # Advanced Usage -- [SDK](./advanced-usage/sdk/index.md) - - [App Proof Generation and Verification](./advanced-usage/sdk/app-proof.md) - - [EVM Proof Generation and Verification](./advanced-usage/sdk/evm-proof.md) +- [SDK](./advanced-usage/sdk.md) - [Creating a New Extension](./advanced-usage/new-extension.md) diff --git a/book/src/advanced-usage/sdk.md b/book/src/advanced-usage/sdk.md new file mode 100644 index 0000000000..9b8a2629eb --- /dev/null +++ b/book/src/advanced-usage/sdk.md @@ -0,0 +1,118 @@ +# Using the SDK + +While the CLI provides a convenient way to build, prove, and verify programs, you may want more fine-grained control over the process. The OpenVM Rust SDK allows you to customize various aspects of the workflow programmatically. + +For more information on the basic CLI flow, see [Overview of Basic Usage](../../writing-apps/overview.md). Writing a guest program is the same as in the CLI. + +## Imports and Setup + +If you have a guest program and would like to try running the **host program** specified in the next section, you can do so by adding the following imports and setup at the top of the file. You may need to modify the imports and/or the `SomeStruct` struct to match your program. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:dependencies }} +``` + +## Building and Transpiling a Program + +The SDK provides lower-level control over the building and transpiling process. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:build }} +{{ #include ../../../crates/sdk/examples/sdk_app.rs:read_elf}} + +{{ #include ../../../crates/sdk/examples/sdk_app.rs:transpilation }} +``` + +### Using `SdkVmConfig` + +The `SdkVmConfig` struct allows you to specify the extensions and system configuration your VM will use. To customize your own configuration, you can use the `SdkVmConfig::builder()` method and set the extensions and system configuration you want. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:vm_config }} +``` + +## Running a Program + +To run your program and see the public value output, you can do the following: + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:execution }} +``` + +### Using `StdIn` + +The `StdIn` struct allows you to format any serializable type into a VM-readable format by passing in a reference to your struct into `StdIn::write` as above. You also have the option to pass in a `&[u8]` into `StdIn::write_bytes`, or a `&[F]` into `StdIn::write_field` where `F` is the `openvm_stark_sdk::p3_baby_bear::BabyBear` field type. + +> **Generating CLI Bytes** +> To get the VM byte representation of a serializable struct `data` (i.e. for use in the CLI), you can print out the result of `openvm::serde::to_vec(data).unwrap()` in a Rust host program. + +## Generating and Verifying Proofs + +There are two types of proofs that you can generate, with the sections below continuing from this point. + +- [App Proof](#app-proof): Generates a STARK proof of the guest program +- [EVM Proof](#evm-proof): Generates a halo2 proof that can be posted on-chain + +## App Proof + +### Generating App Proofs + +After building and transpiling a program, you can then generate a proof. To do so, you need to commit your `VmExe`, generate an `AppProvingKey`, format your input into `StdIn`, and then generate a proof. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:proof_generation }} +``` + +### Verifying App Proofs + +After generating a proof, you can verify it. To do so, you need your verifying key (which you can get from your `AppProvingKey`) and the output of your `generate_app_proof` call. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:verification }} +``` + +## EVM Proof + +### Setup + +To generate an EVM proof, you'll first need to ensure that you have followed the [CLI installation steps](../../getting-started/install.md). get the appropraite KZG params by running the following command. + +```bash +cargo openvm setup +``` + +> ⚠️ **WARNING** +> Generating an EVM proof will require a substantial amount of computation and memory. If you have run `cargo openvm setup` and don't need a specialized aggregation configuration, consider deserializing the proving key from the file `~/.openvm/agg.pk` instead of generating it. + +> ⚠️ **WARNING** +> `cargo openvm setup` requires very large amounts of computation and memory (~200 GB). + +
+Also note that there are additional dependncies for the EVM Proof flow. Click here to show. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_app.rs:dependencies }} +``` + +
+ +### Keygen + +Now, you'll still need to generate the app proving key for the next step. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_evm.rs:keygen }} +``` + +### EVM Proof Generation and Verification + +You can now run the aggregation keygen, proof, and verification functions for the EVM proof. Note, you **do not** need to generate the app proof `generate_app_proof` with, as the EVM proof function will handle this automatically. + +```rust,no_run,noplayground +{{ #include ../../../crates/sdk/examples/sdk_evm.rs:evm_verification }} +``` + +> ⚠️ **WARNING** +> The aggregation proving key `agg_pk` above is large. Avoid cloning it if possible. + +Note that `DEFAULT_PARAMS_DIR` is the directory where Halo2 parameters are stored by the `cargo openvm setup` CLI command. For more information on the setup process, see the `EVM Level` section of the [verify](../../writing-apps/verify.md) doc. diff --git a/book/src/advanced-usage/sdk/app-proof.md b/book/src/advanced-usage/sdk/app-proof.md deleted file mode 100644 index 83a3d1f5eb..0000000000 --- a/book/src/advanced-usage/sdk/app-proof.md +++ /dev/null @@ -1,53 +0,0 @@ -# App Proof Generation and Verification - -To generate an app proof using the SDK, follow the steps below. - -## Building and Transpiling a Program - -The SDK provides lower-level control over the building and transpiling process. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:build }} -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:read_elf}} - -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:transpilation }} -``` - -### Using `SdkVmConfig` - -The `SdkVmConfig` struct allows you to specify the extensions and system configuration your VM will use. To customize your own configuration, you can use the `SdkVmConfig::builder()` method and set the extensions and system configuration you want. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:vm_config }} -``` - -## Running a Program - -To run your program and see the public value output, you can do the following: - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:execution }} -``` - -### Using `StdIn` - -The `StdIn` struct allows you to format any serializable type into a VM-readable format by passing in a reference to your struct into `StdIn::write` as above. You also have the option to pass in a `&[u8]` into `StdIn::write_bytes`, or a `&[F]` into `StdIn::write_field` where `F` is the `openvm_stark_sdk::p3_baby_bear::BabyBear` field type. - -> **Generating CLI Bytes** -> To get the VM byte representation of a serializable struct `data` (i.e. for use in the CLI), you can print out the result of `openvm::serde::to_vec(data).unwrap()` in a Rust host program. - -## Generating App Proofs - -After building and transpiling a program, you can then generate a proof. To do so, you need to commit your `VmExe`, generate an `AppProvingKey`, format your input into `StdIn`, and then generate a proof. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:proof_generation }} -``` - -## Verifying App Proofs - -After generating a proof, you can verify it. To do so, you need your verifying key (which you can get from your `AppProvingKey`) and the output of your `generate_app_proof` call. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:verification }} -``` diff --git a/book/src/advanced-usage/sdk/evm-proof.md b/book/src/advanced-usage/sdk/evm-proof.md deleted file mode 100644 index 6de8ed0eaa..0000000000 --- a/book/src/advanced-usage/sdk/evm-proof.md +++ /dev/null @@ -1,72 +0,0 @@ -# EVM Proof Generation and Verification - -Generating an end-to-end EVM proof that can be used on-chain contains many steps that are similar to previous App Proof section, but we will call some other SDK functions to generate and verify the final EVM proof. - -## Setup - -To generate an EVM proof, you'll first need to ensure that you have followed the [CLI installation steps](../../getting-started/install.md). get the appropraite KZG params by running the following command. - -```bash -cargo openvm setup -``` - -> ⚠️ **WARNING** -> Generating an EVM proof will require a substantial amount of computation and memory. If you have run `cargo openvm setup` and don't need a specialized aggregation configuration, consider deserializing the proving key from the file `~/.openvm/agg.pk` instead of generating it. - -> ⚠️ **WARNING** -> `cargo openvm setup` requires very large amounts of computation and memory (~200 GB). - -## Building and Transpiling a Program - -The SDK provides lower-level control over the building and transpiling process. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:build }} -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:read_elf}} - -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:transpilation }} -``` - -### Using `SdkVmConfig` - -The `SdkVmConfig` struct allows you to specify the extensions and system configuration your VM will use. To customize your own configuration, you can use the `SdkVmConfig::builder()` method and set the extensions and system configuration you want. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:vm_config }} -``` - -## Running a Program - -To run your program and see the public value output, you can do the following: - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:execution }} -``` - -### Using `StdIn` - -The `StdIn` struct allows you to format any serializable type into a VM-readable format by passing in a reference to your struct into `StdIn::write` as above. You also have the option to pass in a `&[u8]` into `StdIn::write_bytes`, or a `&[F]` into `StdIn::write_field` where `F` is the `openvm_stark_sdk::p3_baby_bear::BabyBear` field type. - -> **Generating CLI Bytes** -> To get the VM byte representation of a serializable struct `data` (i.e. for use in the CLI), you can print out the result of `openvm::serde::to_vec(data).unwrap()` in a Rust host program. - -## Generating App Proofs - -After building and transpiling a program, you can then generate a proof. To do so, you need to commit your `VmExe`, generate an `AppProvingKey`, format your input into `StdIn`, and then generate a proof. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:proof_generation }} -``` - -## End-to-end EVM Proof Generation and Verification - -Generating and verifying an EVM proof is an extension of the above process. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_evm.rs:evm_verification }} -``` - -> ⚠️ **WARNING** -> The aggregation proving key `agg_pk` above is large. Avoid cloning it if possible. - -Note that `DEFAULT_PARAMS_DIR` is the directory where Halo2 parameters are stored by the `cargo openvm setup` CLI command. For more information on the setup process, see the `EVM Level` section of the [verify](../../writing-apps/verify.md) doc. diff --git a/book/src/advanced-usage/sdk/index.md b/book/src/advanced-usage/sdk/index.md deleted file mode 100644 index 3813331b90..0000000000 --- a/book/src/advanced-usage/sdk/index.md +++ /dev/null @@ -1,20 +0,0 @@ -# Using the SDK - -While the CLI provides a convenient way to build, prove, and verify programs, you may want more fine-grained control over the process. The OpenVM Rust SDK allows you to customize various aspects of the workflow programmatically. - -For more information on the basic CLI flow, see [Overview of Basic Usage](../../writing-apps/overview.md). Writing a guest program is the same as in the CLI. - -## Imports and Setup - -If you have a guest program and would like to try running the **host program** specified in the next section, you can do so by adding the following imports and setup at the top of the file. You may need to modify the imports and/or the `SomeStruct` struct to match your program. - -```rust,no_run,noplayground -{{ #include ../../../../crates/sdk/examples/sdk_app.rs:dependencies }} -``` - -## Types of Proofs - -The SDK can generate two types of proofs, depending on your specific use case. - -- [App Proof](./app-proof.md): Generates a STARK proof of the guest program -- [EVM Proof](./evm-proof.md): Generates a halo2 proof that can be posted on-chain diff --git a/crates/sdk/examples/sdk_evm.rs b/crates/sdk/examples/sdk_evm.rs index 973b6c3145..fd4c834d29 100644 --- a/crates/sdk/examples/sdk_evm.rs +++ b/crates/sdk/examples/sdk_evm.rs @@ -69,36 +69,32 @@ fn main() -> Result<(), Box> { let my_input = SomeStruct { a: 1, b: 2 }; // anything that can be serialized let mut stdin = StdIn::default(); stdin.write(&my_input); - - // 5. Run the program - let output = sdk.execute(exe.clone(), vm_config.clone(), stdin.clone())?; - println!("public values output: {:?}", output); // ANCHOR_END: execution - // ANCHOR: proof_generation - // 6. Set app configuration + // ANCHOR: keygen + // 5. Set app configuration let app_log_blowup = 2; let app_fri_params = FriParameters::standard_with_100_bits_conjectured_security(app_log_blowup); let app_config = AppConfig::new(app_fri_params, vm_config); - // 7. Commit the exe + // 6. Commit the exe let app_committed_exe = sdk.commit_app_exe(app_fri_params, exe)?; - // 8. Generate an AppProvingKey + // 7. Generate an AppProvingKey let app_pk = Arc::new(sdk.app_keygen(app_config)?); - // ANCHOR_END: proof_generation + // ANCHOR_END: keygen // ANCHOR: evm_verification - // 9. Generate the aggregation proving key + // 8. Generate the aggregation proving key const DEFAULT_PARAMS_DIR: &str = concat!(env!("HOME"), "/.openvm/params/"); let halo2_params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR); let agg_config = AggConfig::default(); let agg_pk = sdk.agg_keygen(agg_config, &halo2_params_reader)?; - // 10. Generate the SNARK verifier contract + // 9. Generate the SNARK verifier contract let verifier = sdk.generate_snark_verifier_contract(&halo2_params_reader, &agg_pk)?; - // 11. Generate an EVM proof + // 10. Generate an EVM proof let proof = sdk.generate_evm_proof( &halo2_params_reader, app_pk, @@ -107,7 +103,7 @@ fn main() -> Result<(), Box> { stdin, )?; - // 12. Verify the EVM proof + // 11. Verify the EVM proof let success = sdk.verify_evm_proof(&verifier, &proof); assert!(success); // ANCHOR_END: evm_verification