|
| 1 | +# Writing a MidenVM Program In Rust |
| 2 | + |
| 3 | +*Using the Miden compiler to write programs in Rust and generate a proof of computation using the MidenVM CLI* |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +In this guide, we will write a simple Rust program that checks whether an integer is prime. We will compile the Rust program into a Miden package and run it in the Miden VM. We will also see how to use the Miden CLI to generate a STARK proof that the computation was performed correctly. |
| 8 | + |
| 9 | +## What we'll cover |
| 10 | + |
| 11 | +- Writing basic programs in Rust using the Miden compiler. |
| 12 | +- Running programs in the Miden VM. |
| 13 | +- Generating a proof of compuation for the `is_prime` program |
| 14 | +- Verifying the STARK proof of the `is_prime` program execution |
| 15 | + |
| 16 | +## Limitations and Important Considerations |
| 17 | + |
| 18 | +Please note these current limitations of the Miden compiler: |
| 19 | +- **No Floating Point Support:** Only integer arithmetic is supported (e.g., `u32`, `u64`, etc.). |
| 20 | +- **No Standard Library:** Programs must be written with `#![no_std]`, limiting you to core library functionality. |
| 21 | +- **Entrypoint Constraints:** The `entrypoint` function can accept at most **16 inputs** on the stack and produces a single `u32` output. |
| 22 | + |
| 23 | +## Step 1: Installing the Miden Compiler |
| 24 | + |
| 25 | +Clone the repository and install the compiler: |
| 26 | +```bash |
| 27 | +git clone https://github.com/0xpolygonmiden/compiler |
| 28 | +cd compiler |
| 29 | +git checkout next |
| 30 | +``` |
| 31 | + |
| 32 | +Then install the Miden compiler: |
| 33 | +```bash |
| 34 | +cargo install --path midenc --locked |
| 35 | +``` |
| 36 | + |
| 37 | +and the cargo-miden toolchain: |
| 38 | +```bash |
| 39 | +cargo install --path tools/cargo-miden --locked |
| 40 | +``` |
| 41 | + |
| 42 | +## Step 2: Writing the Rust Program |
| 43 | + |
| 44 | +Outside of the compiler repository, create a new Miden project: |
| 45 | +```bash |
| 46 | +cargo miden new is_prime |
| 47 | +cd is_prime |
| 48 | +``` |
| 49 | + |
| 50 | +Add the following Rust code to `is_prime/src/lib.rs`. This code checks whether a number is prime: |
| 51 | +```rust |
| 52 | +#![no_std] |
| 53 | + |
| 54 | +// Custom panic handler since we don't have the standard library. |
| 55 | +#[cfg(not(test))] |
| 56 | +#[panic_handler] |
| 57 | +fn my_panic(_info: &core::panic::PanicInfo) -> ! { |
| 58 | + loop {} |
| 59 | +} |
| 60 | + |
| 61 | +/// Returns true if the integer is prime. |
| 62 | +fn is_prime(n: u32) -> bool { |
| 63 | + if n <= 1 { |
| 64 | + return false; |
| 65 | + } |
| 66 | + if n <= 3 { |
| 67 | + return true; |
| 68 | + } |
| 69 | + if n % 2 == 0 || n % 3 == 0 { |
| 70 | + return false; |
| 71 | + } |
| 72 | + let mut i = 5; |
| 73 | + while i * i <= n { |
| 74 | + if n % i == 0 || n % (i + 2) == 0 { |
| 75 | + return false; |
| 76 | + } |
| 77 | + i += 6; |
| 78 | + } |
| 79 | + true |
| 80 | +} |
| 81 | + |
| 82 | +/// The entry point to the Miden program. |
| 83 | +#[no_mangle] |
| 84 | +fn entrypoint(n: u32) -> bool { |
| 85 | + is_prime(n) |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +Add this code into your project's `src/lib.rs` file. |
| 90 | + |
| 91 | +Next, create an `is_prime/inputs.toml` file: |
| 92 | +```toml |
| 93 | +[inputs] |
| 94 | +stack = [2147482583] |
| 95 | +``` |
| 96 | + |
| 97 | +This file sets the value that will be passed into our `entrypoint` function when the program runs. |
| 98 | + |
| 99 | +## Step 3: Running the Program in the Miden VM |
| 100 | + |
| 101 | +Compile your program with: |
| 102 | +```bash |
| 103 | +cargo miden build --release |
| 104 | +``` |
| 105 | + |
| 106 | +Run your compiled Miden assembly program using: |
| 107 | +```bash |
| 108 | +midenc run target/miden/release/is_prime.masp --inputs inputs.toml |
| 109 | +``` |
| 110 | + |
| 111 | +The output will look like this: |
| 112 | +``` |
| 113 | +Run program: target/miden/release/is_prime.masp |
| 114 | +------------------------------------------------------------------------------- |
| 115 | +Executed program with hash 0x79689b17ab6286cfde4651ef1f675cab19ad4efd9defd2c43001a06e7cbd8c40 in 2 seconds |
| 116 | +Output: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] |
| 117 | +VM cycles: 2039234 extended to 2097152 steps (2% padding). |
| 118 | +├── Stack rows: 1668454 |
| 119 | +├── Range checker rows: 61329 |
| 120 | +└── Chiplets rows: 2039234 |
| 121 | + ├── Hash chiplet rows: 1792040 |
| 122 | + ├── Bitwise chiplet rows: 247192 |
| 123 | + ├── Memory chiplet rows: 1 |
| 124 | + └── Kernel ROM rows: 0 |
| 125 | +``` |
| 126 | + |
| 127 | +The program returns `1` if the integer passed to the `is_prime` function is prime and `0` if it is not. |
| 128 | + |
| 129 | +## Step 4: Generating a zk proof of the `is_prime` program execution |
| 130 | + |
| 131 | +First install the Miden CLI by cloning the Miden VM repository and checking out the `next` branch: |
| 132 | +```bash |
| 133 | +git clone [email protected]:0xPolygonMiden/miden-vm.git |
| 134 | +cd miden-vm |
| 135 | +git checkout next |
| 136 | +``` |
| 137 | + |
| 138 | +Build and install the Miden VM CLI: |
| 139 | +``` |
| 140 | +cd miden |
| 141 | +cargo install --path . --features concurrent,executable |
| 142 | +``` |
| 143 | + |
| 144 | +After installation is complete, return to the `is_prime` directory. |
| 145 | + |
| 146 | +The current input file format for the Miden VM differs slightly from that of the compiler. This means we need to create an `is_prime.inputs` file at the root of the `is_prime` directory: |
| 147 | +```json |
| 148 | +{ |
| 149 | + "operand_stack": ["2147482583"] |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +Now, using the Miden VM CLI tool, we can prove our program by running the following: |
| 154 | +``` |
| 155 | +miden prove target/miden/release/is_prime.masp -i is_prime.inputs |
| 156 | +``` |
| 157 | + |
| 158 | +The output should look like this: |
| 159 | + |
| 160 | +``` |
| 161 | +=============================================================================== |
| 162 | +Prove program: target/miden/release/is_prime.masp |
| 163 | +------------------------------------------------------------------------------- |
| 164 | +Proving program with hash 79689b17ab6286cfde4651ef1f675cab19ad4efd9defd2c43001a06e7cbd8c40... |
| 165 | +Program proved in 85558 ms |
| 166 | +Output: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] |
| 167 | +``` |
| 168 | + |
| 169 | +To verify the proof generated in the previous step, run the following: |
| 170 | +``` |
| 171 | +miden verify -p target/miden/release/is_prime.proof -i is_prime.inputs -x 79689b17ab6286cfde4651ef1f675cab19ad4efd9defd2c43001a06e7cbd8c40 |
| 172 | +``` |
| 173 | + |
| 174 | +The output should look like this: |
| 175 | +``` |
| 176 | +=============================================================================== |
| 177 | +Verifying proof: target/miden/release/is_prime.proof |
| 178 | +------------------------------------------------------------------------------- |
| 179 | +Verification complete in 5 ms |
| 180 | +``` |
| 181 | + |
| 182 | +## Conclusion |
| 183 | + |
| 184 | +This tutorial demonstrated how to write a basic program using the Miden compiler and how to prove and verify the execution of the program using the Miden CLI. |
0 commit comments