diff --git a/air/src/errors.rs b/air/src/errors.rs new file mode 100644 index 0000000000..b8c9114653 --- /dev/null +++ b/air/src/errors.rs @@ -0,0 +1,27 @@ +use super::String; +use core::fmt::{Display, Formatter}; + +// EXECUTION ERROR +// ================================================================================================ + +#[derive(Debug)] +pub enum ExecutionOptionsError { + ExpectedCyclesTooBig(u32, u32), + OtherErrors(String), +} + +impl Display for ExecutionOptionsError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { + use ExecutionOptionsError::*; + + match self { + ExpectedCyclesTooBig(max, expected) => { + write!(f, "The expected number of cycles must be smaller than the maximum number of cycles: maximum is {max}, but expectd is {expected}") + } + OtherErrors(error) => write!(f, "{error}"), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ExecutionOptionsError {} diff --git a/air/src/lib.rs b/air/src/lib.rs index 4e5c1bcb5a..18c667e2ad 100644 --- a/air/src/lib.rs +++ b/air/src/lib.rs @@ -5,7 +5,7 @@ extern crate alloc; use vm_core::{ - utils::{collections::Vec, ByteWriter, Serializable}, + utils::{collections::Vec, string::String, ByteWriter, Serializable}, ExtensionOf, ProgramInfo, StackInputs, StackOutputs, ONE, ZERO, }; use winter_air::{ @@ -20,6 +20,8 @@ use constraints::{chiplets, range}; pub mod trace; use trace::*; +mod errors; +mod options; mod proof; mod utils; @@ -28,7 +30,9 @@ use utils::TransitionConstraintRange; // EXPORTS // ================================================================================================ -pub use proof::{ExecutionProof, HashFunction, ProofOptions}; +pub use errors::ExecutionOptionsError; +pub use options::{ExecutionOptions, ProvingOptions}; +pub use proof::{ExecutionProof, HashFunction}; pub use vm_core::{ utils::{DeserializationError, ToElements}, Felt, FieldElement, StarkField, diff --git a/air/src/options.rs b/air/src/options.rs new file mode 100644 index 0000000000..b94e3536c4 --- /dev/null +++ b/air/src/options.rs @@ -0,0 +1,169 @@ +use super::{ExecutionOptionsError, HashFunction}; +use winter_air::{FieldExtension, ProofOptions as WinterProofOptions}; + +// PROVING OPTIONS +// ================================================================================================ + +/// A set of parameters specifying how Miden VM execution proofs are to be generated. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct ProvingOptions { + pub exec_options: ExecutionOptions, + pub proof_options: WinterProofOptions, + pub hash_fn: HashFunction, +} + +impl ProvingOptions { + // CONSTRUCTOR + // -------------------------------------------------------------------------------------------- + + /// Creates a new instance of [ProvingOptions] from the specified parameters. + pub fn new( + num_queries: usize, + blowup_factor: usize, + grinding_factor: u32, + field_extension: FieldExtension, + fri_folding_factor: usize, + fri_remainder_max_degree: usize, + hash_fn: HashFunction, + ) -> Self { + let proof_options = WinterProofOptions::new( + num_queries, + blowup_factor, + grinding_factor, + field_extension, + fri_folding_factor, + fri_remainder_max_degree, + ); + let exec_options = ExecutionOptions::default(); + Self { + exec_options, + proof_options, + hash_fn, + } + } + + /// Creates a new preset instance of [ProvingOptions] targeting 96-bit security level. + /// + /// If `recursive` flag is set to true, proofs will be generated using an arithmetization- + /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification, + /// but may take significantly longer to generate. + pub fn with_96_bit_security(recursive: bool) -> Self { + if recursive { + let proof_options = WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 4, 7); + Self { + exec_options: ExecutionOptions::default(), + proof_options, + hash_fn: HashFunction::Rpo256, + } + } else { + let proof_options = + WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 8, 255); + Self { + exec_options: ExecutionOptions::default(), + proof_options, + hash_fn: HashFunction::Blake3_192, + } + } + } + + /// Creates a new preset instance of [ProvingOptions] targeting 128-bit security level. + /// + /// If `recursive` flag is set to true, proofs will be generated using an arithmetization- + /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification, + /// but may take significantly longer to generate. + pub fn with_128_bit_security(recursive: bool) -> Self { + if recursive { + let proof_options = WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 4, 7); + Self { + exec_options: ExecutionOptions::default(), + proof_options, + hash_fn: HashFunction::Rpo256, + } + } else { + let proof_options = WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 8, 255); + Self { + exec_options: ExecutionOptions::default(), + proof_options, + hash_fn: HashFunction::Blake3_256, + } + } + } + + /// Sets [ExecutionOptions] for this [ProvingOptions]. + /// + /// This sets the maximum number of cycles a program is allowed to execute as well as + /// the number of cycles the program is expected to execute. + pub fn with_execution_options(mut self, exec_options: ExecutionOptions) -> Self { + self.exec_options = exec_options; + self + } + + // PUBLIC ACCESSORS + // -------------------------------------------------------------------------------------------- + + /// Returns the hash function to be used in STARK proof generation. + pub const fn hash_fn(&self) -> HashFunction { + self.hash_fn + } + + /// Returns the execution options specified for this [ProvingOptions] + pub const fn execution_options(&self) -> &ExecutionOptions { + &self.exec_options + } +} + +impl Default for ProvingOptions { + fn default() -> Self { + Self::with_96_bit_security(false) + } +} + +impl From for WinterProofOptions { + fn from(options: ProvingOptions) -> Self { + options.proof_options + } +} + +// EXECUTION OPTIONS +// ================================================================================================ + +/// A set of parameters specifying execution parameters of the VM. +/// +/// - `max_cycles` specifies the maximum number of cycles a program is allowed to execute. +/// - `expected_cycles` specifies the number of cycles a program is expected to execute. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ExecutionOptions { + max_cycles: Option, + expected_cycles: u32, +} + +impl Default for ExecutionOptions { + fn default() -> Self { + ExecutionOptions { + max_cycles: None, + expected_cycles: 64, + } + } +} + +impl ExecutionOptions { + // CONSTRUCTOR + // -------------------------------------------------------------------------------------------- + + /// Creates a new instance of [ExecutionOptions] from the specified parameters. + pub fn new( + max_cycles: Option, + expected_cycles: u32, + ) -> Result { + if max_cycles.is_some_and(|max_cycles| max_cycles < expected_cycles) { + return Err(ExecutionOptionsError::ExpectedCyclesTooBig( + max_cycles.unwrap(), + expected_cycles, + )); + } + Ok(ExecutionOptions { + max_cycles, + expected_cycles, + }) + } +} diff --git a/air/src/proof.rs b/air/src/proof.rs index abca3611f3..7f83908a51 100644 --- a/air/src/proof.rs +++ b/air/src/proof.rs @@ -3,7 +3,7 @@ use vm_core::{ crypto::hash::{Blake3_192, Blake3_256, Hasher, Rpo256}, utils::collections::Vec, }; -use winter_air::{proof::StarkProof, FieldExtension, ProofOptions as WinterProofOptions}; +use winter_air::proof::StarkProof; // EXECUTION PROOF // ================================================================================================ @@ -81,104 +81,6 @@ impl ExecutionProof { } } -// PROOF OPTIONS -// ================================================================================================ - -/// A set of parameters specifying how Miden VM execution proofs are to be generated. -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct ProofOptions { - pub options: WinterProofOptions, - pub hash_fn: HashFunction, -} - -impl ProofOptions { - // CONSTRUCTOR - // -------------------------------------------------------------------------------------------- - - /// Creates a new instance of [ProofOptions] from the specified parameters. - pub fn new( - num_queries: usize, - blowup_factor: usize, - grinding_factor: u32, - field_extension: FieldExtension, - fri_folding_factor: usize, - fri_max_remainder_size: usize, - hash_fn: HashFunction, - ) -> Self { - let options = WinterProofOptions::new( - num_queries, - blowup_factor, - grinding_factor, - field_extension, - fri_folding_factor, - fri_max_remainder_size, - ); - Self { options, hash_fn } - } - - /// Creates a new preset instance of [ProofOptions] targeting 96-bit security level. - /// - /// If `recursive` flag is set to true, proofs will be generated using an arithmetization- - /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification, - /// but may take significantly longer to generate. - pub fn with_96_bit_security(recursive: bool) -> Self { - if recursive { - let options = WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 4, 7); - Self { - hash_fn: HashFunction::Rpo256, - options, - } - } else { - let options = WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 8, 255); - Self { - hash_fn: HashFunction::Blake3_192, - options, - } - } - } - - /// Creates a new preset instance of [ProofOptions] targeting 128-bit security level. - /// - /// If `recursive` flag is set to true, proofs will be generated using an arithmetization- - /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification, - /// but may take significantly longer to generate. - pub fn with_128_bit_security(recursive: bool) -> Self { - if recursive { - let options = WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 4, 7); - Self { - hash_fn: HashFunction::Rpo256, - options, - } - } else { - let options = WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 8, 255); - Self { - hash_fn: HashFunction::Blake3_256, - options, - } - } - } - - // PUBLIC ACCESSORS - // -------------------------------------------------------------------------------------------- - - /// Returns the hash function to be used in STARK proof generation. - pub const fn hash_fn(&self) -> HashFunction { - self.hash_fn - } -} - -impl Default for ProofOptions { - fn default() -> Self { - Self::with_96_bit_security(false) - } -} - -impl From for WinterProofOptions { - fn from(options: ProofOptions) -> Self { - options.options - } -} - // HASH FUNCTION // ================================================================================================ diff --git a/miden/README.md b/miden/README.md index 9efe8ec4c8..4d7ac47db9 100644 --- a/miden/README.md +++ b/miden/README.md @@ -42,6 +42,7 @@ The `execute_iter()` function returns a `VmStateIterator` which can be used to i For example: ```rust use miden::{Assembler, execute, execute_iter, MemAdviceProvider, StackInputs}; +use processor::ExecutionOptions; // instantiate the assembler let assembler = Assembler::default(); @@ -55,8 +56,11 @@ let stack_inputs = StackInputs::default(); // instantiate an empty advice provider let mut advice_provider = MemAdviceProvider::default(); +// instantiate default execution options +let exec_options = ExecutionOptions::default(); + // execute the program with no inputs -let trace = execute(&program, stack_inputs.clone(), &mut advice_provider).unwrap(); +let trace = execute(&program, stack_inputs.clone(), &mut advice_provider, exec_options).unwrap(); // now, execute the same program in debug mode and iterate over VM states for vm_state in execute_iter(&program, stack_inputs, advice_provider) { @@ -73,7 +77,7 @@ To execute a program on Miden VM and generate a proof that the program was execu * `program: &Program` - a reference to a Miden program to be executed. * `stack_inputs: StackInputs` - a set of public inputs with which to execute the program. * `advice_provider: AdviceProvider` - an instance of an advice provider that yields secret, non-deterministic inputs to the prover. -* `options: ProofOptions` - config parameters for proof generation. The default options target 96-bit security level. +* `options: ProvingOptions` - config parameters for proof generation. The default options target 96-bit security level. If the program is executed successfully, the function returns a tuple with 2 elements: @@ -83,7 +87,7 @@ If the program is executed successfully, the function returns a tuple with 2 ele #### Proof generation example Here is a simple example of executing a program which pushes two numbers onto the stack and computes their sum: ```rust -use miden::{Assembler, MemAdviceProvider, ProofOptions, prove, StackInputs}; +use miden::{Assembler, MemAdviceProvider, ProvingOptions, prove, StackInputs}; // instantiate the assembler let assembler = Assembler::default(); @@ -96,7 +100,7 @@ let (outputs, proof) = prove( &program, StackInputs::default(), // we won't provide any inputs MemAdviceProvider::default(), // we won't provide advice inputs - ProofOptions::default(), // we'll be using default options + ProvingOptions::default(), // we'll be using default options ) .unwrap(); @@ -155,7 +159,7 @@ add // stack state: 3 2 ``` Notice that except for the first 2 operations which initialize the stack, the sequence of `swap dup.1 add` operations repeats over and over. In fact, we can repeat these operations an arbitrary number of times to compute an arbitrary Fibonacci number. In Rust, it would look like this (this is actually a simplified version of the example in [fibonacci.rs](src/examples/src/fibonacci.rs)): ```rust -use miden::{Assembler, MemAdviceProvider, ProofOptions, StackInputs}; +use miden::{Assembler, MemAdviceProvider, ProvingOptions, StackInputs}; // set the number of terms to compute let n = 50; @@ -183,7 +187,7 @@ let (outputs, proof) = miden::prove( &program, stack_inputs, advice_provider, - ProofOptions::default(), // use default proof options + ProvingOptions::default(), // use default proving options ) .unwrap(); diff --git a/miden/benches/program_execution.rs b/miden/benches/program_execution.rs index bde9b3e4b6..51ba1f01b8 100644 --- a/miden/benches/program_execution.rs +++ b/miden/benches/program_execution.rs @@ -1,5 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use miden::{execute, Assembler, MemAdviceProvider, StackInputs}; +use processor::ExecutionOptions; use std::time::Duration; use stdlib::StdLibrary; @@ -18,7 +19,14 @@ fn program_execution(c: &mut Criterion) { .with_library(&StdLibrary::default()) .expect("failed to load stdlib"); let program = assembler.compile(source).expect("Failed to compile test source."); - bench.iter(|| execute(&program, StackInputs::default(), MemAdviceProvider::default())); + bench.iter(|| { + execute( + &program, + StackInputs::default(), + MemAdviceProvider::default(), + ExecutionOptions::default(), + ) + }); }); group.finish(); diff --git a/miden/src/cli/prove.rs b/miden/src/cli/prove.rs index b06dc55e5b..2f90800e57 100644 --- a/miden/src/cli/prove.rs +++ b/miden/src/cli/prove.rs @@ -1,5 +1,6 @@ use super::data::{Debug, InputFile, Libraries, OutputFile, ProgramFile, ProofFile}; -use miden::ProofOptions; +use miden::ProvingOptions; +use processor::{ExecutionOptions, ExecutionOptionsError}; use std::{io::Write, path::PathBuf, time::Instant}; use structopt::StructOpt; @@ -11,10 +12,22 @@ pub struct ProveCmd { #[structopt(short = "a", long = "assembly", parse(from_os_str))] assembly_file: PathBuf, + /// Number of cycles the program is expected to consume + #[structopt(short = "e", long = "exp-cycles", default_value = "64")] + expected_cycles: u32, + /// Path to input file #[structopt(short = "i", long = "input", parse(from_os_str))] input_file: Option, + /// Paths to .masl library files + #[structopt(short = "l", long = "libraries", parse(from_os_str))] + library_paths: Vec, + + /// Maximum number of cycles a program is allowed to consume + #[structopt(short = "m", long = "max-cycles")] + max_cycles: Option, + /// Number of outputs #[structopt(short = "n", long = "num-outputs", default_value = "16")] num_outputs: usize, @@ -27,24 +40,23 @@ pub struct ProveCmd { #[structopt(short = "p", long = "proof", parse(from_os_str))] proof_file: Option, - /// Security level for execution proofs generated by the VM - #[structopt(short = "s", long = "security", default_value = "96bits")] - security: String, - /// Enable generation of proofs suitable for recursive verification #[structopt(short = "r", long = "recursive")] recursive: bool, - /// Paths to .masl library files - #[structopt(short = "l", long = "libraries", parse(from_os_str))] - library_paths: Vec, + /// Security level for execution proofs generated by the VM + #[structopt(short = "s", long = "security", default_value = "96bits")] + security: String, } impl ProveCmd { - pub fn get_proof_options(&self) -> ProofOptions { + pub fn get_proof_options(&self) -> Result { + let exec_options = ExecutionOptions::new(self.max_cycles, self.expected_cycles)?; match self.security.as_str() { - "96bits" => ProofOptions::with_96_bit_security(self.recursive), - "128bits" => ProofOptions::with_128_bit_security(self.recursive), + "96bits" => Ok(ProvingOptions::with_96_bit_security(self.recursive) + .with_execution_options(exec_options)), + "128bits" => Ok(ProvingOptions::with_128_bit_security(self.recursive) + .with_execution_options(exec_options)), other => panic!("{} is not a valid security setting", other), } } @@ -77,9 +89,11 @@ impl ProveCmd { let stack_inputs = input_data.parse_stack_inputs()?; let advice_provider = input_data.parse_advice_provider()?; + let proving_options = self.get_proof_options().map_err(|err| format!("{err}"))?; + // execute program and generate proof let (stack_outputs, proof) = - prover::prove(&program, stack_inputs, advice_provider, self.get_proof_options()) + prover::prove(&program, stack_inputs, advice_provider, proving_options) .map_err(|err| format!("Failed to prove program - {:?}", err))?; println!( diff --git a/miden/src/cli/run.rs b/miden/src/cli/run.rs index e8423c0567..78535d63e9 100644 --- a/miden/src/cli/run.rs +++ b/miden/src/cli/run.rs @@ -1,4 +1,5 @@ use super::data::{Debug, InputFile, Libraries, OutputFile, ProgramFile}; +use processor::ExecutionOptions; use std::{path::PathBuf, time::Instant}; use structopt::StructOpt; @@ -8,18 +9,30 @@ pub struct RunCmd { /// Path to .masm assembly file #[structopt(short = "a", long = "assembly", parse(from_os_str))] assembly_file: PathBuf, + + /// Number of cycles the program is expected to consume + #[structopt(short = "e", long = "exp-cycles", default_value = "64")] + expected_cycles: u32, + /// Path to input file #[structopt(short = "i", long = "input", parse(from_os_str))] input_file: Option, + + /// Paths to .masl library files + #[structopt(short = "l", long = "libraries", parse(from_os_str))] + library_paths: Vec, + + /// Maximum number of cycles a program is allowed to consume + #[structopt(short = "m", long = "max-cycles")] + max_cycles: Option, + /// Number of ouptuts #[structopt(short = "n", long = "num-outputs", default_value = "16")] num_outputs: usize, + /// Path to output file #[structopt(short = "o", long = "output", parse(from_os_str))] output_file: Option, - /// Paths to .masl library files - #[structopt(short = "l", long = "libraries", parse(from_os_str))] - library_paths: Vec, } impl RunCmd { @@ -37,6 +50,10 @@ impl RunCmd { // load input data from file let input_data = InputFile::read(&self.input_file, &self.assembly_file)?; + // get execution options + let execution_options = ExecutionOptions::new(self.max_cycles, self.expected_cycles) + .map_err(|err| format!("{err}"))?; + // fetch the stack and program inputs from the arguments let stack_inputs = input_data.parse_stack_inputs()?; let advice_provider = input_data.parse_advice_provider()?; @@ -46,7 +63,7 @@ impl RunCmd { let now = Instant::now(); // execute program and generate outputs - let trace = processor::execute(&program, stack_inputs, advice_provider) + let trace = processor::execute(&program, stack_inputs, advice_provider, execution_options) .map_err(|err| format!("Failed to generate exection trace = {:?}", err))?; println!("done ({} steps in {} ms)", trace.get_trace_len(), now.elapsed().as_millis()); diff --git a/miden/src/examples/mod.rs b/miden/src/examples/mod.rs index 6cd9a1452a..93c0c50b9b 100644 --- a/miden/src/examples/mod.rs +++ b/miden/src/examples/mod.rs @@ -1,4 +1,4 @@ -use miden::{AdviceProvider, ExecutionProof, Program, ProgramInfo, ProofOptions, StackInputs}; +use miden::{AdviceProvider, ExecutionProof, Program, ProgramInfo, ProvingOptions, StackInputs}; use std::io::Write; use std::time::Instant; use structopt::StructOpt; @@ -49,10 +49,10 @@ pub enum ExampleType { } impl ExampleOptions { - pub fn get_proof_options(&self) -> ProofOptions { + pub fn get_proof_options(&self) -> ProvingOptions { match self.security.as_str() { - "96bits" => ProofOptions::with_96_bit_security(self.recursive), - "128bits" => ProofOptions::with_128_bit_security(self.recursive), + "96bits" => ProvingOptions::with_96_bit_security(self.recursive), + "128bits" => ProvingOptions::with_128_bit_security(self.recursive), other => panic!("{} is not a valid security level", other), } } @@ -139,7 +139,7 @@ where } = example; let (mut outputs, proof) = - miden::prove(&program, stack_inputs.clone(), advice_provider, ProofOptions::default()) + miden::prove(&program, stack_inputs.clone(), advice_provider, ProvingOptions::default()) .unwrap(); assert_eq!( diff --git a/miden/src/lib.rs b/miden/src/lib.rs index c4f052544d..816c1ca81b 100644 --- a/miden/src/lib.rs +++ b/miden/src/lib.rs @@ -12,6 +12,6 @@ pub use processor::{ }; pub use prover::{ math, prove, Digest, ExecutionProof, FieldExtension, HashFunction, InputError, Program, - ProofOptions, StackOutputs, StarkProof, Word, + ProvingOptions, StackOutputs, StarkProof, Word, }; pub use verifier::{verify, VerificationError}; diff --git a/processor/README.md b/processor/README.md index 1b89293af8..643c7e71a5 100644 --- a/processor/README.md +++ b/processor/README.md @@ -15,7 +15,7 @@ The `execute_iter()` function returns a `VmStateIterator` which can be used to i For example: ```Rust use miden_assembly::Assembler; -use miden_processor::{execute, execute_iter, MemAdviceProvider, StackInputs}; +use miden_processor::{execute, execute_iter, ExecutionOptions, MemAdviceProvider, StackInputs, }; // instantiate the assembler let assembler = Assembler::default(); @@ -29,11 +29,14 @@ let stack_inputs = StackInputs::default(); // instantiate an empty advice provider let mut advice_provider = MemAdviceProvider::default(); +// instantiate default execution options +let exec_options = ExecutionOptions::default(); + // execute the program with no inputs -let trace = execute(&program, stack_inputs.clone(), &mut advice_provider).unwrap(); +let trace = execute(&program, stack_inputs.clone(), &mut advice_provider, exec_options).unwrap(); // now, execute the same program in debug mode and iterate over VM states -for vm_state in execute_iter(&program, stack_inputs, advice_provider) { +for vm_state in execute_iter(&program, stack_inputs, advice_provider, exec_options) { match vm_state { Ok(vm_state) => println!("{:?}", vm_state), Err(_) => println!("something went terribly wrong!"), diff --git a/processor/src/lib.rs b/processor/src/lib.rs index be4b4c7e9a..c6eb96107f 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -8,6 +8,7 @@ use miden_air::trace::{ CHIPLETS_WIDTH, DECODER_TRACE_WIDTH, MIN_TRACE_LEN, RANGE_CHECK_TRACE_WIDTH, STACK_TRACE_WIDTH, SYS_TRACE_WIDTH, }; +pub use miden_air::{ExecutionOptions, ExecutionOptionsError}; pub use vm_core::{ chiplets::hasher::Digest, errors::InputError, utils::DeserializationError, AssemblyOp, Kernel, Operation, Program, ProgramInfo, QuadExtension, StackInputs, StackOutputs, Word, @@ -111,11 +112,13 @@ pub fn execute( program: &Program, stack_inputs: StackInputs, advice_provider: A, + _options: ExecutionOptions, ) -> Result where A: AdviceProvider, { let mut process = Process::new(program.kernel().clone(), stack_inputs, advice_provider); + // TODO: use ExecutionOptions to limit program execution let stack_outputs = process.execute(program)?; let trace = ExecutionTrace::new(process, stack_outputs); assert_eq!(&program.hash(), trace.program_hash(), "inconsistent program hash"); diff --git a/prover/README.md b/prover/README.md index 43193963a0..e26405a4d4 100644 --- a/prover/README.md +++ b/prover/README.md @@ -7,7 +7,7 @@ This crate exposes a `prove()` function which can be used to execute Miden VM pr * `program: &Program` - a reference to a Miden program to be executed. * `stack_inputs: StackInputs` - a set of public inputs with which to execute the program. * `advice_provider: AdviceProvider` - an instance of an advice provider that yields secret, non-deterministic inputs to the prover. -* `options: &ProofOptions` - config parameters for proof generation. The default options target 96-bit security level. +* `options: &ProvingOptions` - config parameters for proof generation. The default options target 96-bit security level. If the program is executed successfully, the function returns a tuple with 2 elements: @@ -18,7 +18,7 @@ If the program is executed successfully, the function returns a tuple with 2 ele Here is a simple example of executing a program which pushes two numbers onto the stack and computes their sum: ```Rust use miden_assembly::Assembler; -use miden_prover::{prove, ProofOptions, StackInputs, MemAdviceProvider}; +use miden_prover::{prove, ProvingOptions, StackInputs, MemAdviceProvider}; // instantiate the assembler let assembler = Assembler::default(); @@ -31,7 +31,7 @@ let (outputs, proof) = prove( &program, StackInputs::default(), // we won't provide any stack inputs MemAdviceProvider::default(), // we won't provide any advice values - &ProofOptions::default(), // we'll be using default options + &ProvingOptions::default(), // we'll be using default options ) .unwrap(); diff --git a/prover/src/gpu.rs b/prover/src/gpu.rs index a7811f6a54..6c15c40402 100644 --- a/prover/src/gpu.rs +++ b/prover/src/gpu.rs @@ -324,7 +324,7 @@ where #[cfg(test)] mod tests { use super::*; - use air::{ProofOptions, StarkField}; + use air::{ProvingOptions, StarkField}; use processor::{crypto::RpoRandomCoin, StackInputs, StackOutputs}; use winter_prover::math::fields::CubeExtension; @@ -404,7 +404,7 @@ mod tests { fn create_test_prover() -> ExecutionProver { ExecutionProver::new( - ProofOptions::with_128_bit_security(true), + ProvingOptions::with_128_bit_security(true), StackInputs::default(), StackOutputs::default(), ) diff --git a/prover/src/lib.rs b/prover/src/lib.rs index d3061fbce4..0f379e2634 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -24,7 +24,7 @@ mod gpu; // EXPORTS // ================================================================================================ -pub use air::{DeserializationError, ExecutionProof, FieldExtension, HashFunction, ProofOptions}; +pub use air::{DeserializationError, ExecutionProof, FieldExtension, HashFunction, ProvingOptions}; pub use processor::{ crypto, math, utils, AdviceInputs, AdviceProvider, Digest, ExecutionError, InputError, MemAdviceProvider, Program, StackInputs, StackOutputs, Word, @@ -34,8 +34,8 @@ pub use winter_prover::StarkProof; // PROVER // ================================================================================================ -/// Executes and proves the specified `program` and returns the result together with a STARK-based proof of -/// the program's execution. +/// Executes and proves the specified `program` and returns the result together with a STARK-based +/// proof of the program's execution. /// /// * `inputs` specifies the initial state of the stack as well as non-deterministic (secret) /// inputs for the VM. @@ -47,7 +47,7 @@ pub fn prove( program: &Program, stack_inputs: StackInputs, advice_provider: A, - options: ProofOptions, + options: ProvingOptions, ) -> Result<(StackOutputs, ExecutionProof), ExecutionError> where A: AdviceProvider, @@ -55,7 +55,12 @@ where // execute the program to create an execution trace #[cfg(feature = "std")] let now = Instant::now(); - let trace = processor::execute(program, stack_inputs.clone(), advice_provider)?; + let trace = processor::execute( + program, + stack_inputs.clone(), + advice_provider, + *options.execution_options(), + )?; #[cfg(feature = "std")] debug!( "Generated execution trace of {} columns and {} steps in {} ms", @@ -118,7 +123,7 @@ where R: RandomCoin, { pub fn new( - options: ProofOptions, + options: ProvingOptions, stack_inputs: StackInputs, stack_outputs: StackOutputs, ) -> Self { diff --git a/stdlib/tests/crypto/stark/mod.rs b/stdlib/tests/crypto/stark/mod.rs index a00031eccf..811aea89be 100644 --- a/stdlib/tests/crypto/stark/mod.rs +++ b/stdlib/tests/crypto/stark/mod.rs @@ -6,7 +6,7 @@ use crate::build_test; use assembly::Assembler; use miden_air::{FieldExtension, HashFunction, PublicInputs}; use test_utils::{ - prove, AdviceInputs, MemAdviceProvider, ProgramInfo, ProofOptions, StackInputs, VerifierError, + prove, AdviceInputs, MemAdviceProvider, ProgramInfo, ProvingOptions, StackInputs, VerifierError, }; // Note: Changes to MidenVM may cause this test to fail when some of the assumptions documented @@ -57,7 +57,7 @@ pub fn generate_recursive_verifier_data( let advice_provider = MemAdviceProvider::from(advice_inputs); let options = - ProofOptions::new(43, 8, 12, FieldExtension::Quadratic, 4, 7, HashFunction::Rpo256); + ProvingOptions::new(43, 8, 12, FieldExtension::Quadratic, 4, 7, HashFunction::Rpo256); let (stack_outputs, proof) = prove(&program, stack_inputs.clone(), advice_provider, options).unwrap(); diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 8fe87ddfa1..1846f2a7ef 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -19,10 +19,10 @@ pub use vm_core::chiplets::hasher::{hash_elements, STATE_WIDTH}; pub use assembly::{Library, MaslLibrary}; pub use processor::{ - AdviceInputs, AdviceProvider, ExecutionError, ExecutionTrace, Process, StackInputs, - VmStateIterator, + AdviceInputs, AdviceProvider, ExecutionError, ExecutionOptions, ExecutionTrace, Process, + StackInputs, VmStateIterator, }; -pub use prover::{prove, MemAdviceProvider, ProofOptions}; +pub use prover::{prove, MemAdviceProvider, ProvingOptions}; pub use test_case::test_case; pub use verifier::{ProgramInfo, VerifierError}; pub use vm_core::{ @@ -223,7 +223,12 @@ impl Test { pub fn execute(&self) -> Result { let program = self.compile(); let advice_provider = MemAdviceProvider::from(self.advice_inputs.clone()); - processor::execute(&program, self.stack_inputs.clone(), advice_provider) + processor::execute( + &program, + self.stack_inputs.clone(), + advice_provider, + ExecutionOptions::default(), + ) } /// Compiles the test's source to a Program and executes it with the tests inputs. Returns the @@ -244,9 +249,13 @@ impl Test { let stack_inputs = StackInputs::try_from_values(pub_inputs).unwrap(); let program = self.compile(); let advice_provider = MemAdviceProvider::from(self.advice_inputs.clone()); - let (mut stack_outputs, proof) = - prover::prove(&program, stack_inputs.clone(), advice_provider, ProofOptions::default()) - .unwrap(); + let (mut stack_outputs, proof) = prover::prove( + &program, + stack_inputs.clone(), + advice_provider, + ProvingOptions::default(), + ) + .unwrap(); let program_info = ProgramInfo::from(program); if test_fail {