Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add execution options for processor and prover #991

Merged
merged 3 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions air/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::String;
use core::fmt::{Display, Formatter};

// EXECUTION ERROR
// ================================================================================================
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

#[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 {}
8 changes: 6 additions & 2 deletions air/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -20,6 +20,8 @@ use constraints::{chiplets, range};
pub mod trace;
use trace::*;

mod errors;
mod options;
mod proof;

mod utils;
Expand All @@ -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,
Expand Down
169 changes: 169 additions & 0 deletions air/src/options.rs
Original file line number Diff line number Diff line change
@@ -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<ProvingOptions> for WinterProofOptions {
fn from(options: ProvingOptions) -> Self {
options.proof_options
}
}

// EXECUTION OPTIONS
// ================================================================================================

/// A set of parameters specifying execution parameters of the VM.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
///
/// - `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<u32>,
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<u32>,
expected_cycles: u32,
) -> Result<Self, ExecutionOptionsError> {
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,
})
}
}
100 changes: 1 addition & 99 deletions air/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// ================================================================================================
Expand Down Expand Up @@ -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<ProofOptions> for WinterProofOptions {
fn from(options: ProofOptions) -> Self {
options.options
}
}

// HASH FUNCTION
// ================================================================================================

Expand Down
Loading
Loading