diff --git a/book/src/advanced-usage/sdk.md b/book/src/advanced-usage/sdk.md
index 5e9ffe32a7..72b748be55 100644
--- a/book/src/advanced-usage/sdk.md
+++ b/book/src/advanced-usage/sdk.md
@@ -6,10 +6,10 @@ For more information on the basic CLI flow, see [Overview of Basic Usage](../wri
## Imports and Setup
-If you have a guest program and would like to try running the **host program** specified below, 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.
+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.rs:dependencies }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:dependencies }}
```
## Building and Transpiling a Program
@@ -17,10 +17,10 @@ If you have a guest program and would like to try running the **host program** s
The SDK provides lower-level control over the building and transpiling process.
```rust,no_run,noplayground
-{{ #include ../../../crates/sdk/examples/sdk.rs:build }}
-{{ #include ../../../crates/sdk/examples/sdk.rs:read_elf}}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:build }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:read_elf}}
-{{ #include ../../../crates/sdk/examples/sdk.rs:transpilation }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:transpilation }}
```
### Using `SdkVmConfig`
@@ -28,7 +28,7 @@ The SDK provides lower-level control over the building and transpiling process.
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.rs:vm_config }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:vm_config }}
```
## Running a Program
@@ -36,47 +36,89 @@ The `SdkVmConfig` struct allows you to specify the extensions and system configu
To run your program and see the public value output, you can do the following:
```rust,no_run,noplayground
-{{ #include ../../../crates/sdk/examples/sdk.rs:execution }}
+{{ #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**
+> **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 Proofs
+## 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 STARK proof(s) 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.rs:proof_generation }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:proof_generation }}
```
-## Verifying Proofs
+For large guest programs, the program will be proved in multiple continuation segments and the returned `proof: ContinuationVmProof` object consists of multiple STARK proofs, one for each segment.
+
+### 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.rs:verification }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:verification }}
```
-## End-to-end EVM Proof Generation and Verification
+## EVM Proof
+
+### Setup
-Generating and verifying an EVM proof is an extension of the above process.
+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**
+>
+> `cargo openvm setup` requires very large amounts of computation and memory (~200 GB).
+
+
+Also note that there are additional dependencies for the EVM Proof flow. Click here to view.
```rust,no_run,noplayground
-{{ #include ../../../crates/sdk/examples/sdk.rs:evm_verification }}
+{{ #include ../../../crates/sdk/examples/sdk_app.rs:dependencies }}
```
-> ⚠️ **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**
-> The aggregation proving key `agg_pk` above is large. Avoid cloning it if possible.
+### Keygen
-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.
+Now, you'll need to generate the app proving key for the next step.
-> ⚠️ **WARNING**
-> `cargo openvm setup` requires very large amounts of computation and memory (~200 GB).
+```rust,no_run,noplayground
+{{ #include ../../../crates/sdk/examples/sdk_evm.rs:keygen }}
+```
+
+> ⚠️ **WARNING**
+>
+> 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, to save computation.
+
+### 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 with the `generate_app_proof` function, 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/crates/sdk/examples/sdk.rs b/crates/sdk/examples/sdk_app.rs
similarity index 78%
rename from crates/sdk/examples/sdk.rs
rename to crates/sdk/examples/sdk_app.rs
index 5c60053764..05a33d56e0 100644
--- a/crates/sdk/examples/sdk.rs
+++ b/crates/sdk/examples/sdk_app.rs
@@ -4,9 +4,8 @@ use std::{fs, sync::Arc};
use eyre::Result;
use openvm::platform::memory::MEM_SIZE;
use openvm_build::GuestOptions;
-use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
use openvm_sdk::{
- config::{AggConfig, AppConfig, SdkVmConfig},
+ config::{AppConfig, SdkVmConfig},
prover::AppProver,
Sdk, StdIn,
};
@@ -102,29 +101,5 @@ fn main() -> Result<(), Box> {
sdk.verify_app_proof(&app_vk, &proof)?;
// ANCHOR_END: verification
- // ANCHOR: evm_verification
- // 11. 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)?;
-
- // 12. Generate the SNARK verifier contract
- let verifier = sdk.generate_snark_verifier_contract(&halo2_params_reader, &agg_pk)?;
-
- // 13. Generate an EVM proof
- let proof = sdk.generate_evm_proof(
- &halo2_params_reader,
- app_pk,
- app_committed_exe,
- agg_pk,
- stdin,
- )?;
-
- // 14. Verify the EVM proof
- let success = sdk.verify_evm_proof(&verifier, &proof);
- assert!(success);
- // ANCHOR_END: evm_verification
-
Ok(())
}
diff --git a/crates/sdk/examples/sdk_evm.rs b/crates/sdk/examples/sdk_evm.rs
new file mode 100644
index 0000000000..24bd6add55
--- /dev/null
+++ b/crates/sdk/examples/sdk_evm.rs
@@ -0,0 +1,112 @@
+// ANCHOR: dependencies
+use std::{fs, sync::Arc};
+
+use eyre::Result;
+use openvm::platform::memory::MEM_SIZE;
+use openvm_build::GuestOptions;
+use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
+use openvm_sdk::{
+ config::{AggConfig, AppConfig, SdkVmConfig},
+ Sdk, StdIn,
+};
+use openvm_stark_sdk::config::FriParameters;
+use openvm_transpiler::elf::Elf;
+use serde::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct SomeStruct {
+ pub a: u64,
+ pub b: u64,
+}
+// ANCHOR_END: dependencies
+
+#[allow(dead_code, unused_variables)]
+fn read_elf() -> Result<(), Box> {
+ // ANCHOR: read_elf
+ // 2b. Load the ELF from a file
+ let elf_bytes = fs::read("your_path_to_elf")?;
+ let elf = Elf::decode(&elf_bytes, MEM_SIZE as u32)?;
+ // ANCHOR_END: read_elf
+ Ok(())
+}
+
+#[allow(unused_variables, unused_doc_comments)]
+fn main() -> Result<(), Box> {
+ // ANCHOR: vm_config
+ let vm_config = SdkVmConfig::builder()
+ .system(Default::default())
+ .rv32i(Default::default())
+ .rv32m(Default::default())
+ .io(Default::default())
+ .build();
+ // ANCHOR_END: vm_config
+
+ /// to import example guest code in crate replace `target_path` for:
+ /// ```
+ /// use std::path::PathBuf;
+ ///
+ /// let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).to_path_buf();
+ /// path.push("guest");
+ /// let target_path = path.to_str().unwrap();
+ /// ```
+ // ANCHOR: build
+ // 1. Build the VmConfig with the extensions needed.
+ let sdk = Sdk;
+
+ // 2a. Build the ELF with guest options and a target filter.
+ let guest_opts = GuestOptions::default();
+ let target_path = "your_path_project_root";
+ let elf = sdk.build(guest_opts, target_path, &Default::default())?;
+ // ANCHOR_END: build
+
+ // ANCHOR: transpilation
+ // 3. Transpile the ELF into a VmExe
+ let exe = sdk.transpile(elf, vm_config.transpiler())?;
+ // ANCHOR_END: transpilation
+
+ // ANCHOR: execution
+ // 4. Format your input into StdIn
+ let my_input = SomeStruct { a: 1, b: 2 }; // anything that can be serialized
+ let mut stdin = StdIn::default();
+ stdin.write(&my_input);
+ // ANCHOR_END: execution
+
+ // 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);
+
+ // 6. Commit the exe
+ let app_committed_exe = sdk.commit_app_exe(app_fri_params, exe)?;
+
+ // 7. Generate an AppProvingKey
+ let app_pk = Arc::new(sdk.app_keygen(app_config)?);
+ // ANCHOR_END: keygen
+
+ // ANCHOR: evm_verification
+ // 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)?;
+
+ // 9. Generate the SNARK verifier smart contract
+ let verifier = sdk.generate_snark_verifier_contract(&halo2_params_reader, &agg_pk)?;
+
+ // 10. Generate an EVM proof
+ let proof = sdk.generate_evm_proof(
+ &halo2_params_reader,
+ app_pk,
+ app_committed_exe,
+ agg_pk,
+ stdin,
+ )?;
+
+ // 11. Verify the EVM proof
+ let success = sdk.verify_evm_proof(&verifier, &proof);
+ assert!(success);
+ // ANCHOR_END: evm_verification
+
+ Ok(())
+}