An open API service indexing awesome lists of open source software.

https://github.com/sanjay-sol/zkvm

A Minimal STARK based zkVM.
https://github.com/sanjay-sol/zkvm

air execution-trace field-elements fri goldilocks memory merkle-tree registers zkvm

Last synced: 18 days ago
JSON representation

A Minimal STARK based zkVM.

Awesome Lists containing this project

README

          

# zkVM — Minimal Zero-Knowledge Virtual Machine

A fully working STARK-based zkVM in Rust. No trusted setup. Pure hash-based cryptography. Runs on stable Rust.

---

## Quick Start

```bash
# Build
cargo build --release

# Run fibonacci(10) — prove and verify
cargo run --release -- run fibonacci 10

# Run 5!
cargo run --release -- run factorial 5

# Run sum(1..50)
cargo run --release -- run sum 50

# Run all built-in examples
cargo run --release -- run-all

# Benchmark
cargo run --release -- bench

# Show system parameters
cargo run --release -- info

# Run ALL tests (51 unit tests)
cargo test
```

---

## Example Output

### fibonacci(10)

```
Program : fibonacci(10)

[ 1/4 ] Executing VM ... done in 30.42us
Steps : 66
Trace rows : 128 (padded to power of 2)
r0 (result) : 55
Expected : 55

[ 2/4 ] Checking constraints ... ALL SATISFIED

[ 3/4 ] Generating STARK proof ... done in 11.29ms
FRI layers : 6
FRI queries : 30
Trace cols : 11
OOD evals : 22
Proof size : ~71 KB (rough estimate)

[ 4/4 ] Verifying proof ... VALID (1.49ms)

Proof generation: 11.29ms
Proof verification: 1.50ms
Total: 13.06ms
```

### factorial(5)

```
Program : 5!

[ 1/4 ] Executing VM ... done in 15.50us
Steps : 25
Trace rows : 32 (padded to power of 2)
r0 (result) : 120
Expected : 120

[ 2/4 ] Checking constraints ... ALL SATISFIED

[ 3/4 ] Generating STARK proof ... done in 3.91ms
FRI layers : 4
FRI queries : 30
Trace cols : 11
OOD evals : 22
Proof size : ~69 KB (rough estimate)

[ 4/4 ] Verifying proof ... VALID (2.02ms)

Proof generation: 3.91ms
Proof verification: 2.02ms
Total: 6.04ms
```

---

## Benchmarks

All benchmarks run on release builds (`cargo run --release -- bench`).

| Program | Trace Length | Prove | Verify | Ratio |
|---------|-------------|-------|--------|-------|
| fibonacci(5) | 64 | 4,432 us | 1,384 us | 3.2x |
| fibonacci(10) | 128 | 18,396 us | 2,694 us | 6.8x |
| fibonacci(15) | 128 | 15,785 us | 2,418 us | 6.5x |
| factorial(5) | 32 | 3,231 us | 1,293 us | 2.5x |
| factorial(7) | 64 | 6,135 us | 1,618 us | 3.8x |
| sum(20) | 128 | 11,194 us | 1,615 us | 6.9x |
| sum(50) | 256 | 20,885 us | 1,870 us | 11.2x |

Verification is consistently 3-11x faster than proving. Proof generation scales roughly linearly with trace length.

---

## Run-All Results

All 10 built-in programs prove and verify successfully:

```
fibonacci(0) PASS
fibonacci(1) PASS
fibonacci(10) PASS
fibonacci(15) PASS
factorial(1) PASS
factorial(5) PASS
factorial(7) PASS
sum(10) PASS
sum(50) PASS
memory roundtrip PASS

Results: 10 passed, 0 failed
```

---

## Test Suite

51 unit tests covering every module. All passing.

```
cargo test

running 51 tests
test channel::tests::test_absorb_resets_squeeze ... ok
test channel::tests::test_absorb_changes_output ... ok
test channel::tests::test_deterministic ... ok
test channel::tests::test_different_input_different_output ... ok
test channel::tests::test_sequential_squeezings_differ ... ok
test constraints::tests::test_boundary_initial_state ... ok
test constraints::tests::test_factorial_constraints ... ok
test constraints::tests::test_fibonacci_constraints ... ok
test constraints::tests::test_sum_constraints ... ok
test field::tests::test_add_wrap ... ok
test field::tests::test_field_laws ... ok
test field::tests::test_half ... ok
test field::tests::test_inv ... ok
test field::tests::test_mul_2_32 ... ok
test field::tests::test_mul_basic ... ok
test field::tests::test_pow ... ok
test field::tests::test_reduce_known ... ok
test field::tests::test_root_of_unity ... ok
test field::tests::test_root_of_unity_order ... ok
test field::tests::test_sub_wrap ... ok
test fri::tests::test_fold_correctness ... ok
test fri::tests::test_fold_domain_consistency ... ok
test fri::tests::test_fri_commit_verify_low_degree ... ok
test fri::tests::test_fri_multiple_polys ... ok
test merkle::tests::test_large_tree ... ok
test merkle::tests::test_open_and_verify_all_leaves ... ok
test merkle::tests::test_root_changes_with_leaf ... ok
test merkle::tests::test_root_deterministic ... ok
test merkle::tests::test_wrong_leaf_fails ... ok
test poly::tests::test_divide_by_vanishing ... ok
test poly::tests::test_domain_powers ... ok
test poly::tests::test_eval_poly ... ok
test poly::tests::test_interpolate_eval_consistency ... ok
test poly::tests::test_lde_consistent_with_poly ... ok
test poly::tests::test_mul_poly ... ok
test poly::tests::test_ntt_intt_roundtrip ... ok
test poly::tests::test_ntt_known_values ... ok
test prover::tests::test_prover_runs_without_panic ... ok
test trace::tests::test_column_extraction ... ok
test trace::tests::test_trace_length_power_of_two ... ok
test trace::tests::test_trace_selector_column ... ok
test verifier::tests::test_verify_factorial_5 ... ok
test verifier::tests::test_verify_fibonacci_5 ... ok
test verifier::tests::test_verify_fibonacci_10 ... ok
test verifier::tests::test_verify_sum_10 ... ok
test vm::tests::test_factorial ... ok
test vm::tests::test_fibonacci ... ok
test vm::tests::test_jnz ... ok
test vm::tests::test_mem_roundtrip ... ok
test vm::tests::test_sum ... ok

test result: ok. 51 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```

---

## What This Implements

```
Program (assembly)
|
v
+-------------------------------------------------------+
| VM Execution (vm.rs) |
| 8 registers x Felt, 11 opcodes, linear memory |
| Records every state transition |
+------------------------+------------------------------+
| Execution Trace (trace.rs)
v
+----------------------------------+
| Trace Matrix T[row][col] | n x 11
| Padded to next power of 2 |
+--------------+-------------------+
| NTT interpolation (poly.rs)
v
+----------------------------------+
| Trace polynomials T_j(x) | deg n-1
+--------------+-------------------+
| LDE x4 (poly.rs)
v
+----------------------------------+
| LDE evaluations + Merkle trees | (merkle.rs)
| Committed via Blake3 |
+--------------+-------------------+
| AIR (constraints.rs)
v
+----------------------------------+
| Constraint polynomial C(x) |
| Quotient Q(x) = C(x)/Z(x) |
+--------------+-------------------+
| DEEP-ALI (prover.rs)
v
+----------------------------------+
| Composition polynomial |
| FRI low-degree proof (fri.rs) |
+--------------+-------------------+
|
v
StarkProof
|
v
+----------------------------------+
| Verifier (verifier.rs) |
| Replays transcript |
| Checks Merkle + FRI |
+----------------------------------+
```

---

## File Structure

```
zkvm/
├── Cargo.toml
├── src/
│ ├── lib.rs re-exports all modules
│ ├── main.rs CLI (cargo run -- run fibonacci 10)
│ ├── field.rs Goldilocks field (p = 2^64 - 2^32 + 1)
│ ├── vm.rs ISA + execution engine
│ ├── trace.rs Execution trace recording + padding
│ ├── constraints.rs AIR constraint system
│ ├── poly.rs NTT, iNTT, LDE, polynomial evaluation
│ ├── merkle.rs Binary Merkle tree + proof
│ ├── channel.rs Fiat-Shamir transcript (Blake3)
│ ├── fri.rs FRI commit + verify
│ ├── prover.rs Full STARK prover
│ └── verifier.rs Full STARK verifier
└── examples/
├── fibonacci.zkasm
├── factorial.zkasm
└── sum.zkasm
```

---

## Instruction Set

| Opcode | Semantics |
|--------|-----------|
| `CONST rd, imm` | `rd = imm` |
| `ADD rd, rs1, rs2` | `rd = rs1 + rs2` |
| `SUB rd, rs1, rs2` | `rd = rs1 - rs2` |
| `MUL rd, rs1, rs2` | `rd = rs1 * rs2` |
| `JMP addr` | `pc = addr` |
| `JZ rs, addr` | `if rs == 0: pc = addr` |
| `JNZ rs, addr` | `if rs != 0: pc = addr` |
| `COPY rd, rs` | `rd = rs` |
| `LOAD rd, addr` | `rd = mem[addr]` |
| `STORE rs, addr` | `mem[addr] = rs` |
| `HALT` | stop |

All values live in `F_p` (Goldilocks field, `p = 2^64 - 2^32 + 1`).

---

## Proof System Parameters

| Parameter | Value | Notes |
|-----------|-------|-------|
| Field | Goldilocks | `p = 2^64 - 2^32 + 1` |
| Hash | Blake3 | 256-bit, no trusted setup |
| LDE blowup | 4x | `fri.rs: BLOWUP_FACTOR` |
| FRI queries | 30 | `fri.rs: NUM_QUERIES` |
| Trace width | 11 | 8 regs + pc + sel + opcode |
| Post-quantum | Yes | hash-based only, no elliptic curves |
| Trusted setup | None | transparent |
| Security | ~30 bits | increase `NUM_QUERIES` for production |

---

## Running Tests

```bash
cargo test # all 51 tests
cargo test test_field # only field arithmetic tests
cargo test test_fri # only FRI tests
cargo test test_verify # only verifier tests
cargo test -- --nocapture # show println output
```

---

## Writing a Custom Program

```rust
use zkvm_lib::{
vm::Instruction,
field::Felt,
trace::generate_trace,
constraints::ConstraintSystem,
prover::prove,
verifier::verify,
};

fn main() {
// Program: compute 3 * 4 = 12
let program = vec![
Instruction::Const(0, Felt::new(3)),
Instruction::Const(1, Felt::new(4)),
Instruction::Mul(2, 0, 1),
Instruction::Halt,
];

// Execute and record trace
let (vm, trace) = generate_trace(&program, 16);
println!("Result: r2 = {}", vm.regs[2].0); // 12

// Prove
let cs = ConstraintSystem::new(program, vec![vm.regs[2]]);
let proof = prove(&trace, &cs, vec![vm.regs[2]]);

// Verify
match verify(&proof) {
Ok(()) => println!("Proof VALID"),
Err(msg) => println!("Proof INVALID: {msg}"),
}
}
```

---

## Cryptographic Stack

- **No trusted setup** -- all randomness derived from Blake3 (Fiat-Shamir)
- **Post-quantum** -- only hash functions, no elliptic curves
- **FRI soundness** -- cheating prover is caught with probability >= 1 - (1/|F|)^30 per query
- **Completeness** -- honest prover always convinces verifier

---

## Resources

- [Anatomy of a STARK](https://aszepieniec.github.io/stark-anatomy/) -- best tutorial
- [STARK paper (Ben-Sasson et al.)](https://eprint.iacr.org/2018/046.pdf)
- [FRI paper](https://eccc.weizmann.ac.il/report/2017/134/)
- [Winterfell](https://github.com/facebook/winterfell) -- production STARK in Rust
- [RISC Zero](https://github.com/risc0/risc0) -- zkVM for full RISC-V

---

## License

MIT