miden_air/options.rs
1use super::{
2 trace::MIN_TRACE_LEN, ExecutionOptionsError, FieldExtension, HashFunction, WinterProofOptions,
3};
4
5// PROVING OPTIONS
6// ================================================================================================
7
8/// A set of parameters specifying how Miden VM execution proofs are to be generated.
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub struct ProvingOptions {
11 exec_options: ExecutionOptions,
12 proof_options: WinterProofOptions,
13 hash_fn: HashFunction,
14}
15
16impl ProvingOptions {
17 // CONSTANTS
18 // --------------------------------------------------------------------------------------------
19
20 /// Standard proof parameters for 96-bit conjectured security in non-recursive context.
21 pub const REGULAR_96_BITS: WinterProofOptions =
22 WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 8, 255);
23
24 /// Standard proof parameters for 128-bit conjectured security in non-recursive context.
25 pub const REGULAR_128_BITS: WinterProofOptions =
26 WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 8, 255);
27
28 /// Standard proof parameters for 96-bit conjectured security in recursive context.
29 pub const RECURSIVE_96_BITS: WinterProofOptions =
30 WinterProofOptions::new(27, 8, 16, FieldExtension::Quadratic, 4, 7);
31
32 /// Standard proof parameters for 128-bit conjectured security in recursive context.
33 pub const RECURSIVE_128_BITS: WinterProofOptions =
34 WinterProofOptions::new(27, 16, 21, FieldExtension::Cubic, 4, 7);
35
36 // CONSTRUCTORS
37 // --------------------------------------------------------------------------------------------
38
39 /// Creates a new instance of [ProvingOptions] from the specified parameters.
40 pub fn new(
41 num_queries: usize,
42 blowup_factor: usize,
43 grinding_factor: u32,
44 field_extension: FieldExtension,
45 fri_folding_factor: usize,
46 fri_remainder_max_degree: usize,
47 hash_fn: HashFunction,
48 ) -> Self {
49 let proof_options = WinterProofOptions::new(
50 num_queries,
51 blowup_factor,
52 grinding_factor,
53 field_extension,
54 fri_folding_factor,
55 fri_remainder_max_degree,
56 );
57 let exec_options = ExecutionOptions::default();
58 Self { exec_options, proof_options, hash_fn }
59 }
60
61 /// Creates a new preset instance of [ProvingOptions] targeting 96-bit security level.
62 ///
63 /// If `recursive` flag is set to true, proofs will be generated using an arithmetization-
64 /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification,
65 /// but may take significantly longer to generate.
66 pub fn with_96_bit_security(recursive: bool) -> Self {
67 if recursive {
68 Self {
69 exec_options: ExecutionOptions::default(),
70 proof_options: Self::RECURSIVE_96_BITS,
71 hash_fn: HashFunction::Rpo256,
72 }
73 } else {
74 Self {
75 exec_options: ExecutionOptions::default(),
76 proof_options: Self::REGULAR_96_BITS,
77 hash_fn: HashFunction::Blake3_192,
78 }
79 }
80 }
81
82 /// Creates a new preset instance of [ProvingOptions] targeting 96-bit security level,
83 /// using the RPX hashing function.
84 pub fn with_96_bit_security_rpx() -> Self {
85 Self {
86 exec_options: ExecutionOptions::default(),
87 proof_options: Self::RECURSIVE_96_BITS,
88 hash_fn: HashFunction::Rpx256,
89 }
90 }
91
92 /// Creates a new preset instance of [ProvingOptions] targeting 128-bit security level.
93 ///
94 /// If `recursive` flag is set to true, proofs will be generated using an arithmetization-
95 /// friendly hash function (RPO). Such proofs are well-suited for recursive proof verification,
96 /// but may take significantly longer to generate.
97 pub fn with_128_bit_security(recursive: bool) -> Self {
98 if recursive {
99 Self {
100 exec_options: ExecutionOptions::default(),
101 proof_options: Self::RECURSIVE_128_BITS,
102 hash_fn: HashFunction::Rpo256,
103 }
104 } else {
105 Self {
106 exec_options: ExecutionOptions::default(),
107 proof_options: Self::REGULAR_128_BITS,
108 hash_fn: HashFunction::Blake3_256,
109 }
110 }
111 }
112
113 /// Creates a new preset instance of [ProvingOptions] targeting 128-bit security level,
114 /// using the RPX hashing function.
115 pub fn with_128_bit_security_rpx() -> Self {
116 Self {
117 exec_options: ExecutionOptions::default(),
118 proof_options: Self::RECURSIVE_128_BITS,
119 hash_fn: HashFunction::Rpx256,
120 }
121 }
122
123 /// Sets [ExecutionOptions] for this [ProvingOptions].
124 ///
125 /// This sets the maximum number of cycles a program is allowed to execute as well as
126 /// the number of cycles the program is expected to execute.
127 pub fn with_execution_options(mut self, exec_options: ExecutionOptions) -> Self {
128 self.exec_options = exec_options;
129 self
130 }
131
132 // PUBLIC ACCESSORS
133 // --------------------------------------------------------------------------------------------
134
135 /// Returns the hash function to be used in STARK proof generation.
136 pub const fn hash_fn(&self) -> HashFunction {
137 self.hash_fn
138 }
139
140 /// Returns the execution options specified for this [ProvingOptions]
141 pub const fn execution_options(&self) -> &ExecutionOptions {
142 &self.exec_options
143 }
144}
145
146impl Default for ProvingOptions {
147 fn default() -> Self {
148 Self::with_96_bit_security(false)
149 }
150}
151
152impl From<ProvingOptions> for WinterProofOptions {
153 fn from(options: ProvingOptions) -> Self {
154 options.proof_options
155 }
156}
157
158// EXECUTION OPTIONS
159// ================================================================================================
160
161/// A set of parameters specifying execution parameters of the VM.
162///
163/// - `max_cycles` specifies the maximum number of cycles a program is allowed to execute.
164/// - `expected_cycles` specifies the number of cycles a program is expected to execute.
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
166pub struct ExecutionOptions {
167 max_cycles: u32,
168 expected_cycles: u32,
169 enable_tracing: bool,
170 enable_debugging: bool,
171}
172
173impl Default for ExecutionOptions {
174 fn default() -> Self {
175 ExecutionOptions {
176 max_cycles: u32::MAX,
177 expected_cycles: MIN_TRACE_LEN as u32,
178 enable_tracing: false,
179 enable_debugging: false,
180 }
181 }
182}
183
184impl ExecutionOptions {
185 // CONSTRUCTOR
186 // --------------------------------------------------------------------------------------------
187
188 /// Creates a new instance of [ExecutionOptions] from the specified parameters.
189 ///
190 /// If the `max_cycles` is `None` the maximum number of cycles will be set to `u32::MAX`
191 pub fn new(
192 max_cycles: Option<u32>,
193 expected_cycles: u32,
194 enable_tracing: bool,
195 enable_debugging: bool,
196 ) -> Result<Self, ExecutionOptionsError> {
197 let max_cycles = max_cycles.unwrap_or(u32::MAX);
198 if max_cycles < MIN_TRACE_LEN as u32 {
199 return Err(ExecutionOptionsError::MaxCycleNumTooSmall(expected_cycles));
200 }
201 if max_cycles < expected_cycles {
202 return Err(ExecutionOptionsError::ExpectedCyclesTooBig {
203 max_cycles,
204 expected_cycles,
205 });
206 }
207
208 // Round up the expected number of cycles to the next power of two. If it is smaller than
209 // MIN_TRACE_LEN -- pad expected number to it.
210 let expected_cycles = expected_cycles.next_power_of_two().max(MIN_TRACE_LEN as u32);
211
212 Ok(ExecutionOptions {
213 max_cycles,
214 expected_cycles,
215 enable_tracing,
216 enable_debugging,
217 })
218 }
219
220 /// Enables execution of the `trace` instructions.
221 pub fn with_tracing(mut self) -> Self {
222 self.enable_tracing = true;
223 self
224 }
225
226 /// Enables execution of programs in debug mode.
227 ///
228 /// In debug mode the VM does the following:
229 /// - Executes `debug` instructions (these are ignored in regular mode).
230 /// - Records additional info about program execution (e.g., keeps track of stack state at every
231 /// cycle of the VM) which enables stepping through the program forward and backward.
232 pub fn with_debugging(mut self) -> Self {
233 self.enable_debugging = true;
234 self
235 }
236
237 // PUBLIC ACCESSORS
238 // --------------------------------------------------------------------------------------------
239
240 /// Returns maximum number of cycles a program is allowed to execute for.
241 pub fn max_cycles(&self) -> u32 {
242 self.max_cycles
243 }
244
245 /// Returns the number of cycles a program is expected to take.
246 ///
247 /// This will serve as a hint to the VM for how much memory to allocate for a program's
248 /// execution trace and may result in performance improvements when the number of expected
249 /// cycles is equal to the number of actual cycles.
250 pub fn expected_cycles(&self) -> u32 {
251 self.expected_cycles
252 }
253
254 /// Returns a flag indicating whether the VM should execute `trace` instructions.
255 pub fn enable_tracing(&self) -> bool {
256 self.enable_tracing
257 }
258
259 /// Returns a flag indicating whether the VM should execute a program in debug mode.
260 pub fn enable_debugging(&self) -> bool {
261 self.enable_debugging
262 }
263}