1use crate::air_private_input::PrivateInput;
2use crate::math_utils::safe_div_usize;
3use crate::stdlib::prelude::*;
4use crate::types::builtin_name::BuiltinName;
5use crate::types::instance_definitions::bitwise_instance_def::{
6 CELLS_PER_BITWISE, INPUT_CELLS_PER_BITWISE,
7};
8use crate::types::instance_definitions::builtins_instance_def::BUILTIN_INSTANCES_PER_COMPONENT;
9use crate::types::instance_definitions::ec_op_instance_def::{
10 CELLS_PER_EC_OP, INPUT_CELLS_PER_EC_OP,
11};
12use crate::types::instance_definitions::ecdsa_instance_def::CELLS_PER_SIGNATURE;
13use crate::types::instance_definitions::keccak_instance_def::{
14 CELLS_PER_KECCAK, INPUT_CELLS_PER_KECCAK, KECCAK_INSTANCES_PER_COMPONENT,
15};
16use crate::types::instance_definitions::mod_instance_def::CELLS_PER_MOD;
17use crate::types::instance_definitions::pedersen_instance_def::{
18 CELLS_PER_HASH, INPUT_CELLS_PER_HASH,
19};
20use crate::types::instance_definitions::poseidon_instance_def::{
21 CELLS_PER_POSEIDON, INPUT_CELLS_PER_POSEIDON,
22};
23use crate::types::instance_definitions::range_check_instance_def::CELLS_PER_RANGE_CHECK;
24use crate::types::relocatable::{MaybeRelocatable, Relocatable};
25use crate::vm::errors::memory_errors::{self, InsufficientAllocatedCellsError, MemoryError};
26use crate::vm::errors::runner_errors::RunnerError;
27use crate::vm::errors::vm_errors::VirtualMachineError;
28use crate::vm::vm_core::VirtualMachine;
29use crate::vm::vm_memory::memory::Memory;
30use crate::vm::vm_memory::memory_segments::MemorySegmentManager;
31
32mod bitwise;
33mod ec_op;
34mod hash;
35mod keccak;
36mod modulo;
37mod output;
38mod poseidon;
39mod range_check;
40mod segment_arena;
41mod signature;
42
43pub use self::keccak::KeccakBuiltinRunner;
44pub(crate) use self::range_check::{RC_N_PARTS_96, RC_N_PARTS_STANDARD};
45use self::segment_arena::ARENA_BUILTIN_SIZE;
46pub use bitwise::BitwiseBuiltinRunner;
47pub use ec_op::EcOpBuiltinRunner;
48pub use hash::HashBuiltinRunner;
49pub use modulo::ModBuiltinRunner;
50use num_integer::{div_ceil, div_floor};
51pub use output::{OutputBuiltinRunner, OutputBuiltinState};
52pub use poseidon::PoseidonBuiltinRunner;
53pub use range_check::RangeCheckBuiltinRunner;
54pub use segment_arena::SegmentArenaBuiltinRunner;
55pub use signature::SignatureBuiltinRunner;
56
57use super::cairo_pie::BuiltinAdditionalData;
58
59#[derive(Debug, Clone)]
68pub enum BuiltinRunner {
69 Bitwise(BitwiseBuiltinRunner),
70 EcOp(EcOpBuiltinRunner),
71 Hash(HashBuiltinRunner),
72 Output(OutputBuiltinRunner),
73 RangeCheck(RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>),
74 RangeCheck96(RangeCheckBuiltinRunner<RC_N_PARTS_96>),
75 Keccak(KeccakBuiltinRunner),
76 Signature(SignatureBuiltinRunner),
77 Poseidon(PoseidonBuiltinRunner),
78 SegmentArena(SegmentArenaBuiltinRunner),
79 Mod(ModBuiltinRunner),
80}
81
82impl BuiltinRunner {
83 pub fn initialize_segments(&mut self, segments: &mut MemorySegmentManager) {
85 match *self {
86 BuiltinRunner::Bitwise(ref mut bitwise) => bitwise.initialize_segments(segments),
87 BuiltinRunner::EcOp(ref mut ec) => ec.initialize_segments(segments),
88 BuiltinRunner::Hash(ref mut hash) => hash.initialize_segments(segments),
89 BuiltinRunner::Output(ref mut output) => output.initialize_segments(segments),
90 BuiltinRunner::RangeCheck(ref mut range_check) => {
91 range_check.initialize_segments(segments)
92 }
93 BuiltinRunner::RangeCheck96(ref mut range_check) => {
94 range_check.initialize_segments(segments)
95 }
96 BuiltinRunner::Keccak(ref mut keccak) => keccak.initialize_segments(segments),
97 BuiltinRunner::Signature(ref mut signature) => signature.initialize_segments(segments),
98 BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.initialize_segments(segments),
99 BuiltinRunner::SegmentArena(ref mut segment_arena) => {
100 segment_arena.initialize_segments(segments)
101 }
102 BuiltinRunner::Mod(ref mut modulo) => modulo.initialize_segments(segments),
103 }
104 }
105
106 pub fn initial_stack(&self) -> Vec<MaybeRelocatable> {
107 match *self {
108 BuiltinRunner::Bitwise(ref bitwise) => bitwise.initial_stack(),
109 BuiltinRunner::EcOp(ref ec) => ec.initial_stack(),
110 BuiltinRunner::Hash(ref hash) => hash.initial_stack(),
111 BuiltinRunner::Output(ref output) => output.initial_stack(),
112 BuiltinRunner::RangeCheck(ref range_check) => range_check.initial_stack(),
113 BuiltinRunner::RangeCheck96(ref range_check) => range_check.initial_stack(),
114 BuiltinRunner::Keccak(ref keccak) => keccak.initial_stack(),
115 BuiltinRunner::Signature(ref signature) => signature.initial_stack(),
116 BuiltinRunner::Poseidon(ref poseidon) => poseidon.initial_stack(),
117 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.initial_stack(),
118 BuiltinRunner::Mod(ref modulo) => modulo.initial_stack(),
119 }
120 }
121
122 pub fn final_stack(
124 &mut self,
125 segments: &MemorySegmentManager,
126 pointer: Relocatable,
127 ) -> Result<Relocatable, RunnerError> {
128 if let BuiltinRunner::Output(output) = self {
129 return output.final_stack(segments, pointer);
130 }
131 if self.included() {
132 let stop_pointer_addr =
133 (pointer - 1).map_err(|_| RunnerError::NoStopPointer(Box::new(self.name())))?;
134 let stop_pointer = segments
135 .memory
136 .get_relocatable(stop_pointer_addr)
137 .map_err(|_| RunnerError::NoStopPointer(Box::new(self.name())))?;
138 if self.base() as isize != stop_pointer.segment_index {
139 return Err(RunnerError::InvalidStopPointerIndex(Box::new((
140 self.name(),
141 stop_pointer,
142 self.base(),
143 ))));
144 }
145 let stop_ptr = stop_pointer.offset;
146 let mut num_instances = self.get_used_instances(segments)?;
147 if matches!(self, BuiltinRunner::SegmentArena(_)) {
148 num_instances += 1;
152 }
153 let used = num_instances * self.cells_per_instance() as usize;
154 if stop_ptr != used {
155 return Err(RunnerError::InvalidStopPointer(Box::new((
156 self.name(),
157 Relocatable::from((self.base() as isize, used)),
158 Relocatable::from((self.base() as isize, stop_ptr)),
159 ))));
160 }
161 self.set_stop_ptr(stop_ptr);
162 Ok(stop_pointer_addr)
163 } else {
164 self.set_stop_ptr(0);
165 Ok(pointer)
166 }
167 }
168
169 pub fn get_allocated_memory_units(
171 &self,
172 vm: &VirtualMachine,
173 ) -> Result<usize, memory_errors::MemoryError> {
174 Ok(self.get_allocated_instances(vm)? * self.cells_per_instance() as usize)
175 }
176
177 pub fn get_allocated_instances(
179 &self,
180 vm: &VirtualMachine,
181 ) -> Result<usize, memory_errors::MemoryError> {
182 match *self {
183 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => Ok(0),
184 _ => {
185 match self.ratio() {
186 None => {
187 let instances: usize =
189 self.get_used_cells(&vm.segments)? / self.cells_per_instance() as usize;
190 let needed_components = instances / self.instances_per_component() as usize;
191
192 let components = if needed_components > 0 {
193 needed_components.next_power_of_two()
194 } else {
195 0
196 };
197 Ok(self.instances_per_component() as usize * components)
198 }
199 Some(0) => Ok(0),
201 Some(ratio) => {
202 let min_step_num = (ratio * self.instances_per_component()) as usize;
203 let min_step = if let Some(ratio_den) = self.ratio_den() {
204 div_ceil(min_step_num, ratio_den as usize)
205 } else {
206 min_step_num
207 };
208
209 if vm.current_step < min_step {
210 return Err(InsufficientAllocatedCellsError::MinStepNotReached(
211 Box::new((min_step, self.name())),
212 )
213 .into());
214 };
215
216 let allocated_instances = if let Some(ratio_den) = self.ratio_den() {
217 safe_div_usize(vm.current_step * ratio_den as usize, ratio as usize)
218 .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?
219 } else {
220 safe_div_usize(vm.current_step, ratio as usize)
221 .map_err(|_| MemoryError::ErrorCalculatingMemoryUnits)?
222 };
223 Ok(allocated_instances)
224 }
225 }
226 }
227 }
228 }
229
230 fn included(&self) -> bool {
232 match *self {
233 BuiltinRunner::Bitwise(ref bitwise) => bitwise.included,
234 BuiltinRunner::EcOp(ref ec) => ec.included,
235 BuiltinRunner::Hash(ref hash) => hash.included,
236 BuiltinRunner::Output(ref output) => output.included,
237 BuiltinRunner::RangeCheck(ref range_check) => range_check.included,
238 BuiltinRunner::RangeCheck96(ref range_check) => range_check.included,
239 BuiltinRunner::Keccak(ref keccak) => keccak.included,
240 BuiltinRunner::Signature(ref signature) => signature.included,
241 BuiltinRunner::Poseidon(ref poseidon) => poseidon.included,
242 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.included,
243 BuiltinRunner::Mod(ref modulo) => modulo.included,
244 }
245 }
246
247 pub fn base(&self) -> usize {
249 match *self {
250 BuiltinRunner::Bitwise(ref bitwise) => bitwise.base(),
251 BuiltinRunner::EcOp(ref ec) => ec.base(),
252 BuiltinRunner::Hash(ref hash) => hash.base(),
253 BuiltinRunner::Output(ref output) => output.base(),
254 BuiltinRunner::RangeCheck(ref range_check) => range_check.base(),
255 BuiltinRunner::RangeCheck96(ref range_check) => range_check.base(),
256 BuiltinRunner::Keccak(ref keccak) => keccak.base(),
257 BuiltinRunner::Signature(ref signature) => signature.base(),
258 BuiltinRunner::Poseidon(ref poseidon) => poseidon.base(),
259 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.base(),
261 BuiltinRunner::Mod(ref modulo) => modulo.base(),
262 }
263 }
264
265 pub fn ratio(&self) -> Option<u32> {
266 match self {
267 BuiltinRunner::Bitwise(bitwise) => bitwise.ratio(),
268 BuiltinRunner::EcOp(ec) => ec.ratio(),
269 BuiltinRunner::Hash(hash) => hash.ratio(),
270 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => None,
271 BuiltinRunner::RangeCheck(range_check) => range_check.ratio(),
272 BuiltinRunner::RangeCheck96(range_check) => range_check.ratio(),
273 BuiltinRunner::Keccak(keccak) => keccak.ratio(),
274 BuiltinRunner::Signature(ref signature) => signature.ratio(),
275 BuiltinRunner::Poseidon(poseidon) => poseidon.ratio(),
276 BuiltinRunner::Mod(ref modulo) => modulo.ratio(),
277 }
278 }
279
280 pub fn ratio_den(&self) -> Option<u32> {
281 match self {
282 BuiltinRunner::RangeCheck(range_check) => range_check.ratio_den(),
283 BuiltinRunner::RangeCheck96(range_check) => range_check.ratio_den(),
284 BuiltinRunner::Mod(modulo) => modulo.ratio_den(),
285 _ => None,
286 }
287 }
288
289 pub fn add_validation_rule(&self, memory: &mut Memory) {
290 match *self {
291 BuiltinRunner::RangeCheck(ref range_check) => range_check.add_validation_rule(memory),
292 BuiltinRunner::RangeCheck96(ref range_check) => range_check.add_validation_rule(memory),
293 BuiltinRunner::Signature(ref signature) => signature.add_validation_rule(memory),
294 BuiltinRunner::Poseidon(ref poseidon) => poseidon.add_validation_rule(memory),
295 _ => {}
296 }
297 }
298
299 pub fn deduce_memory_cell(
300 &self,
301 address: Relocatable,
302 memory: &Memory,
303 ) -> Result<Option<MaybeRelocatable>, RunnerError> {
304 match *self {
305 BuiltinRunner::Bitwise(ref bitwise) => bitwise.deduce_memory_cell(address, memory),
306 BuiltinRunner::EcOp(ref ec) => ec.deduce_memory_cell(address, memory),
307 BuiltinRunner::Hash(ref hash) => hash.deduce_memory_cell(address, memory),
308 BuiltinRunner::Keccak(ref keccak) => keccak.deduce_memory_cell(address, memory),
309 BuiltinRunner::Poseidon(ref poseidon) => poseidon.deduce_memory_cell(address, memory),
310 _ => Ok(None),
311 }
312 }
313
314 pub fn get_memory_segment_addresses(&self) -> (usize, Option<usize>) {
315 (self.base(), self.stop_ptr())
316 }
317
318 pub fn get_used_cells(&self, segments: &MemorySegmentManager) -> Result<usize, MemoryError> {
319 match self {
320 BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_used_cells(segments),
321 BuiltinRunner::EcOp(ref ec) => ec.get_used_cells(segments),
322 BuiltinRunner::Hash(ref hash) => hash.get_used_cells(segments),
323 BuiltinRunner::Output(ref output) => output.get_used_cells(segments),
324 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_cells(segments),
325 BuiltinRunner::RangeCheck96(ref range_check) => range_check.get_used_cells(segments),
326 BuiltinRunner::Keccak(ref keccak) => keccak.get_used_cells(segments),
327 BuiltinRunner::Signature(ref signature) => signature.get_used_cells(segments),
328 BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_cells(segments),
329 BuiltinRunner::SegmentArena(ref segment_arena) => {
330 segment_arena.get_used_cells(segments)
331 }
332 BuiltinRunner::Mod(ref modulo) => modulo.get_used_cells(segments),
333 }
334 }
335
336 pub fn get_used_instances(
337 &self,
338 segments: &MemorySegmentManager,
339 ) -> Result<usize, MemoryError> {
340 match self {
341 BuiltinRunner::Bitwise(ref bitwise) => bitwise.get_used_instances(segments),
342 BuiltinRunner::EcOp(ref ec) => ec.get_used_instances(segments),
343 BuiltinRunner::Hash(ref hash) => hash.get_used_instances(segments),
344 BuiltinRunner::Output(ref output) => output.get_used_instances(segments),
345 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_used_instances(segments),
346 BuiltinRunner::RangeCheck96(ref range_check) => {
347 range_check.get_used_instances(segments)
348 }
349 BuiltinRunner::Keccak(ref keccak) => keccak.get_used_instances(segments),
350 BuiltinRunner::Signature(ref signature) => signature.get_used_instances(segments),
351 BuiltinRunner::Poseidon(ref poseidon) => poseidon.get_used_instances(segments),
352 BuiltinRunner::SegmentArena(ref segment_arena) => {
353 segment_arena.get_used_instances(segments)
354 }
355 BuiltinRunner::Mod(modulo) => modulo.get_used_instances(segments),
356 }
357 }
358
359 pub fn get_range_check_usage(&self, memory: &Memory) -> Option<(usize, usize)> {
360 match self {
361 BuiltinRunner::RangeCheck(ref range_check) => range_check.get_range_check_usage(memory),
362 BuiltinRunner::RangeCheck96(ref range_check) => {
363 range_check.get_range_check_usage(memory)
364 }
365 _ => None,
366 }
367 }
368
369 pub fn get_used_perm_range_check_units(
371 &self,
372 vm: &VirtualMachine,
373 ) -> Result<usize, MemoryError> {
374 match self {
375 BuiltinRunner::RangeCheck(range_check) => {
376 let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?;
377 Ok(used_cells * range_check.n_parts() as usize)
378 }
379 BuiltinRunner::RangeCheck96(range_check) => {
380 let (used_cells, _) = self.get_used_cells_and_allocated_size(vm)?;
381 Ok(used_cells * range_check.n_parts() as usize)
382 }
383 _ => Ok(0),
384 }
385 }
386
387 pub fn get_used_diluted_check_units(&self, diluted_spacing: u32, diluted_n_bits: u32) -> usize {
388 match self {
389 BuiltinRunner::Bitwise(ref bitwise) => {
390 bitwise.get_used_diluted_check_units(diluted_spacing, diluted_n_bits)
391 }
392 BuiltinRunner::Keccak(ref keccak) => {
393 keccak.get_used_diluted_check_units(diluted_n_bits)
394 }
395 _ => 0,
396 }
397 }
398
399 fn cells_per_instance(&self) -> u32 {
400 match self {
401 BuiltinRunner::Bitwise(_) => CELLS_PER_BITWISE,
402 BuiltinRunner::EcOp(_) => CELLS_PER_EC_OP,
403 BuiltinRunner::Hash(_) => CELLS_PER_HASH,
404 BuiltinRunner::RangeCheck(_) | BuiltinRunner::RangeCheck96(_) => CELLS_PER_RANGE_CHECK,
405 BuiltinRunner::Output(_) => 0,
406 BuiltinRunner::Keccak(_) => CELLS_PER_KECCAK,
407 BuiltinRunner::Signature(_) => CELLS_PER_SIGNATURE,
408 BuiltinRunner::Poseidon(_) => CELLS_PER_POSEIDON,
409 BuiltinRunner::SegmentArena(_) => ARENA_BUILTIN_SIZE,
410 BuiltinRunner::Mod(_) => CELLS_PER_MOD,
411 }
412 }
413
414 fn n_input_cells(&self) -> u32 {
415 match self {
416 BuiltinRunner::Bitwise(_) => INPUT_CELLS_PER_BITWISE,
417 BuiltinRunner::EcOp(_) => INPUT_CELLS_PER_EC_OP,
418 BuiltinRunner::Hash(_) => INPUT_CELLS_PER_HASH,
419 BuiltinRunner::RangeCheck(_) | BuiltinRunner::RangeCheck96(_) => CELLS_PER_RANGE_CHECK,
420 BuiltinRunner::Output(_) => 0,
421 BuiltinRunner::Keccak(_) => INPUT_CELLS_PER_KECCAK,
422 BuiltinRunner::Signature(_) => CELLS_PER_SIGNATURE,
423 BuiltinRunner::Poseidon(_) => INPUT_CELLS_PER_POSEIDON,
424 BuiltinRunner::SegmentArena(_) => ARENA_BUILTIN_SIZE,
425 BuiltinRunner::Mod(_) => CELLS_PER_MOD,
426 }
427 }
428
429 fn instances_per_component(&self) -> u32 {
430 match self {
431 BuiltinRunner::Keccak(_) => KECCAK_INSTANCES_PER_COMPONENT,
432 _ => BUILTIN_INSTANCES_PER_COMPONENT,
433 }
434 }
435
436 pub fn name(&self) -> BuiltinName {
437 match self {
438 BuiltinRunner::Bitwise(_) => BuiltinName::bitwise,
439 BuiltinRunner::EcOp(_) => BuiltinName::ec_op,
440 BuiltinRunner::Hash(_) => BuiltinName::pedersen,
441 BuiltinRunner::RangeCheck(_) => BuiltinName::range_check,
442 BuiltinRunner::RangeCheck96(_) => BuiltinName::range_check96,
443 BuiltinRunner::Output(_) => BuiltinName::output,
444 BuiltinRunner::Keccak(_) => BuiltinName::keccak,
445 BuiltinRunner::Signature(_) => BuiltinName::ecdsa,
446 BuiltinRunner::Poseidon(_) => BuiltinName::poseidon,
447 BuiltinRunner::SegmentArena(_) => BuiltinName::segment_arena,
448 BuiltinRunner::Mod(b) => b.name(),
449 }
450 }
451
452 pub fn run_security_checks(&self, vm: &VirtualMachine) -> Result<(), VirtualMachineError> {
453 if let BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) = self {
454 return Ok(());
455 }
456 if let BuiltinRunner::Mod(modulo) = self {
457 modulo.run_additional_security_checks(vm)?;
458 }
459 let cells_per_instance = self.cells_per_instance() as usize;
460 let n_input_cells = self.n_input_cells() as usize;
461 let builtin_segment_index = self.base();
462 let builtin_segment = match vm.segments.memory.data.get(builtin_segment_index) {
464 Some(segment) if !segment.is_empty() => segment,
465 _ => return Ok(()),
466 };
467 let offset_max = builtin_segment.len().saturating_sub(1);
472 let offset_len = builtin_segment.iter().filter(|x| x.is_some()).count();
474 let n = match offset_len {
475 0 => 0,
476 _ => div_floor(offset_max, cells_per_instance) + 1,
477 };
478 if n > div_floor(offset_len, n_input_cells) {
481 return Err(MemoryError::MissingMemoryCells(Box::new(self.name())).into());
482 }
483 let mut missing_offsets = Vec::with_capacity(n);
485 for i in 0..n {
487 for j in 0..n_input_cells {
488 let offset = cells_per_instance * i + j;
489 if builtin_segment
490 .get(offset)
491 .filter(|x| x.is_some())
492 .is_none()
493 {
494 missing_offsets.push(offset)
495 }
496 }
497 }
498 if !missing_offsets.is_empty() {
499 return Err(MemoryError::MissingMemoryCellsWithOffsets(Box::new((
500 self.name(),
501 missing_offsets,
502 )))
503 .into());
504 }
505 for i in 0..n {
508 for j in n_input_cells..cells_per_instance {
509 let offset = cells_per_instance * i + j;
510 if builtin_segment
511 .get(offset)
512 .filter(|x| x.is_some())
513 .is_none()
514 {
515 vm.verify_auto_deductions_for_addr(
516 Relocatable::from((builtin_segment_index as isize, offset)),
517 self,
518 )?;
519 }
520 }
521 }
522 Ok(())
523 }
524
525 pub fn get_used_cells_and_allocated_size(
526 &self,
527 vm: &VirtualMachine,
528 ) -> Result<(usize, usize), MemoryError> {
529 match self {
530 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => {
531 let used = self.get_used_cells(&vm.segments)?;
532 Ok((used, used))
533 }
534 _ => {
535 let used_cells = self.get_used_cells(&vm.segments)?;
536 if vm.disable_trace_padding {
537 let num_instances = self.get_used_instances(&vm.segments)?;
540 let padded_used_cells = if num_instances > 0 {
541 num_instances.next_power_of_two() * self.cells_per_instance() as usize
542 } else {
543 0
544 };
545 Ok((used_cells, padded_used_cells))
546 } else {
547 let size = self.get_allocated_memory_units(vm)?;
548 if used_cells > size {
549 return Err(InsufficientAllocatedCellsError::BuiltinCells(Box::new((
550 self.name(),
551 used_cells,
552 size,
553 )))
554 .into());
555 }
556 Ok((used_cells, size))
557 }
558 }
559 }
560 }
561
562 pub fn get_additional_data(&self) -> BuiltinAdditionalData {
564 match self {
565 BuiltinRunner::Hash(builtin) => builtin.get_additional_data(),
566 BuiltinRunner::Output(builtin) => builtin.get_additional_data(),
567 BuiltinRunner::Signature(builtin) => builtin.get_additional_data(),
568 _ => BuiltinAdditionalData::None,
569 }
570 }
571
572 pub fn extend_additional_data(
575 &mut self,
576 additional_data: &BuiltinAdditionalData,
577 ) -> Result<(), RunnerError> {
578 match self {
579 BuiltinRunner::Hash(builtin) => builtin.extend_additional_data(additional_data),
580 BuiltinRunner::Output(builtin) => builtin.extend_additional_data(additional_data),
581 BuiltinRunner::Signature(builtin) => builtin.extend_additional_data(additional_data),
582 _ => Ok(()),
583 }
584 }
585
586 pub fn air_private_input(&self, segments: &MemorySegmentManager) -> Vec<PrivateInput> {
588 match self {
589 BuiltinRunner::RangeCheck(builtin) => builtin.air_private_input(&segments.memory),
590 BuiltinRunner::RangeCheck96(builtin) => builtin.air_private_input(&segments.memory),
591 BuiltinRunner::Bitwise(builtin) => builtin.air_private_input(&segments.memory),
592 BuiltinRunner::Hash(builtin) => builtin.air_private_input(&segments.memory),
593 BuiltinRunner::EcOp(builtin) => builtin.air_private_input(&segments.memory),
594 BuiltinRunner::Poseidon(builtin) => builtin.air_private_input(&segments.memory),
595 BuiltinRunner::Signature(builtin) => builtin.air_private_input(&segments.memory),
596 BuiltinRunner::Keccak(builtin) => builtin.air_private_input(&segments.memory),
597 BuiltinRunner::Mod(builtin) => builtin.air_private_input(segments),
598 _ => vec![],
599 }
600 }
601
602 pub(crate) fn set_stop_ptr(&mut self, stop_ptr: usize) {
603 match self {
604 BuiltinRunner::Bitwise(ref mut bitwise) => bitwise.stop_ptr = Some(stop_ptr),
605 BuiltinRunner::EcOp(ref mut ec) => ec.stop_ptr = Some(stop_ptr),
606 BuiltinRunner::Hash(ref mut hash) => hash.stop_ptr = Some(stop_ptr),
607 BuiltinRunner::Output(ref mut output) => output.stop_ptr = Some(stop_ptr),
608 BuiltinRunner::RangeCheck(ref mut range_check) => range_check.stop_ptr = Some(stop_ptr),
609 BuiltinRunner::RangeCheck96(ref mut range_check) => {
610 range_check.stop_ptr = Some(stop_ptr)
611 }
612 BuiltinRunner::Keccak(ref mut keccak) => keccak.stop_ptr = Some(stop_ptr),
613 BuiltinRunner::Signature(ref mut signature) => signature.stop_ptr = Some(stop_ptr),
614 BuiltinRunner::Poseidon(ref mut poseidon) => poseidon.stop_ptr = Some(stop_ptr),
615 BuiltinRunner::SegmentArena(ref mut segment_arena) => {
616 segment_arena.stop_ptr = Some(stop_ptr)
617 }
618 BuiltinRunner::Mod(modulo) => modulo.stop_ptr = Some(stop_ptr),
619 }
620 }
621
622 pub(crate) fn stop_ptr(&self) -> Option<usize> {
623 match self {
624 BuiltinRunner::Bitwise(ref bitwise) => bitwise.stop_ptr,
625 BuiltinRunner::EcOp(ref ec) => ec.stop_ptr,
626 BuiltinRunner::Hash(ref hash) => hash.stop_ptr,
627 BuiltinRunner::Output(ref output) => output.stop_ptr,
628 BuiltinRunner::RangeCheck(ref range_check) => range_check.stop_ptr,
629 BuiltinRunner::RangeCheck96(ref range_check) => range_check.stop_ptr,
630 BuiltinRunner::Keccak(ref keccak) => keccak.stop_ptr,
631 BuiltinRunner::Signature(ref signature) => signature.stop_ptr,
632 BuiltinRunner::Poseidon(ref poseidon) => poseidon.stop_ptr,
633 BuiltinRunner::SegmentArena(ref segment_arena) => segment_arena.stop_ptr,
634 BuiltinRunner::Mod(ref modulo) => modulo.stop_ptr,
635 }
636 }
637}
638
639impl From<KeccakBuiltinRunner> for BuiltinRunner {
640 fn from(runner: KeccakBuiltinRunner) -> Self {
641 BuiltinRunner::Keccak(runner)
642 }
643}
644
645impl From<BitwiseBuiltinRunner> for BuiltinRunner {
646 fn from(runner: BitwiseBuiltinRunner) -> Self {
647 BuiltinRunner::Bitwise(runner)
648 }
649}
650
651impl From<EcOpBuiltinRunner> for BuiltinRunner {
652 fn from(runner: EcOpBuiltinRunner) -> Self {
653 BuiltinRunner::EcOp(runner)
654 }
655}
656
657impl From<HashBuiltinRunner> for BuiltinRunner {
658 fn from(runner: HashBuiltinRunner) -> Self {
659 BuiltinRunner::Hash(runner)
660 }
661}
662
663impl From<OutputBuiltinRunner> for BuiltinRunner {
664 fn from(runner: OutputBuiltinRunner) -> Self {
665 BuiltinRunner::Output(runner)
666 }
667}
668
669impl From<RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>> for BuiltinRunner {
670 fn from(runner: RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>) -> Self {
671 BuiltinRunner::RangeCheck(runner)
672 }
673}
674
675impl From<RangeCheckBuiltinRunner<RC_N_PARTS_96>> for BuiltinRunner {
676 fn from(runner: RangeCheckBuiltinRunner<RC_N_PARTS_96>) -> Self {
677 BuiltinRunner::RangeCheck96(runner)
678 }
679}
680
681impl From<SignatureBuiltinRunner> for BuiltinRunner {
682 fn from(runner: SignatureBuiltinRunner) -> Self {
683 BuiltinRunner::Signature(runner)
684 }
685}
686
687impl From<PoseidonBuiltinRunner> for BuiltinRunner {
688 fn from(runner: PoseidonBuiltinRunner) -> Self {
689 BuiltinRunner::Poseidon(runner)
690 }
691}
692
693impl From<SegmentArenaBuiltinRunner> for BuiltinRunner {
694 fn from(runner: SegmentArenaBuiltinRunner) -> Self {
695 BuiltinRunner::SegmentArena(runner)
696 }
697}
698
699impl From<ModBuiltinRunner> for BuiltinRunner {
700 fn from(runner: ModBuiltinRunner) -> Self {
701 BuiltinRunner::Mod(runner)
702 }
703}
704
705#[cfg(test)]
706mod tests {
707 use super::*;
708 use crate::cairo_run::{cairo_run, CairoRunConfig};
709 use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
710 use crate::relocatable;
711 use crate::types::builtin_name::BuiltinName;
712 use crate::types::instance_definitions::mod_instance_def::ModInstanceDef;
713 use crate::types::instance_definitions::LowRatio;
714 use crate::types::layout_name::LayoutName;
715 use crate::types::program::Program;
716 use crate::utils::test_utils::*;
717 use crate::vm::errors::memory_errors::InsufficientAllocatedCellsError;
718 use crate::vm::vm_memory::memory::MemoryCell;
719 use assert_matches::assert_matches;
720
721 #[cfg(target_arch = "wasm32")]
722 use wasm_bindgen_test::*;
723
724 #[test]
725 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
726 fn get_n_input_cells_bitwise() {
727 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
728 let builtin: BuiltinRunner = bitwise.clone().into();
729 assert_eq!(INPUT_CELLS_PER_BITWISE, builtin.n_input_cells())
730 }
731
732 #[test]
733 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
734 fn get_n_input_cells_hash() {
735 let hash = HashBuiltinRunner::new(Some(10), true);
736 let builtin: BuiltinRunner = hash.clone().into();
737 assert_eq!(INPUT_CELLS_PER_HASH, builtin.n_input_cells())
738 }
739
740 #[test]
741 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
742 fn get_n_input_cells_ec_op() {
743 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
744 let builtin: BuiltinRunner = ec_op.clone().into();
745 assert_eq!(INPUT_CELLS_PER_EC_OP, builtin.n_input_cells())
746 }
747
748 #[test]
749 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
750 fn get_n_input_cells_ecdsa() {
751 let signature = SignatureBuiltinRunner::new(Some(10), true);
752 let builtin: BuiltinRunner = signature.clone().into();
753 assert_eq!(CELLS_PER_SIGNATURE, builtin.n_input_cells())
754 }
755
756 #[test]
757 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
758 fn get_n_input_cells_output() {
759 let output = OutputBuiltinRunner::new(true);
760 let builtin: BuiltinRunner = output.into();
761 assert_eq!(0, builtin.n_input_cells())
762 }
763
764 #[test]
765 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
766 fn get_cells_per_instance_bitwise() {
767 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
768 let builtin: BuiltinRunner = bitwise.clone().into();
769 assert_eq!(CELLS_PER_BITWISE, builtin.cells_per_instance())
770 }
771
772 #[test]
773 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
774 fn get_cells_per_instance_hash() {
775 let hash = HashBuiltinRunner::new(Some(10), true);
776 let builtin: BuiltinRunner = hash.clone().into();
777 assert_eq!(CELLS_PER_HASH, builtin.cells_per_instance())
778 }
779
780 #[test]
781 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
782 fn get_cells_per_instance_ec_op() {
783 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
784 let builtin: BuiltinRunner = ec_op.clone().into();
785 assert_eq!(CELLS_PER_EC_OP, builtin.cells_per_instance())
786 }
787
788 #[test]
789 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
790 fn get_cells_per_instance_ecdsa() {
791 let signature = SignatureBuiltinRunner::new(Some(10), true);
792 let builtin: BuiltinRunner = signature.clone().into();
793 assert_eq!(CELLS_PER_SIGNATURE, builtin.cells_per_instance())
794 }
795
796 #[test]
797 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
798 fn get_cells_per_instance_output() {
799 let output = OutputBuiltinRunner::new(true);
800 let builtin: BuiltinRunner = output.into();
801 assert_eq!(0, builtin.cells_per_instance())
802 }
803
804 #[test]
805 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
806 fn get_name_bitwise() {
807 let bitwise = BitwiseBuiltinRunner::new(Some(10), true);
808 let builtin: BuiltinRunner = bitwise.into();
809 assert_eq!(BuiltinName::bitwise, builtin.name())
810 }
811
812 #[test]
813 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
814 fn get_name_hash() {
815 let hash = HashBuiltinRunner::new(Some(10), true);
816 let builtin: BuiltinRunner = hash.into();
817 assert_eq!(BuiltinName::pedersen, builtin.name())
818 }
819
820 #[test]
821 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
822 fn get_name_range_check() {
823 let range_check = RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(10), true);
824 let builtin: BuiltinRunner = range_check.into();
825 assert_eq!(BuiltinName::range_check, builtin.name())
826 }
827
828 #[test]
829 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
830 fn get_name_ec_op() {
831 let ec_op = EcOpBuiltinRunner::new(Some(256), true);
832 let builtin: BuiltinRunner = ec_op.into();
833 assert_eq!(BuiltinName::ec_op, builtin.name())
834 }
835
836 #[test]
837 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
838 fn get_name_ecdsa() {
839 let signature = SignatureBuiltinRunner::new(Some(10), true);
840 let builtin: BuiltinRunner = signature.into();
841 assert_eq!(BuiltinName::ecdsa, builtin.name())
842 }
843
844 #[test]
845 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
846 fn get_name_output() {
847 let output = OutputBuiltinRunner::new(true);
848 let builtin: BuiltinRunner = output.into();
849 assert_eq!(BuiltinName::output, builtin.name())
850 }
851
852 #[test]
853 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
854 fn get_allocated_memory_units_bitwise_with_items() {
855 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(10), true));
856
857 let program = program!(
858 builtins = vec![BuiltinName::bitwise],
859 data = vec_data!(
860 (4612671182993129469_i64),
861 (5189976364521848832_i64),
862 (18446744073709551615_i128),
863 (5199546496550207487_i64),
864 (4612389712311386111_i64),
865 (5198983563776393216_i64),
866 (2),
867 (2345108766317314046_i64),
868 (5191102247248822272_i64),
869 (5189976364521848832_i64),
870 (7),
871 (1226245742482522112_i64),
872 ((
873 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
874 10
875 )),
876 (2345108766317314046_i64)
877 ),
878 main = Some(8),
879 );
880
881 let mut cairo_runner = cairo_runner!(program);
882
883 let mut hint_processor = BuiltinHintProcessor::new_empty();
884
885 let address = cairo_runner.initialize(false).unwrap();
886
887 cairo_runner
888 .run_until_pc(address, &mut hint_processor)
889 .unwrap();
890
891 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(5));
892 }
893
894 #[test]
895 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
896 fn compare_proof_mode_with_and_without_disable_trace_padding() {
897 const PEDERSEN_TEST: &[u8] =
898 include_bytes!("../../../../../cairo_programs/proof_programs/pedersen_test.json");
899 const BIGINT_TEST: &[u8] =
900 include_bytes!("../../../../../cairo_programs/proof_programs/bigint.json");
901 const POSEIDON_HASH_TEST: &[u8] =
902 include_bytes!("../../../../../cairo_programs/proof_programs/poseidon_hash.json");
903
904 let program_files = vec![PEDERSEN_TEST, BIGINT_TEST, POSEIDON_HASH_TEST];
905
906 for program_data in program_files {
907 let config_false = CairoRunConfig {
908 disable_trace_padding: false,
909 proof_mode: true,
910 layout: LayoutName::all_cairo,
911 ..Default::default()
912 };
913 let mut hint_processor_false = BuiltinHintProcessor::new_empty();
914 let runner_false =
915 cairo_run(program_data, &config_false, &mut hint_processor_false).unwrap();
916 let last_step_false = runner_false.vm.current_step;
917
918 assert!(last_step_false.is_power_of_two());
919
920 let config_true = CairoRunConfig {
921 disable_trace_padding: true,
922 proof_mode: true,
923 layout: LayoutName::all_cairo,
924 ..Default::default()
925 };
926 let mut hint_processor_true = BuiltinHintProcessor::new_empty();
927 let runner_true =
928 cairo_run(program_data, &config_true, &mut hint_processor_true).unwrap();
929 let last_step_true = runner_true.vm.current_step;
930
931 assert!(!last_step_true.is_power_of_two());
933
934 assert!(last_step_true < last_step_false);
935
936 let builtin_runners_false = &runner_false.vm.builtin_runners;
937 let builtin_runners_true = &runner_true.vm.builtin_runners;
938 assert_eq!(builtin_runners_false.len(), builtin_runners_true.len());
939 for (builtin_runner_false, builtin_runner_true) in builtin_runners_false
941 .iter()
942 .zip(builtin_runners_true.iter())
943 {
944 assert_eq!(builtin_runner_false.name(), builtin_runner_true.name());
945 match builtin_runner_false {
946 BuiltinRunner::Output(_) | BuiltinRunner::SegmentArena(_) => {
947 continue;
948 }
949 _ => {}
950 }
951 let (_, allocated_size_false) = builtin_runner_false
952 .get_used_cells_and_allocated_size(&runner_false.vm)
953 .unwrap();
954 let (used_cells_true, allocated_size_true) = builtin_runner_true
955 .get_used_cells_and_allocated_size(&runner_true.vm)
956 .unwrap();
957 let n_allocated_instances_false = safe_div_usize(
958 allocated_size_false,
959 builtin_runner_false.cells_per_instance() as usize,
960 )
961 .unwrap();
962 let n_allocated_instances_true = safe_div_usize(
963 allocated_size_true,
964 builtin_runner_true.cells_per_instance() as usize,
965 )
966 .unwrap();
967 assert!(
968 n_allocated_instances_false.is_power_of_two()
969 || n_allocated_instances_false == 0
970 );
971 assert!(
972 n_allocated_instances_true.is_power_of_two() || n_allocated_instances_true == 0
973 );
974 assert!(
978 n_allocated_instances_true == 0
979 || n_allocated_instances_true != n_allocated_instances_false
980 );
981
982 let n_output_cells = builtin_runner_true.cells_per_instance() as usize
987 - builtin_runner_true.n_input_cells() as usize;
988 assert!(
989 used_cells_true + n_output_cells
990 >= (builtin_runner_true.cells_per_instance() as usize)
991 * builtin_runner_true
992 .get_used_instances(&runner_true.vm.segments)
993 .unwrap()
994 );
995 }
996 }
997 }
998
999 #[test]
1000 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1001 fn get_allocated_memory_units_ec_op_with_items() {
1002 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(10), true));
1003
1004 let program = program!(
1005 builtins = vec![BuiltinName::ec_op],
1006 data = vec_data!(
1007 (4612671182993129469_i64),
1008 (5189976364521848832_i64),
1009 (18446744073709551615_i128),
1010 (5199546496550207487_i64),
1011 (4612389712311386111_i64),
1012 (5198983563776393216_i64),
1013 (2),
1014 (2345108766317314046_i64),
1015 (5191102247248822272_i64),
1016 (5189976364521848832_i64),
1017 (7),
1018 (1226245742482522112_i64),
1019 ((
1020 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1021 10
1022 )),
1023 (2345108766317314046_i64)
1024 ),
1025 main = Some(8),
1026 );
1027
1028 let mut cairo_runner = cairo_runner!(program);
1029
1030 let mut hint_processor = BuiltinHintProcessor::new_empty();
1031
1032 let address = cairo_runner.initialize(false).unwrap();
1033
1034 cairo_runner
1035 .run_until_pc(address, &mut hint_processor)
1036 .unwrap();
1037
1038 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(7));
1039 }
1040
1041 #[test]
1042 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1043 fn get_allocated_memory_units_hash_with_items() {
1044 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(10), true));
1045
1046 let program = program!(
1047 builtins = vec![BuiltinName::pedersen],
1048 data = vec_data!(
1049 (4612671182993129469_i64),
1050 (5189976364521848832_i64),
1051 (18446744073709551615_i128),
1052 (5199546496550207487_i64),
1053 (4612389712311386111_i64),
1054 (5198983563776393216_i64),
1055 (2),
1056 (2345108766317314046_i64),
1057 (5191102247248822272_i64),
1058 (5189976364521848832_i64),
1059 (7),
1060 (1226245742482522112_i64),
1061 ((
1062 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1063 10
1064 )),
1065 (2345108766317314046_i64)
1066 ),
1067 main = Some(8),
1068 );
1069
1070 let mut cairo_runner = cairo_runner!(program);
1071
1072 let mut hint_processor = BuiltinHintProcessor::new_empty();
1073
1074 let address = cairo_runner.initialize(false).unwrap();
1075
1076 cairo_runner
1077 .run_until_pc(address, &mut hint_processor)
1078 .unwrap();
1079
1080 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(3));
1081 }
1082
1083 #[test]
1084 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1085 fn get_allocated_memory_units_range_check_with_items() {
1086 let builtin = BuiltinRunner::RangeCheck(
1087 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(10), true),
1088 );
1089
1090 let program = program!(
1091 builtins = vec![BuiltinName::range_check],
1092 data = vec_data!(
1093 (4612671182993129469_i64),
1094 (5189976364521848832_i64),
1095 (18446744073709551615_i128),
1096 (5199546496550207487_i64),
1097 (4612389712311386111_i64),
1098 (5198983563776393216_i64),
1099 (2),
1100 (2345108766317314046_i64),
1101 (5191102247248822272_i64),
1102 (5189976364521848832_i64),
1103 (7),
1104 (1226245742482522112_i64),
1105 ((
1106 "3618502788666131213697322783095070105623107215331596699973092056135872020470",
1107 10
1108 )),
1109 (2345108766317314046_i64)
1110 ),
1111 main = Some(8),
1112 );
1113
1114 let mut cairo_runner = cairo_runner!(program);
1115
1116 let mut hint_processor = BuiltinHintProcessor::new_empty();
1117
1118 let address = cairo_runner.initialize(false).unwrap();
1119
1120 cairo_runner
1121 .run_until_pc(address, &mut hint_processor)
1122 .unwrap();
1123
1124 assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(1));
1125 }
1126
1127 #[test]
1128 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1129 fn get_allocated_memory_units_keccak_with_items() {
1130 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(10), true));
1131
1132 let mut vm = vm!();
1133 vm.current_step = 160;
1134 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256));
1135 }
1136
1137 #[test]
1138 fn get_allocated_memory_units_keccak_min_steps_not_reached() {
1139 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(10), true));
1140
1141 let mut vm = vm!();
1142 vm.current_step = 10;
1143 assert_eq!(
1144 builtin.get_allocated_memory_units(&vm),
1145 Err(MemoryError::InsufficientAllocatedCells(
1146 InsufficientAllocatedCellsError::MinStepNotReached(Box::new((
1147 160,
1148 BuiltinName::keccak
1149 )))
1150 ))
1151 );
1152 }
1153
1154 #[test]
1155 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1156 fn get_allocated_memory_units_output() {
1157 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1158 let vm = vm!();
1159
1160 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1162 }
1163
1164 #[test]
1165 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1166 fn get_allocated_memory_units_range_check() {
1167 let builtin = BuiltinRunner::RangeCheck(
1168 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1169 );
1170 let mut vm = vm!();
1171 vm.current_step = 8;
1172 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(1));
1173 }
1174
1175 #[test]
1176 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1177 fn get_allocated_memory_units_hash() {
1178 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true));
1179 let mut vm = vm!();
1180 vm.current_step = 1;
1181 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(3));
1182 }
1183
1184 #[test]
1185 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1186 fn get_allocated_memory_units_bitwise() {
1187 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1188 let mut vm = vm!();
1189 vm.current_step = 256;
1190 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(5));
1191 }
1192
1193 #[test]
1194 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1195 fn get_allocated_memory_units_ec_op() {
1196 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), true));
1197 let mut vm = vm!();
1198 vm.current_step = 256;
1199 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(7));
1200 }
1201
1202 #[test]
1203 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1204 fn get_allocated_memory_units_keccak() {
1205 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1206 let mut vm = vm!();
1207 vm.current_step = 32768;
1208 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(256));
1209 }
1210
1211 #[test]
1212 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1213 fn get_allocated_memory_units_zero_ratio() {
1214 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(0), true));
1215 let vm = vm!();
1216 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1217 }
1218
1219 #[test]
1220 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1221 fn get_allocated_memory_units_none_ratio() {
1222 let mut builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(None, true));
1223 let mut vm = vm!();
1224
1225 builtin.initialize_segments(&mut vm.segments);
1226 vm.compute_segments_effective_sizes();
1227
1228 assert_eq!(builtin.get_allocated_memory_units(&vm), Ok(0));
1229 }
1230
1231 #[test]
1232 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1233 fn get_range_check_usage_range_check() {
1234 let builtin = BuiltinRunner::RangeCheck(
1235 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1236 );
1237 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1238 assert_eq!(builtin.get_range_check_usage(&memory), Some((0, 4)));
1239 }
1240
1241 #[test]
1242 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1243 fn get_range_check_usage_output() {
1244 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1245 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1246 assert_eq!(builtin.get_range_check_usage(&memory), None);
1247 }
1248
1249 #[test]
1250 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1251 fn get_range_check_usage_hash() {
1252 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true));
1253 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1254 assert_eq!(builtin.get_range_check_usage(&memory), None);
1255 }
1256
1257 #[test]
1258 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1259 fn get_range_check_usage_ec_op() {
1260 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), true));
1261 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1262 assert_eq!(builtin.get_range_check_usage(&memory), None);
1263 }
1264
1265 #[test]
1266 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1267 fn get_range_check_usage_bitwise() {
1268 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1269 let memory = memory![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4)];
1270 assert_eq!(builtin.get_range_check_usage(&memory), None);
1271 }
1272
1273 #[test]
1274 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1275 fn get_used_diluted_check_units_bitwise() {
1276 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1277 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 1255);
1278 }
1279
1280 #[test]
1281 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1282 fn get_used_diluted_check_units_keccak_zero_case() {
1283 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1284 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1285 }
1286
1287 #[test]
1288 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1289 fn get_used_diluted_check_units_keccak_non_zero_case() {
1290 let builtin = BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), true));
1291 assert_eq!(builtin.get_used_diluted_check_units(0, 8), 32768);
1292 }
1293
1294 #[test]
1295 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1296 fn get_used_diluted_check_units_ec_op() {
1297 let builtin = BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(10), true));
1298 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1299 }
1300
1301 #[test]
1302 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1303 fn get_used_diluted_check_units_hash() {
1304 let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), true));
1305 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1306 }
1307
1308 #[test]
1309 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1310 fn get_used_diluted_check_units_range_check() {
1311 let builtin = BuiltinRunner::RangeCheck(
1312 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1313 );
1314 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1315 }
1316
1317 #[test]
1318 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1319 fn get_used_diluted_check_units_output() {
1320 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1321 assert_eq!(builtin.get_used_diluted_check_units(270, 7), 0);
1322 }
1323
1324 #[test]
1325 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1326 fn get_memory_segment_addresses_test() {
1327 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1328 assert_eq!(bitwise_builtin.get_memory_segment_addresses(), (0, None),);
1329 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1330 assert_eq!(ec_op_builtin.get_memory_segment_addresses(), (0, None),);
1331 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1332 assert_eq!(hash_builtin.get_memory_segment_addresses(), (0, None),);
1333 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1334 assert_eq!(output_builtin.get_memory_segment_addresses(), (0, None),);
1335 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1336 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1337 );
1338 assert_eq!(
1339 range_check_builtin.get_memory_segment_addresses(),
1340 (0, None),
1341 );
1342 }
1343
1344 #[test]
1345 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1346 fn run_security_checks_for_output() {
1347 let builtin = BuiltinRunner::Output(OutputBuiltinRunner::new(true));
1348 let vm = vm!();
1349
1350 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1351 }
1352
1353 #[test]
1354 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1355 fn run_security_checks_empty_memory() {
1356 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1357 let vm = vm!();
1358 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1360 }
1361
1362 #[test]
1363 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1364 fn run_security_checks_empty_offsets() {
1365 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1366 let mut vm = vm!();
1367
1368 vm.segments.memory.data = vec![vec![]];
1369
1370 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1371 }
1372
1373 #[test]
1374 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1375 fn run_security_checks_bitwise_missing_memory_cells_with_offsets() {
1376 let builtin = BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), true));
1377 let mut vm = vm!();
1378 vm.segments.memory = memory![
1379 ((0, 1), (0, 1)),
1380 ((0, 2), (0, 2)),
1381 ((0, 3), (0, 3)),
1382 ((0, 4), (0, 4))
1383 ];
1384
1385 assert_matches!(
1386 builtin.run_security_checks(&vm),
1387 Err(VirtualMachineError::Memory(
1388 MemoryError::MissingMemoryCellsWithOffsets(bx)
1389 )) if *bx == (BuiltinName::bitwise, vec![0])
1390 );
1391 }
1392
1393 #[test]
1394 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1395 fn run_security_checks_bitwise_missing_memory_cells() {
1396 let bitwise_builtin = BitwiseBuiltinRunner::new(Some(256), true);
1397
1398 let builtin: BuiltinRunner = bitwise_builtin.into();
1399
1400 let mut vm = vm!();
1401
1402 vm.segments.memory = memory![((0, 4), (0, 5))];
1403
1404 assert_matches!(
1405 builtin.run_security_checks(&vm),
1406 Err(VirtualMachineError::Memory(
1407 MemoryError::MissingMemoryCells(bx)
1408 )) if *bx == BuiltinName::bitwise
1409 );
1410 }
1411
1412 #[test]
1413 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1414 fn run_security_checks_hash_missing_memory_cells_with_offsets() {
1415 let builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1416 let mut vm = vm!();
1417
1418 vm.segments.memory = memory![
1419 ((0, 1), (0, 1)),
1420 ((0, 2), (0, 2)),
1421 ((0, 3), (0, 3)),
1422 ((0, 4), (0, 4)),
1423 ((0, 5), (0, 5))
1424 ];
1425 assert_matches!(
1426 builtin.run_security_checks(&vm),
1427 Err(VirtualMachineError::Memory(
1428 MemoryError::MissingMemoryCellsWithOffsets(bx)
1429 )) if *bx == (BuiltinName::pedersen, vec![0])
1430 );
1431 }
1432
1433 #[test]
1434 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1435 fn run_security_checks_hash_missing_memory_cells() {
1436 let hash_builtin = HashBuiltinRunner::new(Some(8), true);
1437
1438 let builtin: BuiltinRunner = hash_builtin.into();
1439
1440 let mut vm = vm!();
1441
1442 vm.segments.memory = memory![((0, 0), (0, 0))];
1443
1444 assert_matches!(
1445 builtin.run_security_checks(&vm),
1446 Err(VirtualMachineError::Memory(
1447 MemoryError::MissingMemoryCells(bx)
1448 )) if *bx == BuiltinName::pedersen
1449 );
1450 }
1451
1452 #[test]
1453 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1454 fn run_security_checks_range_check_missing_memory_cells_with_offsets() {
1455 let range_check_builtin =
1456 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true);
1457 let builtin: BuiltinRunner = range_check_builtin.into();
1458 let mut vm = vm!();
1459
1460 vm.segments.memory = memory![
1461 ((0, 1), 100),
1462 ((0, 2), 2),
1463 ((0, 3), 3),
1464 ((0, 5), 5),
1465 ((0, 6), 17),
1466 ((0, 7), 22)
1467 ];
1468
1469 assert_matches!(
1470 builtin.run_security_checks(&vm),
1471 Err(VirtualMachineError::Memory(
1472 MemoryError::MissingMemoryCells(bx)
1473 )) if *bx == BuiltinName::range_check
1474 );
1475 }
1476
1477 #[test]
1478 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1479 fn run_security_checks_range_check_missing_memory_cells() {
1480 let builtin: BuiltinRunner = BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<
1481 RC_N_PARTS_STANDARD,
1482 >::new(Some(8), true));
1483 let mut vm = vm!();
1484
1485 vm.segments.memory = memory![((0, 1), 1)];
1486
1487 assert_matches!(
1488 builtin.run_security_checks(&vm),
1489 Err(VirtualMachineError::Memory(
1490 MemoryError::MissingMemoryCells(bx)
1491 )) if *bx == BuiltinName::range_check
1492 );
1493 }
1494
1495 #[test]
1496 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1497 fn run_security_checks_range_check_empty() {
1498 let range_check_builtin =
1499 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true);
1500
1501 let builtin: BuiltinRunner = range_check_builtin.into();
1502
1503 let mut vm = vm!();
1504
1505 vm.segments.memory.data = vec![vec![MemoryCell::NONE, MemoryCell::NONE, MemoryCell::NONE]];
1506
1507 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1508 }
1509
1510 #[test]
1511 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1512 fn run_security_checks_validate_auto_deductions() {
1513 let builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1514
1515 let mut vm = vm!();
1516 vm.segments
1517 .memory
1518 .validated_addresses
1519 .extend(&[relocatable!(0, 2)]);
1520
1521 vm.segments.memory = memory![
1522 ((0, 0), (0, 0)),
1523 ((0, 1), (0, 1)),
1524 ((0, 2), (0, 2)),
1525 ((0, 3), (0, 3)),
1526 ((0, 4), (0, 4))
1527 ];
1528
1529 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1530 }
1531
1532 #[test]
1533 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1534 fn run_security_ec_op_check_memory_empty() {
1535 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1536
1537 let builtin: BuiltinRunner = ec_op_builtin.into();
1538
1539 let mut vm = vm!();
1540 vm.segments.memory.data = vec![vec![]];
1542
1543 assert_matches!(builtin.run_security_checks(&vm), Ok(()));
1544 }
1545
1546 #[test]
1547 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1548 fn run_security_ec_op_check_memory_1_element() {
1549 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1550
1551 let builtin: BuiltinRunner = ec_op_builtin.into();
1552
1553 let mut vm = vm!();
1554 vm.segments.memory = memory![((0, 0), 0)];
1556 assert_matches!(
1557 builtin.run_security_checks(&vm),
1558 Err(VirtualMachineError::Memory(
1559 MemoryError::MissingMemoryCells(bx)
1560 )) if *bx == BuiltinName::ec_op
1561 );
1562 }
1563
1564 #[test]
1565 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1566 fn run_security_ec_op_check_memory_3_elements() {
1567 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1568
1569 let builtin: BuiltinRunner = ec_op_builtin.into();
1570
1571 let mut vm = vm!();
1572 vm.segments.memory = memory![((0, 0), 0), ((0, 1), 0), ((0, 2), 0)];
1574
1575 assert_matches!(
1576 builtin.run_security_checks(&vm),
1577 Err(VirtualMachineError::Memory(
1578 MemoryError::MissingMemoryCells(bx)
1579 )) if *bx == BuiltinName::ec_op
1580 );
1581 }
1582
1583 #[test]
1584 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1585 fn run_security_ec_op_missing_memory_cells_with_offsets() {
1586 let builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1587 let mut vm = vm!();
1588 vm.segments.memory = memory![
1589 ((0, 1), (0, 1)),
1590 ((0, 2), (0, 2)),
1591 ((0, 3), (0, 3)),
1592 ((0, 4), (0, 4)),
1593 ((0, 5), (0, 5)),
1594 ((0, 6), (0, 6))
1595 ];
1596
1597 assert_matches!(
1598 builtin.run_security_checks(&vm),
1599 Err(VirtualMachineError::Memory(
1600 MemoryError::MissingMemoryCellsWithOffsets(bx)
1601 )) if *bx == (BuiltinName::ec_op, vec![0])
1602 );
1603 }
1604
1605 #[test]
1606 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1607 fn run_security_ec_op_check_memory_gap() {
1608 let ec_op_builtin = EcOpBuiltinRunner::new(Some(256), true);
1609
1610 let builtin: BuiltinRunner = ec_op_builtin.into();
1611
1612 let mut vm = vm!();
1613 vm.segments.memory = memory![
1615 ((0, 0), 0),
1616 ((0, 1), 1),
1617 ((0, 2), 2),
1618 ((0, 3), 3),
1619 ((0, 4), 4),
1620 ((0, 5), 5),
1621 ((0, 6), 6),
1622 ((0, 8), 8),
1623 ((0, 9), 9),
1624 ((0, 10), 10),
1625 ((0, 11), 11)
1626 ];
1627
1628 assert_matches!(
1629 builtin.run_security_checks(&vm),
1630 Err(VirtualMachineError::Memory(
1631 MemoryError::MissingMemoryCellsWithOffsets(bx)
1632 )) if *bx == (BuiltinName::ec_op, vec![7])
1633 );
1634 }
1635
1636 #[test]
1639 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1640 fn get_used_perm_range_check_units_bitwise() {
1641 let builtin_runner: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1642 let mut vm = vm!();
1643
1644 vm.current_step = 8;
1645 vm.segments.segment_used_sizes = Some(vec![5]);
1646 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1647 }
1648
1649 #[test]
1652 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1653 fn get_used_perm_range_check_units_ec_op() {
1654 let builtin_runner: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1655 let mut vm = vm!();
1656
1657 vm.current_step = 8;
1658 vm.segments.segment_used_sizes = Some(vec![5]);
1659 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1660 }
1661
1662 #[test]
1665 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1666 fn get_used_perm_range_check_units_hash() {
1667 let builtin_runner: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1668 let mut vm = vm!();
1669
1670 vm.current_step = 8;
1671 vm.segments.segment_used_sizes = Some(vec![5]);
1672 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1673 }
1674
1675 #[test]
1678 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1679 fn get_used_perm_range_check_units_output() {
1680 let builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1681 let mut vm = vm!();
1682
1683 vm.current_step = 8;
1684 vm.segments.segment_used_sizes = Some(vec![5]);
1685 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(0));
1686 }
1687
1688 #[test]
1691 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1692 fn get_used_perm_range_check_units_range_check() {
1693 let builtin_runner: BuiltinRunner =
1694 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true).into();
1695 let mut vm = vm!();
1696
1697 vm.current_step = 8;
1698 vm.segments.segment_used_sizes = Some(vec![1]);
1699 assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(8));
1700 }
1701
1702 #[test]
1703 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1704 fn get_ratio_tests() {
1705 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1706 assert_eq!(bitwise_builtin.ratio(), (Some(256)),);
1707 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1708 assert_eq!(ec_op_builtin.ratio(), (Some(256)),);
1709 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1710 assert_eq!(hash_builtin.ratio(), (Some(8)),);
1711 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1712 assert_eq!(output_builtin.ratio(), None,);
1713 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1714 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1715 );
1716 assert_eq!(range_check_builtin.ratio(), (Some(8)),);
1717 let keccak_builtin: BuiltinRunner = KeccakBuiltinRunner::new(Some(2048), true).into();
1718 assert_eq!(keccak_builtin.ratio(), (Some(2048)),);
1719 }
1720
1721 #[test]
1722 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1723 fn get_ratio_den_tests() {
1724 let rangecheck_builtin: BuiltinRunner =
1725 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new_with_low_ratio(
1726 Some(LowRatio::new(1, 2)),
1727 true,
1728 )
1729 .into();
1730 assert_eq!(rangecheck_builtin.ratio_den(), (Some(2)),);
1731
1732 let rangecheck96_builtin: BuiltinRunner =
1733 RangeCheckBuiltinRunner::<RC_N_PARTS_96>::new_with_low_ratio(
1734 Some(LowRatio::new(1, 4)),
1735 true,
1736 )
1737 .into();
1738 assert_eq!(rangecheck96_builtin.ratio_den(), (Some(4)),);
1739
1740 let mod_builtin: BuiltinRunner =
1741 ModBuiltinRunner::new_add_mod(&ModInstanceDef::new(Some(5), 3, 3), true).into();
1742 assert_eq!(mod_builtin.ratio_den(), (Some(1)),);
1743 }
1744
1745 #[test]
1746 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1747 fn bitwise_get_used_instances_test() {
1748 let mut vm = vm!();
1749 vm.segments.segment_used_sizes = Some(vec![4]);
1750
1751 let bitwise_builtin: BuiltinRunner = BitwiseBuiltinRunner::new(Some(256), true).into();
1752 assert_eq!(bitwise_builtin.get_used_instances(&vm.segments), Ok(1));
1753 }
1754
1755 #[test]
1756 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1757 fn ec_op_get_used_instances_test() {
1758 let mut vm = vm!();
1759 vm.segments.segment_used_sizes = Some(vec![4]);
1760
1761 let ec_op_builtin: BuiltinRunner = EcOpBuiltinRunner::new(Some(256), true).into();
1762 assert_eq!(ec_op_builtin.get_used_instances(&vm.segments), Ok(1));
1763 }
1764
1765 #[test]
1766 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1767 fn hash_get_used_instances_test() {
1768 let mut vm = vm!();
1769 vm.segments.segment_used_sizes = Some(vec![4]);
1770
1771 let hash_builtin: BuiltinRunner = HashBuiltinRunner::new(Some(8), true).into();
1772 assert_eq!(hash_builtin.get_used_instances(&vm.segments), Ok(2));
1773 }
1774
1775 #[test]
1776 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1777 fn output_get_used_instances_test() {
1778 let mut vm = vm!();
1779 vm.segments.segment_used_sizes = Some(vec![4]);
1780
1781 let output_builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into();
1782 assert_eq!(output_builtin.get_used_instances(&vm.segments), Ok(4));
1783 }
1784 #[test]
1785 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1786 fn range_check_get_used_instances_test() {
1787 let mut vm = vm!();
1788 vm.segments.segment_used_sizes = Some(vec![4]);
1789
1790 let range_check_builtin: BuiltinRunner = BuiltinRunner::RangeCheck(
1791 RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(Some(8), true),
1792 );
1793 assert_eq!(range_check_builtin.get_used_instances(&vm.segments), Ok(4));
1794 }
1795
1796 #[test]
1797 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1798 fn runners_final_stack() {
1799 let mut builtins = vec![
1800 BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), false)),
1801 BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), false)),
1802 BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)),
1803 BuiltinRunner::Output(OutputBuiltinRunner::new(false)),
1804 BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(
1805 Some(8),
1806 false,
1807 )),
1808 BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), false)),
1809 BuiltinRunner::Signature(SignatureBuiltinRunner::new(Some(512), false)),
1810 ];
1811 let vm = vm!();
1812
1813 for br in builtins.iter_mut() {
1814 assert_eq!(br.final_stack(&vm.segments, vm.get_ap()), Ok(vm.get_ap()));
1815 }
1816 }
1817
1818 #[test]
1819 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1820 fn runners_set_stop_ptr() {
1821 let builtins = vec![
1822 BuiltinRunner::Bitwise(BitwiseBuiltinRunner::new(Some(256), false)),
1823 BuiltinRunner::EcOp(EcOpBuiltinRunner::new(Some(256), false)),
1824 BuiltinRunner::Hash(HashBuiltinRunner::new(Some(1), false)),
1825 BuiltinRunner::Output(OutputBuiltinRunner::new(false)),
1826 BuiltinRunner::RangeCheck(RangeCheckBuiltinRunner::<RC_N_PARTS_STANDARD>::new(
1827 Some(8),
1828 false,
1829 )),
1830 BuiltinRunner::Keccak(KeccakBuiltinRunner::new(Some(2048), false)),
1831 BuiltinRunner::Signature(SignatureBuiltinRunner::new(Some(512), false)),
1832 BuiltinRunner::Poseidon(PoseidonBuiltinRunner::new(Some(32), false)),
1833 BuiltinRunner::SegmentArena(SegmentArenaBuiltinRunner::new(false)),
1834 ];
1835
1836 let ptr = 3;
1837
1838 for mut br in builtins {
1839 br.set_stop_ptr(ptr);
1840 let (_, stop_ptr) = br.get_memory_segment_addresses();
1841 assert_eq!(stop_ptr, Some(ptr));
1842 }
1843 }
1844
1845 #[test]
1846 fn get_additonal_data_none() {
1847 let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(None, true).into();
1848 assert_eq!(builtin.get_additional_data(), BuiltinAdditionalData::None)
1849 }
1850}