Skip to content

Commit

Permalink
Merge pull request #149 from 0xPolygonMiden/dominik_add_merkle_inclus…
Browse files Browse the repository at this point in the history
…ion_proof_benchmark

Upgrading to Miden v0.6 and adding Merkle Inclusion benchmark
  • Loading branch information
Dominik1999 authored Oct 9, 2023
2 parents df0eeee + 7c2003b commit b5583ca
Show file tree
Hide file tree
Showing 7 changed files with 1,362 additions and 84 deletions.
6 changes: 4 additions & 2 deletions benchmarking-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.0", features = ["derive"] }
miden_vm = { version = "0.5.0", package = "miden-vm", features = ["concurrent"]}
clap = { version = "4.0.0", features = ["derive"] }
hex = { version = "0.4.0", default-features = false }
miden-stdlib = { version = "0.5.0", package = "miden-stdlib", default-features = false }
miden_vm = { version = "0.6.0", package = "miden-vm", features = ["concurrent"]}
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
serde_json = "1.0.48"
2 changes: 1 addition & 1 deletion benchmarking-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ and then
OR you run

```
cargo run -- -e fibonacci
cargo run --release -- -e fibonacci
```

You can pass two additional parameters to the CLI `security` and `output`. `security` can be `"high"` for 128-bit security and will default to 96-bit. `output` defines the number of stack outputs the program returns. It defaults to 1.
Expand Down
109 changes: 28 additions & 81 deletions benchmarking-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,10 @@
mod utils_input;
mod utils_program;
use clap::Parser;
use miden_vm::{
AdviceInputs, Assembler, Kernel, MemAdviceProvider, ProgramInfo, ProofOptions, StackInputs,
};
use miden_vm::ProofOptions;
use std::fs;
use std::time::Instant;

#[derive(serde::Deserialize, serde::Serialize)]
pub struct InputFile {
pub operand_stack: Vec<String>,
pub advice_stack: Option<Vec<String>>,
}

// Parse operand_stack vector of strings to a vector of u64
fn parse_advice_provider(advice_input_file: &InputFile) -> Result<MemAdviceProvider, String> {
let tape = advice_input_file
.advice_stack
.as_ref()
.map(Vec::as_slice)
.unwrap_or(&[])
.iter()
.map(|v| v.parse::<u64>().map_err(|e| e.to_string()))
.collect::<Result<Vec<_>, _>>()?;
let advice_inputs = AdviceInputs::default()
.with_stack_values(tape)
.map_err(|e| e.to_string())?;
Ok(MemAdviceProvider::from(advice_inputs))
}

// Parse advice_stack vector of strings to a vector of u64
fn parse_stack_inputs(stack_input_file: &InputFile) -> Result<StackInputs, String> {
let stack_inputs = stack_input_file
.operand_stack
.iter()
.map(|v| v.parse::<u64>().map_err(|e| e.to_string()))
.collect::<Result<Vec<_>, _>>()?;

StackInputs::try_from_values(stack_inputs).map_err(|e| e.to_string())
}

#[derive(Parser)]
#[clap(
author = "Polygon Miden",
Expand Down Expand Up @@ -89,78 +56,58 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// let's read the program
let program_string = fs::read_to_string(format!("../examples/{}.masm", &args.example))?;

// let's read the input files
let input_string = fs::read_to_string(format!("../examples/{}.inputs", &args.example))
.map_err(|err| format!("Failed to open input file `{}` - {}", &args.example, err))?;
let inputs_des: InputFile = serde_json::from_str(&input_string)
.map_err(|err| format!("Failed to deserialize input data - {}", err))
.unwrap();

let advice_provider = parse_advice_provider(&inputs_des).unwrap();
let stack_input = parse_stack_inputs(&inputs_des).unwrap();
let input_string = fs::read_to_string(format!("../examples/{}.inputs", &args.example))?;
let mut inputs = utils_input::Inputs::new();
inputs
.deserialize_inputs(input_string.as_str())
.map_err(|err| format!("Failed to deserialize inputs - {:?}", err))?;

// Compilation time
let now = Instant::now();
let assembler = Assembler::default();
let program = assembler
.compile(&program_string)
.expect("Could not compile source");
let mut program = utils_program::MidenProgram::new(program_string.as_str());
program
.compile_program()
.map_err(|err| format!("Failed to compile program - {:?}", err))?;

println! {"Compilation Time (cold): {} ms", now.elapsed().as_millis()}

let program_hash = program.hash();
let kernel = Kernel::default();
let program_info = ProgramInfo::new(program_hash, kernel);

let now = Instant::now();
let _program2 = assembler
.compile(&program_string)
.expect("Could not compile source");

println! {"Compilation Time (hot): {} ms", now.elapsed().as_millis()}

let stack_input_cloned = stack_input.clone();
let advice_provider_cloned = advice_provider.clone();
let program_to_run = program.program.clone().unwrap();

// Execution time
let now = Instant::now();
let trace = miden_vm::execute(&program, stack_input_cloned, advice_provider_cloned)
.map_err(|err| format!("Failed to generate exection trace = {:?}", err))
.unwrap();
let trace = miden_vm::execute(
&program_to_run,
inputs.stack_inputs.clone(),
inputs.advice_provider.clone(),
)
.map_err(|err| format!("Failed to generate exection trace = {:?}", err))
.unwrap();

println! {"Execution Time: {} steps in {} ms", trace.get_trace_len(), now.elapsed().as_millis()}

// Proving time
let proof_options = if args.security == "high" {
ProofOptions::with_128_bit_security()
ProofOptions::with_128_bit_security(false)
} else {
ProofOptions::with_96_bit_security()
ProofOptions::with_96_bit_security(false)
};

// let's clone the stack_input and advice_provider
// because they are moved into the closure
let stack_input_cloned = stack_input.clone();
let advice_provider_cloned = advice_provider.clone();

let now = Instant::now();
let (output, proof) = miden_vm::prove(
&program,
stack_input_cloned,
advice_provider_cloned,
&program.program.unwrap(),
inputs.stack_inputs.clone(),
inputs.advice_provider,
proof_options,
)
.expect("Proving failed");

println! {"Proving Time: {} ms", now.elapsed().as_millis()}

// let's clone the stack_input and output
// because they are moved into the closure
let stack_input_cloned = stack_input.clone();
let output_cloned = output.clone();

// Verification time
let program_info = program.program_info.unwrap();

let now = Instant::now();
miden_vm::verify(program_info, stack_input_cloned, output_cloned, proof)
miden_vm::verify(program_info, inputs.stack_inputs, output.clone(), proof)
.map_err(|err| format!("Program failed verification! - {}", err))?;

println! {"Verification Time: {} ms", now.elapsed().as_millis()}
Expand Down
Loading

0 comments on commit b5583ca

Please sign in to comment.