diff --git a/.github/workflows/algebra-extension.yml b/.github/workflows/algebra-extension.yml deleted file mode 100644 index 86d0b22365..0000000000 --- a/.github/workflows/algebra-extension.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Algebra Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "extensions/algebra/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run algebra extension crate tests - working-directory: extensions/algebra/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run algebra integration tests - working-directory: extensions/algebra/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/bigint-extension.yml b/.github/workflows/bigint-extension.yml deleted file mode 100644 index d4f11e637d..0000000000 --- a/.github/workflows/bigint-extension.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Bigint Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "extensions/bigint/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run bigint extension crate tests - working-directory: extensions/bigint/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run bigint integration tests - working-directory: extensions/bigint/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/ecc.yml b/.github/workflows/ecc.yml deleted file mode 100644 index cad4209628..0000000000 --- a/.github/workflows/ecc.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: ECC Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "crates/circuits/primitives/**" - - "crates/vm/**" - - "crates/cli/**" - - "extensions/ecc/**" - - "extensions/native/compiler/**" - - "extensions/pairing/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run ecc-circuits crate tests - working-directory: extensions/ecc/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run ecc integration tests - working-directory: extensions/ecc/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast - - - name: Run pairing-circuits crate tests - working-directory: extensions/pairing/circuit - run: | - RUST_MIN_STACK=8388608 cargo nextest run --cargo-profile=fast - - - name: Run pairing-guest crate tests - working-directory: extensions/pairing/guest - run: | - cargo nextest run --cargo-profile=fast --features=bn254,bls12_381,halo2curves - - - name: Run pairing integration tests - working-directory: extensions/pairing/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - RUST_MIN_STACK=8388608 cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/extension-tests.yml b/.github/workflows/extension-tests.yml new file mode 100644 index 0000000000..430f3c7b50 --- /dev/null +++ b/.github/workflows/extension-tests.yml @@ -0,0 +1,84 @@ +name: Extension Tests + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + paths: + - "crates/circuits/primitives/**" + - "crates/vm/**" + - "extensions/**" + - ".github/workflows/extension-tests.yml" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + OPENVM_FAST_TEST: "1" + +jobs: + extension-tests: + strategy: + matrix: + extension: + - { name: "rv32im", path: "rv32im" } + - { name: "native", path: "native" } + - { name: "keccak256", path: "keccak256" } + - { name: "sha256", path: "sha256" } + - { name: "bigint", path: "bigint" } + - { name: "algebra", path: "algebra" } + - { name: "ecc", path: "ecc" } + - { name: "pairing", path: "pairing" } + # Ensure tests run in parallel even if one fails + fail-fast: false + + runs-on: + - runs-on=${{ github.run_id }} + - runner=64cpu-linux-arm64 + - tag=extension-${{ matrix.extension.name }} + + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + - "crates/circuits/primitives/**" + - "crates/vm/**" + - "extensions/${{ matrix.extensions.path }}/**" + - ".github/workflows/extension-tests.yml" + - name: Skip if no changes + if: steps.filter.outputs.matched == 'false' + run: | + echo "No relevant changes, skipping tests." + exit 0 + + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - uses: taiki-e/install-action@nextest + + - name: Run ${{ matrix.extension.name }} circuit crate tests + working-directory: extensions/${{ matrix.extension.path }}/circuit + run: cargo nextest run --cargo-profile=fast + + - name: Run ${{ matrix.extension.name }} guest crate tests + if: hashFiles(format('extensions/{0}/guest', matrix.extension.path)) != '' + working-directory: extensions/${{ matrix.extension.path }}/guest + run: | + FEATURE_ARGS="" + if [[ "${{ matrix.extension.name }}" == "pairing" ]]; then + FEATURE_ARGS="--features=bn254,bls12_381,halo2curves" + fi + cargo nextest run --cargo-profile=fast $FEATURE_ARGS --no-tests=pass + + - name: Run ${{ matrix.extension.name }} integration tests + if: hashFiles(format('extensions/{0}/tests', matrix.extension.path)) != '' + working-directory: extensions/${{ matrix.extension.path }}/tests + run: | + rustup component add rust-src --toolchain nightly-2024-10-30 + cargo nextest run --cargo-profile=fast --no-tests=pass diff --git a/.github/workflows/keccak256-extension.yml b/.github/workflows/keccak256-extension.yml deleted file mode 100644 index 49ebcebbea..0000000000 --- a/.github/workflows/keccak256-extension.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Keccak Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "extensions/keccak256/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run keccak256 extension crate tests - working-directory: extensions/keccak256/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run keccak256 integration tests - working-directory: extensions/keccak256/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/toolchain-edsl.yml b/.github/workflows/native-compiler.yml similarity index 96% rename from .github/workflows/toolchain-edsl.yml rename to .github/workflows/native-compiler.yml index fa19137c0f..028e60e31c 100644 --- a/.github/workflows/toolchain-edsl.yml +++ b/.github/workflows/native-compiler.yml @@ -1,4 +1,4 @@ -name: eDSL Compiler Tests +name: Native Compiler Tests on: push: diff --git a/.github/workflows/native-extension.yml b/.github/workflows/native-extension.yml deleted file mode 100644 index 3c4379d2c2..0000000000 --- a/.github/workflows/native-extension.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Native Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "extensions/native/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run native extension crate tests - working-directory: extensions/native/circuit - run: | - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/rv32im-extension.yml b/.github/workflows/rv32im-extension.yml deleted file mode 100644 index 8431bf845a..0000000000 --- a/.github/workflows/rv32im-extension.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: rv32im Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "extensions/rv32im/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run rv32im extension crate tests - working-directory: extensions/rv32im/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run rv32im integration tests - working-directory: extensions/rv32im/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/sha256-extension.yml b/.github/workflows/sha256-extension.yml deleted file mode 100644 index 73e4e5d39e..0000000000 --- a/.github/workflows/sha256-extension.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: SHA2-256 Extension Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "crates/circuits/sha256-air/**" - - "extensions/sha256/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest - - - name: Run sha256 extension crate tests - working-directory: extensions/sha256/circuit - run: | - cargo nextest run --cargo-profile=fast - - - name: Run sha256 integration tests - working-directory: extensions/sha256/tests - run: | - rustup component add rust-src --toolchain nightly-2024-10-30 - cargo nextest run --cargo-profile=fast diff --git a/.github/workflows/toolchain.yml b/.github/workflows/toolchain.yml deleted file mode 100644 index 5a0c6b852c..0000000000 --- a/.github/workflows/toolchain.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Toolchain Tests - -on: - push: - branches: ["main"] - pull_request: - branches: ["**"] - paths: - - "crates/vm/**" - - "extensions/**" - - "crates/toolchain/**" - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - OPENVM_FAST_TEST: "1" - -jobs: - tests: - runs-on: - - runs-on=${{ github.run_id }} - - runner=64cpu-linux-arm64 - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - uses: taiki-e/install-action@nextest diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 71d40b5535..596864db86 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -5,7 +5,6 @@ # Getting Started - [Install](./getting-started/install.md) - - [Quickstart](./getting-started/quickstart.md) # Writing Apps 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/book/src/custom-extensions/algebra.md b/book/src/custom-extensions/algebra.md index d74b38b779..07d05951a4 100644 --- a/book/src/custom-extensions/algebra.md +++ b/book/src/custom-extensions/algebra.md @@ -111,52 +111,8 @@ The `supported_modulus` parameter is a list of moduli that the guest program wil Here is a toy example using both the modular arithmetic and complex field extension capabilities: -```rust -#![cfg_attr(not(feature = "std"), no_main)] -#![cfg_attr(not(feature = "std"), no_std)] - -use openvm_algebra_guest::{IntMod, moduli_setup::*}; - -openvm::entry!(main); - -// This macro will create two structs, `Mod1` and `Mod2`, -// one for arithmetic modulo 998244353, and the other for arithmetic modulo 1000000007. -moduli_declare! { - Mod1 { modulus = "998244353" }, - Mod2 { modulus = "1000000007" } -} - -// This macro will initialize the moduli. -// Now, `Mod1` is the "zeroth" modular struct, and `Mod2` is the "first" one. -moduli_init! { - "998244353", "1000000007" -} - -// This macro will create two structs, `Complex1` and `Complex2`, -// one for arithmetic in the field $\mathbb{F}_{998244353}[x]/(x^2 + 1)$, -// and the other for arithmetic in the field $\mathbb{F}_{1000000007}[x]/(x^2 + 1)$. -openvm_algebra_complex_macros::complex_declare! { - Complex1 { mod_type = Mod1 }, - Complex2 { mod_type = Mod2 }, -} - -// The order of these structs does not matter, -// given that we specify the `mod_idx` parameters properly. -openvm_algebra_complex_macros::complex_init! { - Complex2 { mod_idx = 1 }, Complex1 { mod_idx = 0 }, -} - -pub fn main() { - // Since we only use an arithmetic operation with `Mod1` and not `Mod2`, - // we only need to call `setup_0()` here. - setup_0(); - setup_all_complex_extensions(); - let a = Complex1::new(Mod1::ZERO, Mod1::from_u32(0x3b8) * Mod1::from_u32(0x100000)); // a = -i in the corresponding field - let b = Complex2::new(Mod2::ZERO, Mod2::from_u32(1000000006)); // b = -i in the corresponding field - assert_eq!(a.clone() * &a * &a * &a * &a, a); // a^5 = a - assert_eq!(b.clone() * &b * &b * &b * &b, b); // b^5 = b - // Note that these assertions would fail, have we provided the `mod_idx` parameters wrongly. -} +```rust,no_run,noplayground +{{ #include ../../../examples/algebra/src/main.rs }} ``` To have the correct imports for the above example, add the following to the `Cargo.toml` file: diff --git a/book/src/custom-extensions/bigint.md b/book/src/custom-extensions/bigint.md index d1bdc2247c..836316aba2 100644 --- a/book/src/custom-extensions/bigint.md +++ b/book/src/custom-extensions/bigint.md @@ -31,49 +31,10 @@ When using the `U256` struct with `target_os = "zkvm"`, the struct utilizes effi ### Example matrix multiplication using `U256` -See the full example [here](https://github.com/openvm-org/openvm/blob/main/crates/toolchain/tests/programs/examples/matrix-power.rs). +See the full example [here](https://github.com/openvm-org/openvm/blob/main/examples/u256/src/main.rs). -```rust -#![cfg_attr(not(feature = "std"), no_main)] -#![cfg_attr(not(feature = "std"), no_std)] - -openvm::entry!(main); -use core::array; -use openvm_bigint_guest::U256; - -const N: usize = 16; -type Matrix = [[U256; N]; N]; - -pub fn get_matrix(val: u8) -> Matrix { - array::from_fn(|_| array::from_fn(|_| U256::from_u8(val))) -} - -pub fn mult(a: &Matrix, b: &Matrix) -> Matrix { - let mut c = get_matrix(0); - for i in 0..N { - for j in 0..N { - for k in 0..N { - c[i][j] += &a[i][k] * &b[k][j]; - } - } - } - c -} - -pub fn get_identity_matrix() -> Matrix { - let mut res = get_matrix(0); - for i in 0..N { - res[i][i] = U256::from_u8(1); - } - res -} - -pub fn main() { - let a: Matrix = get_identity_matrix(); - let b: Matrix = get_matrix(28); - let c: Matrix = mult(&a, &b); - assert_eq!(c, b); -} +```rust,no_run,noplayground +{{ #include ../../../examples/u256/src/main.rs }} ``` To be able to import the `U256` struct, add the following to your `Cargo.toml` file: @@ -111,49 +72,10 @@ When using the `I256` struct with `target_os = "zkvm"`, the struct utilizes effi ### Example matrix multiplication using `I256` -See the full example [here](https://github.com/openvm-org/openvm/blob/main/crates/toolchain/tests/programs/examples/matrix-power-signed.rs). +See the full example [here](https://github.com/openvm-org/openvm/blob/main/examples/i256/src/main.rs). -```rust -#![cfg_attr(not(feature = "std"), no_main)] -#![cfg_attr(not(feature = "std"), no_std)] - -openvm::entry!(main); -use core::array; -use openvm_bigint_guest::I256; - -const N: usize = 16; -type Matrix = [[I256; N]; N]; - -pub fn get_matrix(val: i32) -> Matrix { - array::from_fn(|_| array::from_fn(|_| I256::from_i32(val))) -} - -pub fn mult(a: &Matrix, b: &Matrix) -> Matrix { - let mut c = get_matrix(0); - for i in 0..N { - for j in 0..N { - for k in 0..N { - c[i][j] += &a[i][k] * &b[k][j]; - } - } - } - c -} - -pub fn get_identity_matrix() -> Matrix { - let mut res = get_matrix(0); - for i in 0..N { - res[i][i] = I256::from_i32(1); - } - res -} - -pub fn main() { - let a: Matrix = get_identity_matrix(); - let b: Matrix = get_matrix(-28); - let c: Matrix = mult(&a, &b); - assert_eq!(c, b); -} +```rust,no_run,noplayground +{{ #include ../../../examples/i256/src/main.rs }} ``` To be able to import the `I256` struct, add the following to your `Cargo.toml` file: diff --git a/book/src/custom-extensions/ecc.md b/book/src/custom-extensions/ecc.md index de2b2fbd9a..542f571e3d 100644 --- a/book/src/custom-extensions/ecc.md +++ b/book/src/custom-extensions/ecc.md @@ -63,7 +63,7 @@ For the basic operations provided by the `WeierstrassPoint` trait, the scalar fi ## Example program -See a working example [here](https://github.com/openvm-org/openvm/blob/main/crates/toolchain/tests/programs/examples/ec.rs). +See a working example [here](https://github.com/openvm-org/openvm/blob/main/examples/ecc/src/main.rs). To use the ECC extension, add the following dependencies to `Cargo.toml`: @@ -74,44 +74,17 @@ openvm-ecc-guest = { git = "https://github.com/openvm-org/openvm.git", features One can define their own ECC structs but we will use the Secp256k1 struct from `openvm-ecc-guest` and thus the `k256` feature should be enabled. -```rust -use openvm_ecc_guest::{ - k256::{Secp256k1Coord, Secp256k1Point, Secp256k1Scalar}, - Group, weierstrass::WeierstrassPoint, -}; - -openvm_algebra_guest::moduli_setup::moduli_init! { - "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", - "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" -} - -openvm_ecc_guest::sw_setup::sw_init! { - Secp256k1Coord, -} +```rust,no_run,noplayground +{{ #include ../../../examples/ecc/src/main.rs:imports }} +{{ #include ../../../examples/ecc/src/main.rs:init }} ``` We `moduli_init!` both the coordinate and scalar field because they were declared in the `k256` module, although we will not be using the scalar field below. With the above we can start doing elliptic curve operations like adding points: -```rust -pub fn main() { - setup_all_moduli(); - setup_all_curves(); - let x1 = Secp256k1Coord::from_u32(1); - let y1 = Secp256k1Coord::from_le_bytes(&hex!( - "EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842" - )); - let p1 = Secp256k1Point::from_xy_nonidentity(x1, y1).unwrap(); - - let x2 = Secp256k1Coord::from_u32(2); - let y2 = Secp256k1Coord::from_le_bytes(&hex!( - "D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499" - )); - let p2 = Secp256k1Point::from_xy_nonidentity(x2, y2).unwrap(); - - let p3 = &p1 + &p2; -} +```rust,no_run,noplayground +{{ #include ../../../examples/ecc/src/main.rs:main }} ``` ### Config parameters diff --git a/book/src/custom-extensions/keccak.md b/book/src/custom-extensions/keccak.md index 111b81ae2a..bf33be2d38 100644 --- a/book/src/custom-extensions/keccak.md +++ b/book/src/custom-extensions/keccak.md @@ -10,28 +10,13 @@ The OpenVM Keccak256 Guest extension provides two functions for using in your gu - `keccak256(input: &[u8]) -> [u8; 32]`: Computes the Keccak-256 hash of the input data and returns it as an array of 32 bytes. - `set_keccak256(input: &[u8], output: &mut [u8; 32])`: Sets the output to the Keccak-256 hash of the input data into the provided output buffer. -See the full example [here](https://github.com/openvm-org/openvm/blob/main/crates/toolchain/tests/programs/examples/keccak.rs). +See the full example [here](https://github.com/openvm-org/openvm/blob/main/examples/keccak/src/main.rs). -### Example: +### Example -```rust -use hex::FromHex; -use openvm_keccak256_guest::keccak256; - -pub fn main() { - let test_vectors = [ - ("", "C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470"), - ("CC", "EEAD6DBFC7340A56CAEDC044696A168870549A6A7F6F56961E84A54BD9970B8A"), - ]; - for (input, expected_output) in test_vectors.iter() { - let input = Vec::from_hex(input).unwrap(); - let expected_output = Vec::from_hex(expected_output).unwrap(); - let output = keccak256(&black_box(input)); - if output != *expected_output { - panic!(); - } - } -} +```rust,no_run,noplayground +{{ #include ../../../examples/keccak/src/main.rs:imports }} +{{ #include ../../../examples/keccak/src/main.rs:main }} ``` To be able to import the `keccak256` function, add the following to your `Cargo.toml` file: diff --git a/book/src/custom-extensions/pairing.md b/book/src/custom-extensions/pairing.md index dc412456d5..798e17aa94 100644 --- a/book/src/custom-extensions/pairing.md +++ b/book/src/custom-extensions/pairing.md @@ -8,43 +8,26 @@ $$ \mathbb{F_{p^{12}}} = \mathbb{F_{p^6}}[w]/(w^2 - v) $$ -A full guest program example is available here: [pairing_check.rs](https://github.com/openvm-org/openvm/blob/c19c9ac60b135bb0f38fc997df5eb149db8144b4/crates/toolchain/tests/programs/examples/pairing_check.rs) - ## Guest program setup We'll be working with an example using the BLS12-381 elliptic curve. This is in addition to the setup that needs to be done in the [Writing a Program](../writing-apps/write-program.md) section. In the guest program, we will import the `PairingCheck` and `IntMod` traits, along with the BLS12-381 curve structs (**IMPORTANT:** this requires the `bls12_381` feature enabled in Cargo.toml for the `openvm-pairing-guest` dependency), and a few other values that we will need: -```rust title="guest program" -use openvm_pairing_guest::{ - pairing::PairingCheck, - bls12_381::{Bls12_381, Fp, Fp2}, -}; -use openvm_ecc_guest::AffinePoint; -use openvm_algebra_guest::IntMod; -use openvm::io::read; +```rust,no_run,noplayground title="guest program" +{{ #include ../../../examples/pairing/src/main.rs:imports }} ``` Additionally, we'll need to initialize our moduli and `Fp2` struct via the following macros. For a more in-depth description of these macros, please see the [OpenVM Algebra](./algebra.md) section. -```rust -// These correspond to the BLS12-381 coordinate and scalar moduli, respectively -openvm_algebra_moduli_setup::moduli_init! { - "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", - "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" -} - -openvm_algebra_complex_macros::complex_init! { - Bls12_381Fp2 { mod_idx = 0 }, -} +```rust,no_run,noplayground +{{ #include ../../../examples/pairing/src/main.rs:init }} ``` And we'll run the required setup functions at the top of the guest program's `main()` function: -```rust -setup_0(); -setup_all_complex_extensions(); +```rust,no_run,noplayground +{{ #include ../../../examples/pairing/src/main.rs:setup }} ``` There are two moduli defined internally in the `Bls12_381` feature. The `moduli_init!` macro thus requires both of them to be initialized. However, we do not need the scalar field of BLS12-381 (which is at index 1), and thus we only initialize the modulus from index 0, thus we only use `setup_0()` (as opposed to `setup_all_moduli()`, which will save us some columns when generating the trace). @@ -69,12 +52,8 @@ pub struct PairingCheckInput { Most users that use the pairing extension will want to assert that a pairing is valid (the final exponentiation equals one). With the `PairingCheck` trait imported from the previous section, we have access to the `pairing_check` function on the `Bls12_381` struct. After reading in the input struct, we can use its values in the `pairing_check`: -```rust -let res = Bls12_381::pairing_check( - &[p0, p1], - &[q0, q1], -); -assert!(res.is_ok()) +```rust,no_run,noplayground +{{ #include ../../../examples/pairing/src/main.rs:pairing_check }} ``` ## Additional functionality @@ -115,71 +94,20 @@ supported_modulus = [ ``` Also note that since this is a complicated computation, the `keygen` step requires quite a lot of memory. Run it with `RUST_MIN_STACK` set to a large value, e.g. + ```bash RUST_MIN_STACK=8388608 cargo openvm keygen ``` -### Full example code +### Full example program -This example code contains hardcoded values and no inputs as an example that can be run via the CLI. +This [example code](https://github.com/openvm-org/openvm/blob/main/examples/pairing/src/main.rs) contains hardcoded values and no inputs as an example that can be run via the CLI. -```rust -#![no_main] -#![no_std] - -use hex_literal::hex; -use openvm_algebra_guest::{field::FieldExtension, IntMod}; -use openvm_ecc_guest::AffinePoint; -use openvm_pairing_guest::{ - bls12_381::{Bls12_381, Fp, Fp2}, - pairing::PairingCheck, -}; - -openvm::entry!(main); - -openvm_algebra_moduli_setup::moduli_init! { - "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", - "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" -} +```rust,no_run,noplayground +{{ #include ../../../examples/pairing/src/main.rs:pre }} +{{ #include ../../../examples/pairing/src/main.rs:imports }} -openvm_algebra_complex_macros::complex_init! { - Bls12_381Fp2 { mod_idx = 0 }, -} +{{ #include ../../../examples/pairing/src/main.rs:init }} -pub fn main() { - setup_0(); - setup_all_complex_extensions(); - - let p0 = AffinePoint::new( - Fp::from_be_bytes(&hex!("17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb")), - Fp::from_be_bytes(&hex!("08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1")) - ); - let p1 = AffinePoint::new( - Fp2::from_coeffs([ - Fp::from_be_bytes(&hex!("1638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053")), - Fp::from_be_bytes(&hex!("0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577")) - ]), - Fp2::from_coeffs([ - Fp::from_be_bytes(&hex!("0468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899")), - Fp::from_be_bytes(&hex!("0f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3")) - ]), - ); - let q0 = AffinePoint::new( - Fp::from_be_bytes(&hex!("0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e")), - Fp::from_be_bytes(&hex!("166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28")) - ); - let q1 = AffinePoint::new( - Fp2::from_coeffs([ - Fp::from_be_bytes(&hex!("024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8")), - Fp::from_be_bytes(&hex!("13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e")) - ]), - Fp2::from_coeffs([ - Fp::from_be_bytes(&hex!("0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801")), - Fp::from_be_bytes(&hex!("0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be")) - ]), - ); - - let res = Bls12_381::pairing_check(&[p0, -q0], &[p1, q1]); - assert!(res.is_ok()); -} +{{ #include ../../../examples/pairing/src/main.rs:main }} ``` diff --git a/book/src/custom-extensions/sha256.md b/book/src/custom-extensions/sha256.md index c2102da1b6..7b1e39be51 100644 --- a/book/src/custom-extensions/sha256.md +++ b/book/src/custom-extensions/sha256.md @@ -10,35 +10,13 @@ The OpenVM SHA-256Guest extension provides two functions for using in your guest - `sha256(input: &[u8]) -> [u8; 32]`: Computes the SHA-256 hash of the input data and returns it as an array of 32 bytes. - `set_sha256(input: &[u8], output: &mut [u8; 32])`: Sets the output to the SHA-256 hash of the input data into the provided output buffer. -See the full example [here](https://github.com/openvm-org/openvm/blob/main/examples/sha256). +See the full example [here](https://github.com/openvm-org/openvm/blob/main/examples/sha256/src/main.rs). -### Example: - -```rust -extern crate alloc; - -use alloc::vec::Vec; -use core::hint::black_box; - -use openvm_sha256_guest::sha256; -use hex::FromHex; - -openvm::entry!(main); - -pub fn main() { - let test_vectors = [ - ("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), - ]; - for (input, expected_output) in test_vectors.iter() { - let input = Vec::from_hex(input).unwrap(); - let expected_output = Vec::from_hex(expected_output).unwrap(); - let output = sha256(&black_box(input)); - if output != *expected_output { - panic!(); - } - } -} +### Example +```rust,no_run,noplayground +{{ #include ../../../examples/sha256/src/main.rs:imports }} +{{ #include ../../../examples/sha256/src/main.rs:main }} ``` To be able to import the `sha256` function, add the following to your `Cargo.toml` file: 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(()) +} diff --git a/examples/ecc/src/main.rs b/examples/ecc/src/main.rs index 5ca871b4cf..0b44a45ec6 100644 --- a/examples/ecc/src/main.rs +++ b/examples/ecc/src/main.rs @@ -1,16 +1,16 @@ #![cfg_attr(not(feature = "std"), no_main)] #![cfg_attr(not(feature = "std"), no_std)] -use openvm_algebra_guest::IntMod; - -openvm::entry!(main); - +// ANCHOR: imports use hex_literal::hex; +use openvm_algebra_guest::IntMod; use openvm_ecc_guest::{ k256::{Secp256k1Coord, Secp256k1Point}, weierstrass::WeierstrassPoint, }; +// ANCHOR_END: imports +// ANCHOR: init openvm_algebra_guest::moduli_setup::moduli_init! { "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" @@ -19,6 +19,10 @@ openvm_algebra_guest::moduli_setup::moduli_init! { openvm_ecc_guest::sw_setup::sw_init! { Secp256k1Coord, } +// ANCHOR_END: init + +// ANCHOR: main +openvm::entry!(main); pub fn main() { setup_all_moduli(); @@ -37,3 +41,4 @@ pub fn main() { let _p3 = &p1 + &p2; } +// ANCHOR_END: main diff --git a/examples/keccak/src/main.rs b/examples/keccak/src/main.rs index 904ca95420..068bcd611b 100644 --- a/examples/keccak/src/main.rs +++ b/examples/keccak/src/main.rs @@ -3,12 +3,15 @@ extern crate alloc; +// ANCHOR: imports use alloc::vec::Vec; use core::hint::black_box; use hex::FromHex; use openvm_keccak256_guest::keccak256; +// ANCHOR_END: imports +// ANCHOR: main openvm::entry!(main); pub fn main() { @@ -31,3 +34,4 @@ pub fn main() { } } } +// ANCHOR_END: main diff --git a/examples/pairing/src/main.rs b/examples/pairing/src/main.rs index 1adf39c20c..3de78a3611 100644 --- a/examples/pairing/src/main.rs +++ b/examples/pairing/src/main.rs @@ -1,16 +1,19 @@ +// ANCHOR: pre #![cfg_attr(not(feature = "std"), no_main)] #![cfg_attr(not(feature = "std"), no_std)] use hex_literal::hex; +// ANCHOR_END: pre +// ANCHOR: imports use openvm_algebra_guest::{field::FieldExtension, IntMod}; use openvm_ecc_guest::AffinePoint; use openvm_pairing_guest::{ bls12_381::{Bls12_381, Fp, Fp2}, pairing::PairingCheck, }; +// ANCHOR_END: imports -openvm::entry!(main); - +// ANCHOR: init openvm_algebra_moduli_setup::moduli_init! { "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" @@ -19,10 +22,16 @@ openvm_algebra_moduli_setup::moduli_init! { openvm_algebra_complex_macros::complex_init! { Bls12_381Fp2 { mod_idx = 0 }, } +// ANCHOR_END: init + +// ANCHOR: main +openvm::entry!(main); pub fn main() { + // ANCHOR: setup setup_0(); setup_all_complex_extensions(); + // ANCHOR_END: setup let p0 = AffinePoint::new( Fp::from_be_bytes(&hex!("17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb")), @@ -53,6 +62,9 @@ pub fn main() { ]), ); + // ANCHOR: pairing_check let res = Bls12_381::pairing_check(&[p0, -q0], &[p1, q1]); assert!(res.is_ok()); + // ANCHOR_END: pairing_check } +// ANCHOR_END: main diff --git a/examples/sha256/Cargo.toml b/examples/sha256/Cargo.toml new file mode 100644 index 0000000000..52149e3ad3 --- /dev/null +++ b/examples/sha256/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sha256-example" +version = "0.0.0" +edition = "2021" + +[workspace] +members = [] + +[dependencies] +openvm = { git = "https://github.com/openvm-org/openvm.git" } +openvm-platform = { git = "https://github.com/openvm-org/openvm.git" } +openvm-sha256-guest = { git = "https://github.com/openvm-org/openvm.git" } +hex = { version = "0.4.3", default-features = false, features = ["alloc"] } + +[features] +default = [] +std = ["openvm/std", "openvm-sha256-guest/std"] diff --git a/examples/sha256/openvm.toml b/examples/sha256/openvm.toml new file mode 100644 index 0000000000..656bf52414 --- /dev/null +++ b/examples/sha256/openvm.toml @@ -0,0 +1,4 @@ +[app_vm_config.rv32i] +[app_vm_config.rv32m] +[app_vm_config.io] +[app_vm_config.sha256] diff --git a/examples/sha256/src/main.rs b/examples/sha256/src/main.rs new file mode 100644 index 0000000000..7106cc4131 --- /dev/null +++ b/examples/sha256/src/main.rs @@ -0,0 +1,31 @@ +#![cfg_attr(not(feature = "std"), no_main)] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +// ANCHOR: imports +use alloc::vec::Vec; +use core::hint::black_box; + +use hex::FromHex; +use openvm_sha256_guest::sha256; +// ANCHOR_END: imports + +// ANCHOR: main +openvm::entry!(main); + +pub fn main() { + let test_vectors = [( + "", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + )]; + for (input, expected_output) in test_vectors.iter() { + let input = Vec::from_hex(input).unwrap(); + let expected_output = Vec::from_hex(expected_output).unwrap(); + let output = sha256(&black_box(input)); + if output != *expected_output { + panic!(); + } + } +} +// ANCHOR_END: main diff --git a/examples/u256/src/main.rs b/examples/u256/src/main.rs index 96b46e67e9..adcd7576ae 100644 --- a/examples/u256/src/main.rs +++ b/examples/u256/src/main.rs @@ -5,13 +5,13 @@ openvm::entry!(main); use core::array; -use openvm_bigint_guest::I256; +use openvm_bigint_guest::U256; const N: usize = 16; -type Matrix = [[I256; N]; N]; +type Matrix = [[U256; N]; N]; -pub fn get_matrix(val: i32) -> Matrix { - array::from_fn(|_| array::from_fn(|_| I256::from_i32(val))) +pub fn get_matrix(val: u32) -> Matrix { + array::from_fn(|_| array::from_fn(|_| U256::from_u32(val))) } pub fn mult(a: &Matrix, b: &Matrix) -> Matrix { @@ -29,14 +29,14 @@ pub fn mult(a: &Matrix, b: &Matrix) -> Matrix { pub fn get_identity_matrix() -> Matrix { let mut res = get_matrix(0); for i in 0..N { - res[i][i] = I256::from_i32(1); + res[i][i] = U256::from_u32(1); } res } pub fn main() { let a: Matrix = get_identity_matrix(); - let b: Matrix = get_matrix(-28); + let b: Matrix = get_matrix(28); let c: Matrix = mult(&a, &b); assert_eq!(c, b); } diff --git a/extensions/bigint/tests/programs/examples/book-example2.rs b/extensions/bigint/tests/programs/examples/book-example2.rs deleted file mode 100644 index 96b46e67e9..0000000000 --- a/extensions/bigint/tests/programs/examples/book-example2.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_main)] -#![cfg_attr(not(feature = "std"), no_std)] -#![allow(clippy::needless_range_loop)] - -openvm::entry!(main); -use core::array; - -use openvm_bigint_guest::I256; - -const N: usize = 16; -type Matrix = [[I256; N]; N]; - -pub fn get_matrix(val: i32) -> Matrix { - array::from_fn(|_| array::from_fn(|_| I256::from_i32(val))) -} - -pub fn mult(a: &Matrix, b: &Matrix) -> Matrix { - let mut c = get_matrix(0); - for i in 0..N { - for j in 0..N { - for k in 0..N { - c[i][j] += &a[i][k] * &b[k][j]; - } - } - } - c -} - -pub fn get_identity_matrix() -> Matrix { - let mut res = get_matrix(0); - for i in 0..N { - res[i][i] = I256::from_i32(1); - } - res -} - -pub fn main() { - let a: Matrix = get_identity_matrix(); - let b: Matrix = get_matrix(-28); - let c: Matrix = mult(&a, &b); - assert_eq!(c, b); -} diff --git a/extensions/ecc/tests/programs/examples/ec.rs b/extensions/ecc/tests/programs/examples/ec.rs index ee111991a9..cf9e004281 100644 --- a/extensions/ecc/tests/programs/examples/ec.rs +++ b/extensions/ecc/tests/programs/examples/ec.rs @@ -10,8 +10,6 @@ use openvm_ecc_guest::{ Group, }; -openvm::entry!(main); - openvm_algebra_moduli_setup::moduli_init! { "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F", "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" @@ -21,6 +19,8 @@ openvm_ecc_sw_setup::sw_init! { Secp256k1Coord, } +openvm::entry!(main); + pub fn main() { setup_all_moduli(); setup_all_curves();