Skip to main content

Installation

What you'll need

  • Rust version 1.0 or higher
  • A basic understanding of Zero-Knowledge Proofs (ZKP) and Virtual Machine architecture

Quick start

  1. First, make sure you have an existing Cargo project, or you can simply create a new one with cargo init
  2. Install the zkMemory package
cargo add zkmemory
  1. Create a small state machine program from our StandardMachine module
// Example: 256-bits RAM program using Halo2 proof engine
extern crate alloc;
use alloc::vec;
use ethnum::U256;
use rand::Rng;
use zkmemory::{
base::B256, config::DefaultConfig, constraints::helper::build_and_test_circuit,
default_state_machine::StandardStateMachine,
};

use zkmemory::{base::Base, default_state_machine::StandardInstruction, machine::AbstractMachine};
type CustomStateMachine = StandardStateMachine<B256, B256, 32, 32>;
type Instruction = StandardInstruction<CustomStateMachine, B256, B256, 32, 32>;

fn main() {
// Define the desired machine configuration
let mut machine = CustomStateMachine::new(DefaultConfig::default_config());
let base = machine.base_address();

let mut randomize = rand::thread_rng();
randomize.gen_range(u64::MAX / 2..u64::MAX);

// Define your desired program
let program = vec![
Instruction::Write(
base + B256::from(16),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
Instruction::Write(
base + B256::from(48),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
Instruction::Write(
base + B256::from(80),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
Instruction::Write(
base + B256::from(112),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
Instruction::Write(
base + B256::from(320),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
Instruction::Read(base + B256::from(16)),
Instruction::Write(
base + B256::from(10000),
B256::from(randomize.gen_range(u64::MAX / 2..u64::MAX)),
),
];
let mut trace_record = vec![];
// Execute the program
for instruction in program {
println!("Intruction: {:?}", instruction);
machine.exec(&instruction);
}
// Print the trace record (prettified), sorted by time in ascending order by default
for x in machine.trace().into_iter() {
println!("{:?}", x);
trace_record.push(x);
}

// If build_and_test_circuit does not panic, then the trace is valid.
build_and_test_circuit(trace_record, 10);
}

You can also see a more complex example on our public repo here.