cairo_vm/hint_processor/builtin_hint_processor/
math_utils.rs

1use crate::{
2    hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name,
3    math_utils::signed_felt,
4    stdlib::{boxed::Box, collections::HashMap, prelude::*},
5    types::errors::math_errors::MathError,
6};
7use lazy_static::lazy_static;
8use num_traits::{Signed, Zero};
9
10use crate::utils::CAIRO_PRIME;
11
12use crate::Felt252;
13use crate::{
14    any_box,
15    hint_processor::{
16        builtin_hint_processor::hint_utils::{
17            get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name,
18            insert_value_into_ap,
19        },
20        hint_processor_definition::HintReference,
21    },
22    math_utils::{isqrt, pow2_const},
23    serde::deserialize_program::ApTracking,
24    types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable},
25    vm::{
26        errors::{hint_errors::HintError, vm_errors::VirtualMachineError},
27        vm_core::VirtualMachine,
28    },
29};
30use num_bigint::{BigUint, Sign};
31use num_integer::Integer;
32use num_traits::One;
33
34use super::{
35    hint_utils::{get_maybe_relocatable_from_var_name, get_relocatable_from_var_name},
36    uint256_utils::Uint256,
37};
38
39const ADDR_BOUND: &str = "starkware.starknet.common.storage.ADDR_BOUND";
40
41//Implements hint: memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1
42pub fn is_nn(
43    vm: &mut VirtualMachine,
44    ids_data: &HashMap<String, HintReference>,
45    ap_tracking: &ApTracking,
46) -> Result<(), HintError> {
47    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
48    let range_check_bound = vm.get_range_check_builtin()?.bound();
49    //Main logic (assert a is not negative and within the expected range)
50    insert_value_into_ap(vm, Felt252::from(a.as_ref() >= range_check_bound))
51}
52
53//Implements hint: memory[ap] = 0 if 0 <= ((-ids.a - 1) % PRIME) < range_check_builtin.bound else 1
54pub fn is_nn_out_of_range(
55    vm: &mut VirtualMachine,
56    ids_data: &HashMap<String, HintReference>,
57    ap_tracking: &ApTracking,
58) -> Result<(), HintError> {
59    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
60    let a = a.as_ref();
61    let range_check_bound = vm.get_range_check_builtin()?.bound();
62    //Main logic (assert a is not negative and within the expected range)
63    insert_value_into_ap(vm, Felt252::from(-(a + 1) >= *range_check_bound))
64}
65/* Implements hint:from starkware.cairo.common.math_utils import assert_integer
66%{
67    import itertools
68
69    from starkware.cairo.common.math_utils import assert_integer
70    assert_integer(ids.a)
71    assert_integer(ids.b)
72    a = ids.a % PRIME
73    b = ids.b % PRIME
74    assert a <= b, f'a = {a} is not less than or equal to b = {b}.'
75
76    # Find an arc less than PRIME / 3, and another less than PRIME / 2.
77    lengths_and_indices = [(a, 0), (b - a, 1), (PRIME - 1 - b, 2)]
78    lengths_and_indices.sort()
79    assert lengths_and_indices[0][0] <= PRIME // 3 and lengths_and_indices[1][0] <= PRIME // 2
80    excluded = lengths_and_indices[2][1]
81
82    memory[ids.range_check_ptr + 1], memory[ids.range_check_ptr + 0] = (
83        divmod(lengths_and_indices[0][0], ids.PRIME_OVER_3_HIGH))
84    memory[ids.range_check_ptr + 3], memory[ids.range_check_ptr + 2] = (
85        divmod(lengths_and_indices[1][0], ids.PRIME_OVER_2_HIGH))
86%}
87*/
88pub fn assert_le_felt(
89    vm: &mut VirtualMachine,
90    exec_scopes: &mut ExecutionScopes,
91    ids_data: &HashMap<String, HintReference>,
92    ap_tracking: &ApTracking,
93    constants: &HashMap<String, Felt252>,
94) -> Result<(), HintError> {
95    const PRIME_OVER_3_HIGH: &str = "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH";
96    const PRIME_OVER_2_HIGH: &str = "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH";
97
98    let prime_over_3_high = constants
99        .get(PRIME_OVER_3_HIGH)
100        .ok_or_else(|| HintError::MissingConstant(Box::new(PRIME_OVER_3_HIGH)))?;
101    let prime_over_2_high = constants
102        .get(PRIME_OVER_2_HIGH)
103        .ok_or_else(|| HintError::MissingConstant(Box::new(PRIME_OVER_2_HIGH)))?;
104    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.to_biguint();
105    let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?.to_biguint();
106    let range_check_ptr = get_ptr_from_var_name("range_check_ptr", vm, ids_data, ap_tracking)?;
107
108    // TODO: use UnsignedInteger for this
109    let prime_div2 = prime_div_constant(2)?;
110    let prime_div3 = prime_div_constant(3)?;
111
112    if a > b {
113        return Err(HintError::NonLeFelt252(Box::new((
114            Felt252::from(&a),
115            Felt252::from(&b),
116        ))));
117    }
118
119    let arc1 = &b - &a;
120    let arc2 = &*CAIRO_PRIME - 1_u32 - &b;
121    let mut lengths_and_indices = [(&a, 0_i32), (&arc1, 1_i32), (&arc2, 2_i32)];
122    lengths_and_indices.sort();
123    // TODO: I believe this check can be removed
124    if lengths_and_indices[0].0 > &prime_div3 || lengths_and_indices[1].0 > &prime_div2 {
125        return Err(HintError::ArcTooBig(Box::new((
126            Felt252::from(&lengths_and_indices[0].0.clone()),
127            Felt252::from(&prime_div2),
128            Felt252::from(&lengths_and_indices[1].0.clone()),
129            Felt252::from(&prime_div3),
130        ))));
131    }
132
133    let excluded = lengths_and_indices[2].1;
134    exec_scopes.assign_or_update_variable("excluded", any_box!(Felt252::from(excluded)));
135
136    let (q_0, r_0) = (lengths_and_indices[0].0).div_mod_floor(&prime_over_3_high.to_biguint());
137    let (q_1, r_1) = (lengths_and_indices[1].0).div_mod_floor(&prime_over_2_high.to_biguint());
138
139    vm.insert_value(range_check_ptr, Felt252::from(&r_0))?;
140    vm.insert_value((range_check_ptr + 1_i32)?, Felt252::from(&q_0))?;
141    vm.insert_value((range_check_ptr + 2_i32)?, Felt252::from(&r_1))?;
142    vm.insert_value((range_check_ptr + 3_i32)?, Felt252::from(&q_1))?;
143    Ok(())
144}
145
146pub fn assert_le_felt_v_0_6(
147    vm: &mut VirtualMachine,
148    ids_data: &HashMap<String, HintReference>,
149    ap_tracking: &ApTracking,
150) -> Result<(), HintError> {
151    let a = &get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
152    let b = &get_integer_from_var_name("b", vm, ids_data, ap_tracking)?;
153
154    if a > b {
155        return Err(HintError::NonLeFelt252(Box::new((*a, *b))));
156    }
157    Ok(())
158}
159
160pub fn assert_le_felt_v_0_8(
161    vm: &mut VirtualMachine,
162    ids_data: &HashMap<String, HintReference>,
163    ap_tracking: &ApTracking,
164) -> Result<(), HintError> {
165    let a = &get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
166    let b = &get_integer_from_var_name("b", vm, ids_data, ap_tracking)?;
167
168    if a > b {
169        return Err(HintError::NonLeFelt252(Box::new((*a, *b))));
170    }
171    let bound = vm.get_range_check_builtin()?.bound();
172    let small_inputs = Felt252::from((a < bound && b - a < *bound) as u8);
173    insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking)
174}
175
176pub fn assert_le_felt_excluded_2(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> {
177    let excluded: Felt252 = exec_scopes.get("excluded")?;
178
179    if excluded != Felt252::from(2_i32) {
180        Err(HintError::ExcludedNot2(Box::new(excluded)))
181    } else {
182        Ok(())
183    }
184}
185
186pub fn assert_le_felt_excluded_1(
187    vm: &mut VirtualMachine,
188    exec_scopes: &mut ExecutionScopes,
189) -> Result<(), HintError> {
190    let excluded: Felt252 = exec_scopes.get("excluded")?;
191
192    if excluded != Felt252::ONE {
193        insert_value_into_ap(vm, Felt252::ONE)
194    } else {
195        insert_value_into_ap(vm, Felt252::ZERO)
196    }
197}
198
199pub fn assert_le_felt_excluded_0(
200    vm: &mut VirtualMachine,
201    exec_scopes: &mut ExecutionScopes,
202) -> Result<(), HintError> {
203    let excluded: Felt252 = exec_scopes.get("excluded")?;
204
205    if !excluded.is_zero() {
206        insert_value_into_ap(vm, Felt252::ONE)
207    } else {
208        insert_value_into_ap(vm, Felt252::ZERO)
209    }
210}
211
212//Implements hint:from starkware.cairo.common.math_cmp import is_le_felt
213//    memory[ap] = 0 if (ids.a % PRIME) <= (ids.b % PRIME) else 1
214pub fn is_le_felt(
215    vm: &mut VirtualMachine,
216    ids_data: &HashMap<String, HintReference>,
217    ap_tracking: &ApTracking,
218) -> Result<(), HintError> {
219    let a_mod = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
220    let b_mod = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?;
221    let value = if a_mod > b_mod {
222        Felt252::ONE
223    } else {
224        Felt252::ZERO
225    };
226    insert_value_into_ap(vm, value)
227}
228
229//Implements hint: from starkware.cairo.lang.vm.relocatable import RelocatableValue
230//        both_ints = isinstance(ids.a, int) and isinstance(ids.b, int)
231//        both_relocatable = (
232//            isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and
233//            ids.a.segment_index == ids.b.segment_index)
234//        assert both_ints or both_relocatable, \
235//            f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'
236//        assert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'
237pub fn assert_not_equal(
238    vm: &mut VirtualMachine,
239    ids_data: &HashMap<String, HintReference>,
240    ap_tracking: &ApTracking,
241) -> Result<(), HintError> {
242    let maybe_rel_a = get_maybe_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?;
243    let maybe_rel_b = get_maybe_relocatable_from_var_name("b", vm, ids_data, ap_tracking)?;
244    match (maybe_rel_a, maybe_rel_b) {
245        (MaybeRelocatable::Int(a), MaybeRelocatable::Int(b)) => {
246            if (a - b).is_zero() {
247                return Err(HintError::AssertNotEqualFail(Box::new((
248                    MaybeRelocatable::Int(a),
249                    MaybeRelocatable::Int(b),
250                ))));
251            };
252            Ok(())
253        }
254        (MaybeRelocatable::RelocatableValue(a), MaybeRelocatable::RelocatableValue(b)) => {
255            if a.segment_index != b.segment_index {
256                Err(VirtualMachineError::DiffIndexComp(Box::new((a, b))))?;
257            };
258            if a.offset == b.offset {
259                return Err(HintError::AssertNotEqualFail(Box::new((
260                    MaybeRelocatable::RelocatableValue(a),
261                    MaybeRelocatable::RelocatableValue(b),
262                ))));
263            };
264            Ok(())
265        }
266        (a, b) => Err(VirtualMachineError::DiffTypeComparison(Box::new((a, b))))?,
267    }
268}
269
270//Implements hint:
271// %{
272//     from starkware.cairo.common.math_utils import assert_integer
273//     assert_integer(ids.a)
274//     assert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'
275// %}
276pub fn assert_nn(
277    vm: &mut VirtualMachine,
278    ids_data: &HashMap<String, HintReference>,
279    ap_tracking: &ApTracking,
280) -> Result<(), HintError> {
281    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
282    let range_check_builtin = vm.get_range_check_builtin()?;
283    // assert 0 <= ids.a % PRIME < range_check_builtin.bound
284    // as prime > 0, a % prime will always be > 0
285    if a.as_ref() >= range_check_builtin.bound() {
286        Err(HintError::AssertNNValueOutOfRange(Box::new(a)))
287    } else {
288        Ok(())
289    }
290}
291
292//Implements hint:from starkware.cairo.common.math.cairo
293// %{
294// from starkware.cairo.common.math_utils import assert_integer
295// assert_integer(ids.value)
296// assert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'
297// %}
298pub fn assert_not_zero(
299    vm: &mut VirtualMachine,
300    ids_data: &HashMap<String, HintReference>,
301    ap_tracking: &ApTracking,
302) -> Result<(), HintError> {
303    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
304    if value.is_zero() {
305        return Err(HintError::AssertNotZero(Box::new((
306            value,
307            crate::utils::PRIME_STR.to_string(),
308        ))));
309    };
310    Ok(())
311}
312
313//Implements hint: assert ids.value == 0, 'split_int(): value is out of range.'
314pub fn split_int_assert_range(
315    vm: &mut VirtualMachine,
316    ids_data: &HashMap<String, HintReference>,
317    ap_tracking: &ApTracking,
318) -> Result<(), HintError> {
319    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
320    //Main logic (assert value == 0)
321    if !value.is_zero() {
322        return Err(HintError::SplitIntNotZero);
323    }
324    Ok(())
325}
326
327//Implements hint: memory[ids.output] = res = (int(ids.value) % PRIME) % ids.base
328//        assert res < ids.bound, f'split_int(): Limb {res} is out of range.'
329pub fn split_int(
330    vm: &mut VirtualMachine,
331    ids_data: &HashMap<String, HintReference>,
332    ap_tracking: &ApTracking,
333) -> Result<(), HintError> {
334    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
335    let base = get_integer_from_var_name("base", vm, ids_data, ap_tracking)?;
336    let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?;
337    let base = &base
338        .as_ref()
339        .try_into()
340        .map_err(|_| MathError::DividedByZero)?;
341    let bound = bound.as_ref();
342    let output = get_ptr_from_var_name("output", vm, ids_data, ap_tracking)?;
343    //Main Logic
344    let res = value.mod_floor(base);
345    if &res > bound {
346        return Err(HintError::SplitIntLimbOutOfRange(Box::new(res)));
347    }
348    vm.insert_value(output, res).map_err(HintError::Memory)
349}
350
351//from starkware.cairo.common.math_utils import is_positive
352//ids.is_positive = 1 if is_positive(
353//    value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0
354pub fn is_positive(
355    vm: &mut VirtualMachine,
356    ids_data: &HashMap<String, HintReference>,
357    ap_tracking: &ApTracking,
358) -> Result<(), HintError> {
359    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
360    let value_as_int = signed_felt(value);
361    let range_check_builtin = vm.get_range_check_builtin()?;
362
363    // Avoid using abs so we don't allocate a new BigInt
364    let (sign, abs_value) = value_as_int.into_parts();
365    //Main logic (assert a is positive)
366    if abs_value >= range_check_builtin.bound().to_biguint() {
367        return Err(HintError::ValueOutsideValidRange(Box::new(value)));
368    }
369
370    let result = Felt252::from((sign == Sign::Plus) as u8);
371    insert_value_from_var_name("is_positive", result, vm, ids_data, ap_tracking)
372}
373
374//Implements hint:
375// %{
376//     from starkware.cairo.common.math_utils import assert_integer
377//     assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128
378//     assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW
379//     assert_integer(ids.value)
380//     ids.low = ids.value & ((1 << 128) - 1)
381//     ids.high = ids.value >> 128
382// %}
383pub fn split_felt(
384    vm: &mut VirtualMachine,
385    ids_data: &HashMap<String, HintReference>,
386    ap_tracking: &ApTracking,
387    constants: &HashMap<String, Felt252>,
388) -> Result<(), HintError> {
389    let assert = |b: bool, msg: &str| {
390        b.then_some(())
391            .ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str()))
392    };
393    let bound = pow2_const(128);
394    let max_high = get_constant_from_var_name("MAX_HIGH", constants)?;
395    let max_low = get_constant_from_var_name("MAX_LOW", constants)?;
396    assert(
397        max_high < &bound && max_low < &bound,
398        "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128",
399    )?;
400    assert(
401        Felt252::MAX == max_high * bound + max_low,
402        "assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW",
403    )?;
404    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
405    let value = value.as_ref();
406    //Main logic
407    //assert_integer(ids.value) (done by match)
408    // ids.low = ids.value & ((1 << 128) - 1)
409    // ids.high = ids.value >> 128
410    let (high, low) = value.div_rem(&bound.try_into().unwrap());
411    insert_value_from_var_name("high", high, vm, ids_data, ap_tracking)?;
412    insert_value_from_var_name("low", low, vm, ids_data, ap_tracking)
413}
414
415//Implements hint: from starkware.python.math_utils import isqrt
416//        value = ids.value % PRIME
417//        assert value < 2 ** 250, f"value={value} is outside of the range [0, 2**250)."
418//        assert 2 ** 250 < PRIME
419//        ids.root = isqrt(value)
420pub fn sqrt(
421    vm: &mut VirtualMachine,
422    ids_data: &HashMap<String, HintReference>,
423    ap_tracking: &ApTracking,
424) -> Result<(), HintError> {
425    let mod_value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
426    //This is equal to mod_value > Felt252::from(2).pow(250)
427    if mod_value > pow2_const(250) {
428        return Err(HintError::ValueOutside250BitRange(Box::new(mod_value)));
429        //This is equal to mod_value > bigint!(2).pow(250)
430    }
431    insert_value_from_var_name(
432        "root",
433        Felt252::from(&isqrt(&mod_value.to_biguint())?),
434        vm,
435        ids_data,
436        ap_tracking,
437    )
438}
439
440pub fn signed_div_rem(
441    vm: &mut VirtualMachine,
442    ids_data: &HashMap<String, HintReference>,
443    ap_tracking: &ApTracking,
444) -> Result<(), HintError> {
445    let div = get_integer_from_var_name("div", vm, ids_data, ap_tracking)?;
446    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
447    let value = value.as_ref();
448    let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?;
449    let builtin = vm.get_range_check_builtin()?;
450
451    let builtin_bound = builtin.bound();
452    if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? {
453        return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound))));
454    }
455    let builtin_bound_div_2 = builtin_bound.field_div(&Felt252::TWO.try_into().unwrap());
456    if bound > builtin_bound_div_2 {
457        return Err(HintError::OutOfValidRange(Box::new((
458            bound,
459            builtin_bound_div_2,
460        ))));
461    }
462
463    let int_value = signed_felt(*value);
464    let int_div = div.to_bigint();
465    let int_bound = bound.to_bigint();
466    let (q, r) = int_value.div_mod_floor(&int_div);
467
468    if int_bound.abs() < q.abs() {
469        return Err(HintError::OutOfValidRange(Box::new((
470            Felt252::from(&q),
471            bound,
472        ))));
473    }
474
475    let biased_q = q + int_bound;
476    insert_value_from_var_name("r", Felt252::from(&r), vm, ids_data, ap_tracking)?;
477    insert_value_from_var_name(
478        "biased_q",
479        Felt252::from(&biased_q),
480        vm,
481        ids_data,
482        ap_tracking,
483    )
484}
485
486/*
487Implements hint:
488
489from starkware.cairo.common.math_utils import assert_integer
490assert_integer(ids.div)
491assert 0 < ids.div <= PRIME // range_check_builtin.bound, \
492    f'div={hex(ids.div)} is out of the valid range.'
493ids.q, ids.r = divmod(ids.value, ids.div)
494*/
495pub fn unsigned_div_rem(
496    vm: &mut VirtualMachine,
497    ids_data: &HashMap<String, HintReference>,
498    ap_tracking: &ApTracking,
499) -> Result<(), HintError> {
500    let div = get_integer_from_var_name("div", vm, ids_data, ap_tracking)?;
501    let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
502    let builtin_bound = vm.get_range_check_builtin()?.bound();
503
504    // Main logic
505    if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? {
506        return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound))));
507    }
508
509    let (q, r) = value.div_rem(&(div).try_into().map_err(|_| MathError::DividedByZero)?);
510    insert_value_from_var_name("r", r, vm, ids_data, ap_tracking)?;
511    insert_value_from_var_name("q", q, vm, ids_data, ap_tracking)
512}
513
514//Implements hint: from starkware.cairo.common.math_utils import as_int
515//        # Correctness check.
516//        value = as_int(ids.value, PRIME) % PRIME
517//        assert value < ids.UPPER_BOUND, f'{value} is outside of the range [0, 2**250).'
518//        # Calculation for the assertion.
519//        ids.high, ids.low = divmod(ids.value, ids.SHIFT)
520pub fn assert_250_bit(
521    vm: &mut VirtualMachine,
522    ids_data: &HashMap<String, HintReference>,
523    ap_tracking: &ApTracking,
524    constants: &HashMap<String, Felt252>,
525) -> Result<(), HintError> {
526    const UPPER_BOUND: &str = "starkware.cairo.common.math.assert_250_bit.UPPER_BOUND";
527    const SHIFT: &str = "starkware.cairo.common.math.assert_250_bit.SHIFT";
528    //Declare constant values
529    let upper_bound = constants
530        .get(UPPER_BOUND)
531        .map_or_else(|| get_constant_from_var_name("UPPER_BOUND", constants), Ok)?;
532    let shift = constants
533        .get(SHIFT)
534        .map_or_else(|| get_constant_from_var_name("SHIFT", constants), Ok)?;
535    let value = Felt252::from(&signed_felt(get_integer_from_var_name(
536        "value",
537        vm,
538        ids_data,
539        ap_tracking,
540    )?));
541    //Main logic
542    if &value > upper_bound {
543        return Err(HintError::ValueOutside250BitRange(Box::new(value)));
544    }
545    let (high, low) = value.div_rem(&shift.try_into().map_err(|_| MathError::DividedByZero)?);
546    insert_value_from_var_name("high", high, vm, ids_data, ap_tracking)?;
547    insert_value_from_var_name("low", low, vm, ids_data, ap_tracking)
548}
549
550// Implements hint:
551// %{ ids.is_250 = 1 if ids.addr < 2**250 else 0 %}
552pub fn is_250_bits(
553    vm: &mut VirtualMachine,
554    ids_data: &HashMap<String, HintReference>,
555    ap_tracking: &ApTracking,
556) -> Result<(), HintError> {
557    let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?;
558
559    // Main logic: ids.is_250 = 1 if ids.addr < 2**250 else 0
560    let is_250 = Felt252::from((addr.as_ref().bits() <= 250) as u8);
561
562    insert_value_from_var_name("is_250", is_250, vm, ids_data, ap_tracking)
563}
564
565/*
566Implements hint:
567%{
568    # Verify the assumptions on the relationship between 2**250, ADDR_BOUND and PRIME.
569    ADDR_BOUND = ids.ADDR_BOUND % PRIME
570    assert (2**250 < ADDR_BOUND <= 2**251) and (2 * 2**250 < PRIME) and (
571            ADDR_BOUND * 2 > PRIME), \
572        'normalize_address() cannot be used with the current constants.'
573    ids.is_small = 1 if ids.addr < ADDR_BOUND else 0
574%}
575*/
576pub fn is_addr_bounded(
577    vm: &mut VirtualMachine,
578    ids_data: &HashMap<String, HintReference>,
579    ap_tracking: &ApTracking,
580    constants: &HashMap<String, Felt252>,
581) -> Result<(), HintError> {
582    let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?;
583
584    let addr_bound = constants
585        .get(ADDR_BOUND)
586        .ok_or_else(|| HintError::MissingConstant(Box::new(ADDR_BOUND)))?
587        .to_biguint();
588
589    let lower_bound = BigUint::one() << 250_usize;
590    let upper_bound = BigUint::one() << 251_usize;
591
592    // assert (2**250 < ADDR_BOUND <= 2**251) and (2 * 2**250 < PRIME) and (
593    //      ADDR_BOUND * 2 > PRIME), \
594    //      'normalize_address() cannot be used with the current constants.'
595    // The second check is not needed, as it's true for the CAIRO_PRIME
596    if !(lower_bound < addr_bound
597        && addr_bound <= upper_bound
598        && (&addr_bound << 1_usize) > *CAIRO_PRIME)
599    {
600        return Err(HintError::AssertionFailed(
601            "normalize_address() cannot be used with the current constants."
602                .to_string()
603                .into_boxed_str(),
604        ));
605    }
606
607    // Main logic: ids.is_small = 1 if ids.addr < ADDR_BOUND else 0
608    let is_small = Felt252::from((addr.as_ref() < &Felt252::from(&addr_bound)) as u8);
609
610    insert_value_from_var_name("is_small", is_small, vm, ids_data, ap_tracking)
611}
612
613/*
614Implements hint:
615%{
616    from starkware.cairo.common.math_utils import assert_integer
617    assert_integer(ids.a)
618    assert_integer(ids.b)
619    assert (ids.a % PRIME) < (ids.b % PRIME), \
620        f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'
621%}
622*/
623pub fn assert_lt_felt(
624    vm: &mut VirtualMachine,
625    ids_data: &HashMap<String, HintReference>,
626    ap_tracking: &ApTracking,
627) -> Result<(), HintError> {
628    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
629    let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?;
630    // Main logic
631    // assert_integer(ids.a)
632    // assert_integer(ids.b)
633    // assert (ids.a % PRIME) < (ids.b % PRIME), \
634    //     f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'
635    if a >= b {
636        return Err(HintError::AssertLtFelt252(Box::new((a, b))));
637    };
638    Ok(())
639}
640
641pub fn is_quad_residue(
642    vm: &mut VirtualMachine,
643    ids_data: &HashMap<String, HintReference>,
644    ap_tracking: &ApTracking,
645) -> Result<(), HintError> {
646    let x = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?;
647
648    if x.is_zero() || x == Felt252::ONE {
649        insert_value_from_var_name("y", *x.as_ref(), vm, ids_data, ap_tracking)
650    // } else if Pow::pow(felt_to_biguint(x), &(&*CAIRO_PRIME >> 1_u32)).is_one() {
651    } else if x.pow_felt(&Felt252::MAX.div_rem(&Felt252::TWO.try_into().unwrap()).0) == Felt252::ONE
652    {
653        insert_value_from_var_name("y", x.sqrt().unwrap_or_default(), vm, ids_data, ap_tracking)
654    } else {
655        insert_value_from_var_name(
656            "y",
657            (x.field_div(&Felt252::THREE.try_into().unwrap()))
658                .sqrt()
659                .unwrap_or_default(),
660            vm,
661            ids_data,
662            ap_tracking,
663        )
664    }
665}
666
667fn div_prime_by_bound(bound: Felt252) -> Result<Felt252, VirtualMachineError> {
668    let prime: &BigUint = &CAIRO_PRIME;
669    let limit = prime / bound.to_biguint();
670    Ok(Felt252::from(&limit))
671}
672
673fn prime_div_constant(bound: u32) -> Result<BigUint, VirtualMachineError> {
674    let prime: &BigUint = &CAIRO_PRIME;
675    let limit = prime / bound;
676    Ok(limit)
677}
678
679/* Implements hint:
680   %{
681       ids.a_lsb = ids.a & 1
682       ids.b_lsb = ids.b & 1
683   %}
684*/
685pub fn a_b_bitand_1(
686    vm: &mut VirtualMachine,
687    ids_data: &HashMap<String, HintReference>,
688    ap_tracking: &ApTracking,
689) -> Result<(), HintError> {
690    let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
691    let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?;
692    let two = Felt252::TWO.try_into().unwrap();
693    let a_lsb = a.mod_floor(&two);
694    let b_lsb = b.mod_floor(&two);
695    insert_value_from_var_name("a_lsb", a_lsb, vm, ids_data, ap_tracking)?;
696    insert_value_from_var_name("b_lsb", b_lsb, vm, ids_data, ap_tracking)
697}
698
699lazy_static! {
700    static ref SPLIT_XX_PRIME: BigUint = BigUint::parse_bytes(
701        b"57896044618658097711785492504343953926634992332820282019728792003956564819949",
702        10
703    )
704    .unwrap();
705    static ref II: BigUint = BigUint::parse_bytes(
706        b"19681161376707505956807079304988542015446066515923890162744021073123829784752",
707        10
708    )
709    .unwrap();
710}
711
712/* Implements hint:
713   PRIME = 2**255 - 19
714   II = pow(2, (PRIME - 1) // 4, PRIME)
715
716   xx = ids.xx.low + (ids.xx.high<<128)
717   x = pow(xx, (PRIME + 3) // 8, PRIME)
718   if (x * x - xx) % PRIME != 0:
719       x = (x * II) % PRIME
720   if x % 2 != 0:
721       x = PRIME - x
722   ids.x.low = x & ((1<<128)-1)
723   ids.x.high = x >> 128
724
725   Note: doesnt belong to and is not variation of any hint from common/math
726*/
727pub fn split_xx(
728    vm: &mut VirtualMachine,
729    ids_data: &HashMap<String, HintReference>,
730    ap_tracking: &ApTracking,
731) -> Result<(), HintError> {
732    let xx = Uint256::from_var_name("xx", vm, ids_data, ap_tracking)?;
733    let x_addr = get_relocatable_from_var_name("x", vm, ids_data, ap_tracking)?;
734    let xx: BigUint = xx.low.to_biguint() + (*xx.high * pow2_const(128)).to_biguint();
735    let mut x = xx.modpow(
736        &(&*SPLIT_XX_PRIME + 3_u32).div_floor(&BigUint::from(8_u32)),
737        &SPLIT_XX_PRIME,
738    );
739    if !(&x * &x - xx).mod_floor(&SPLIT_XX_PRIME).is_zero() {
740        x = (&x * &*II).mod_floor(&SPLIT_XX_PRIME)
741    };
742    if !x.mod_floor(&2_u32.into()).is_zero() {
743        x = &*SPLIT_XX_PRIME - x;
744    }
745
746    vm.insert_value(x_addr, Felt252::from(&(&x & &BigUint::from(u128::MAX))))?;
747    vm.insert_value((x_addr + 1)?, Felt252::from(&(x >> 128_u32)))?;
748
749    Ok(())
750}
751
752#[cfg(test)]
753mod tests {
754    use super::*;
755    use crate::{felt_hex, felt_str};
756    use core::ops::Neg;
757
758    use crate::{
759        any_box,
760        hint_processor::{
761            builtin_hint_processor::{
762                builtin_hint_processor_definition::{BuiltinHintProcessor, HintProcessorData},
763                hint_code,
764            },
765            hint_processor_definition::HintProcessorLogic,
766        },
767        relocatable,
768        types::exec_scope::ExecutionScopes,
769        types::relocatable::Relocatable,
770        utils::test_utils::*,
771        vm::{errors::memory_errors::MemoryError, vm_core::VirtualMachine},
772    };
773    use assert_matches::assert_matches;
774
775    #[cfg(not(target_arch = "wasm32"))]
776    use proptest::prelude::*;
777
778    #[cfg(target_arch = "wasm32")]
779    use wasm_bindgen_test::*;
780
781    #[test]
782    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
783    fn run_is_nn_hint_false() {
784        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
785        let mut vm = vm_with_range_check!();
786        //Initialize fp
787        vm.run_context.fp = 10;
788        //Insert ids into memory
789        vm.segments = segments![((1, 9), (-1))];
790        add_segments!(vm, 1);
791        //Create ids_data & hint_data
792        let ids_data = ids_data!["a"];
793        //Execute the hint
794        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
795        //Check that ap now contains false (1)
796        check_memory![vm.segments.memory, ((1, 0), 1)];
797    }
798
799    #[test]
800    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
801    fn run_is_nn_hint_true() {
802        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
803        let mut vm = vm_with_range_check!();
804        //Initialize fp
805        vm.run_context.fp = 5;
806        //Insert ids into memory
807        vm.segments = segments![((1, 4), 1)];
808        add_segments!(vm, 1);
809        //Create ids_data
810        let ids_data = ids_data!["a"];
811        //Execute the hint
812        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
813        //Check that ap now contains true (0)
814        check_memory![vm.segments.memory, ((1, 0), 0)];
815    }
816
817    #[test]
818    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
819    //This test contemplates the case when the number itself is negative, but it is within the range (-prime, -range_check_bound)
820    //Making the comparison return 1 (true)
821    fn run_is_nn_hint_true_border_case() {
822        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
823        let mut vm = vm_with_range_check!();
824        //Initialize fp
825        vm.run_context.fp = 5;
826        //Insert ids into memory
827        add_segments!(vm, 2);
828        vm.insert_value(
829            (1, 4).into(),
830            felt_str!(
831                "3618502788666131213697322783095070105623107215331596699973092056135872020480"
832            )
833            .neg(),
834        )
835        .unwrap();
836        //Create ids_data
837        let ids_data = ids_data!["a"];
838        //Execute the hint
839        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
840        //Check that ap now contains true (0)
841        check_memory![vm.segments.memory, ((1, 0), 0)];
842    }
843
844    #[test]
845    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
846    fn run_is_nn_hint_no_range_check_builtin() {
847        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
848        let mut vm = vm!();
849        //Initialize fp
850        vm.run_context.fp = 5;
851        //Insert ids into memory
852        vm.segments = segments![((1, 4), 1)];
853        //Create ids_data
854        let ids_data = ids_data!["a"];
855        //Execute the hint
856        assert_matches!(
857            run_hint!(vm, ids_data, hint_code),
858            Err(HintError::Internal(
859                VirtualMachineError::NoRangeCheckBuiltin
860            ))
861        );
862    }
863
864    #[test]
865    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
866    fn run_is_nn_hint_incorrect_ids() {
867        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
868        let mut vm = vm_with_range_check!();
869        add_segments!(vm, 2);
870        //Initialize ap
871        //Create ids_data & hint_data
872        let ids_data = ids_data!["b"];
873        //Execute the hint
874        assert_matches!(
875            run_hint!(vm, ids_data, hint_code),
876            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "a"
877        );
878    }
879
880    #[test]
881    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
882    fn run_is_nn_hint_cant_get_ids_from_memory() {
883        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
884        let mut vm = vm_with_range_check!();
885        add_segments!(vm, 2);
886        //Initialize fp
887        vm.run_context.fp = 5;
888        //Dont insert ids into memory
889        //Create ids_data
890        let ids_data = ids_data!["a"];
891        //Execute the hint
892        assert_matches!(
893            run_hint!(vm, ids_data, hint_code),
894            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "a"
895        );
896    }
897
898    #[test]
899    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
900    fn run_is_nn_hint_ids_are_relocatable_values() {
901        let hint_code = "memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1";
902        let mut vm = vm_with_range_check!();
903        //Initialize fp
904        vm.run_context.fp = 5;
905        //Insert ids into memory
906        vm.segments = segments![((1, 4), (2, 3))];
907        //Create ids_data
908        let ids_data = ids_data!["a"];
909        //Execute the hint
910        assert_matches!(
911            run_hint!(vm, ids_data, hint_code),
912            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "a"
913        );
914    }
915
916    #[test]
917    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
918    fn run_assert_le_felt_valid() {
919        let mut constants = HashMap::new();
920        constants.insert(
921            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(),
922            felt_hex!("4000000000000088000000000000001"),
923        );
924        constants.insert(
925            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(),
926            felt_hex!("2AAAAAAAAAAAAB05555555555555556"),
927        );
928        let mut vm = vm_with_range_check!();
929        let mut exec_scopes = scope![("excluded", 1)];
930        //Initialize fp
931        vm.run_context.fp = 3;
932        //Insert ids into memory
933        vm.segments = segments![((1, 0), 1), ((1, 1), 2), ((1, 2), (2, 0))];
934        add_segments!(vm, 1);
935        //Create ids_data & hint_data
936        let ids_data = ids_data!["a", "b", "range_check_ptr"];
937        //Execute the hint
938        assert_matches!(
939            run_hint!(
940                vm,
941                ids_data,
942                hint_code::ASSERT_LE_FELT,
943                &mut exec_scopes,
944                &constants
945            ),
946            Ok(())
947        );
948        //Hint would return an error if the assertion fails
949    }
950
951    #[test]
952    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
953    fn is_le_felt_hint_true() {
954        let hint_code = "memory[ap] = 0 if (ids.a % PRIME) <= (ids.b % PRIME) else 1";
955        let mut vm = vm_with_range_check!();
956        //Initialize fp
957        vm.run_context.fp = 10;
958        //Insert ids into memory
959        vm.segments = segments![((1, 8), 1), ((1, 9), 2)];
960        add_segments!(vm, 1);
961        let ids_data = ids_data!["a", "b"];
962        //Execute the hint
963        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
964        //Check result
965        check_memory![vm.segments.memory, ((1, 0), 0)];
966    }
967
968    #[test]
969    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
970    fn run_is_le_felt_hint_inconsistent_memory() {
971        let hint_code = "memory[ap] = 0 if (ids.a % PRIME) <= (ids.b % PRIME) else 1";
972        let mut vm = vm_with_range_check!();
973        //Initialize fp
974        vm.run_context.fp = 2;
975        vm.segments = segments![((1, 0), 1), ((1, 1), 2)];
976        //Create ids_data & hint_data
977        let ids_data = ids_data!["a", "b"];
978        //Execute the hint
979        assert_matches!(
980            run_hint!(vm, ids_data, hint_code),
981            Err(HintError::Memory(
982                MemoryError::InconsistentMemory(bx)
983            )) if *bx == (Relocatable::from((1, 0)),
984                    MaybeRelocatable::Int(Felt252::ONE),
985                    MaybeRelocatable::Int(Felt252::ZERO))
986        );
987    }
988
989    #[test]
990    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
991    fn run_is_le_felt_hint_incorrect_ids() {
992        let hint_code = "memory[ap] = 0 if (ids.a % PRIME) <= (ids.b % PRIME) else 1";
993        let mut vm = vm!();
994        vm.run_context.fp = 10;
995        vm.segments = segments![((1, 8), 1), ((1, 9), 2)];
996        //Create ids_data & hint_data
997        let ids_data = ids_data!["a", "c"];
998        assert_matches!(
999            run_hint!(vm, ids_data, hint_code),
1000            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "b"
1001        );
1002    }
1003
1004    #[test]
1005    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1006    fn run_assert_nn_valid() {
1007        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1008        let mut vm = vm_with_range_check!();
1009        //Initialize fp
1010        vm.run_context.fp = 1;
1011        //Insert ids into memory
1012        vm.segments = segments![((1, 0), 1)];
1013        //Create ids_data & hint_data
1014        let ids_data = ids_data!["a"];
1015        //Execute the hint
1016        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1017        //Hint would return an error if the assertion fails
1018    }
1019
1020    #[test]
1021    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1022    fn run_assert_nn_invalid() {
1023        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1024        let mut vm = vm_with_range_check!();
1025        //Initialize fp
1026        vm.run_context.fp = 1;
1027        //Insert ids into memory
1028        vm.segments = segments![((1, 0), (-1))];
1029        //Create ids_data & hint_data
1030        let ids_data = ids_data!["a"];
1031        //Execute the hint
1032        assert_matches!(
1033            run_hint!(vm, ids_data, hint_code),
1034            Err(HintError::AssertNNValueOutOfRange(bx)) if *bx == Felt252::from(-1)
1035        );
1036    }
1037
1038    #[test]
1039    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1040    fn run_assert_nn_incorrect_ids() {
1041        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1042        let mut vm = vm_with_range_check!();
1043        //Initialize fp
1044        vm.run_context.fp = 4;
1045        //Insert ids into memory
1046        vm.segments = segments![((1, 0), (-1))];
1047        let ids_data = ids_data!["incorrect_id"];
1048        //Execute the hint
1049        assert_matches!(
1050            run_hint!(vm, ids_data, hint_code),
1051            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "a"
1052        );
1053    }
1054
1055    #[test]
1056    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1057    fn run_assert_nn_a_is_not_integer() {
1058        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1059        let mut vm = vm_with_range_check!();
1060        //Initialize fp
1061        vm.run_context.fp = 1;
1062        //Insert ids into memory
1063        vm.segments = segments![((1, 0), (10, 10))];
1064        let ids_data = ids_data!["a"];
1065        //Execute the hint
1066        assert_matches!(
1067            run_hint!(vm, ids_data, hint_code),
1068            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "a"
1069        );
1070    }
1071
1072    #[test]
1073    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1074    fn run_assert_nn_no_range_check_builtin() {
1075        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1076        let mut vm = vm!();
1077        //Initialize fp
1078        vm.run_context.fp = 1;
1079        //Insert ids into memory
1080        vm.segments = segments![((1, 0), 1)];
1081        let ids_data = ids_data!["a"];
1082        //Execute the hint
1083        assert_matches!(
1084            run_hint!(vm, ids_data, hint_code),
1085            Err(HintError::Internal(
1086                VirtualMachineError::NoRangeCheckBuiltin
1087            ))
1088        );
1089    }
1090
1091    #[test]
1092    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1093    fn run_assert_nn_reference_is_not_in_memory() {
1094        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'";
1095        let mut vm = vm_with_range_check!();
1096        add_segments!(vm, 1);
1097        //Initialize fp
1098        vm.run_context.fp = 4;
1099        let ids_data = ids_data!["a"];
1100        //Execute the hint
1101        assert_matches!(
1102            run_hint!(vm, ids_data, hint_code),
1103            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "a"
1104        );
1105    }
1106
1107    #[test]
1108    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1109    fn run_is_assert_le_felt_invalid() {
1110        let mut vm = vm_with_range_check!();
1111        let mut constants = HashMap::new();
1112        constants.insert(
1113            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(),
1114            felt_hex!("4000000000000088000000000000001"),
1115        );
1116        constants.insert(
1117            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(),
1118            felt_hex!("2AAAAAAAAAAAAB05555555555555556"),
1119        );
1120        let mut exec_scopes = scope![("excluded", Felt252::ONE)];
1121        //Initialize fp
1122        vm.run_context.fp = 3;
1123        //Insert ids into memory
1124        vm.segments = segments![((1, 0), 2), ((1, 1), 1), ((1, 2), (2, 0))];
1125        let ids_data = ids_data!["a", "b", "range_check_ptr"];
1126        add_segments!(vm, 1);
1127        //Execute the hint
1128        assert_matches!(
1129            run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants),
1130            Err(HintError::NonLeFelt252(bx)) if *bx == (Felt252::from(2), Felt252::ONE)
1131        );
1132    }
1133
1134    #[test]
1135    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1136    fn run_is_assert_le_felt_a_is_not_integer() {
1137        let mut vm = vm_with_range_check!();
1138        let mut constants = HashMap::new();
1139        constants.insert(
1140            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(),
1141            felt_hex!("4000000000000088000000000000001"),
1142        );
1143        constants.insert(
1144            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(),
1145            felt_hex!("2AAAAAAAAAAAAB05555555555555556"),
1146        );
1147        let mut exec_scopes = scope![("excluded", 1)];
1148        //Initialize fp
1149        vm.run_context.fp = 3;
1150        //Insert ids into memory
1151        vm.segments = segments![((1, 0), (1, 0)), ((1, 1), 1), ((1, 2), (2, 0))];
1152        let ids_data = ids_data!["a", "b", "range_check_ptr"];
1153        //Execute the hint
1154        assert_matches!(
1155            run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants),
1156            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "a"
1157        );
1158    }
1159
1160    #[test]
1161    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1162    fn run_is_assert_le_felt_b_is_not_integer() {
1163        let mut vm = vm_with_range_check!();
1164        let mut constants = HashMap::new();
1165        constants.insert(
1166            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(),
1167            felt_hex!("4000000000000088000000000000001"),
1168        );
1169        constants.insert(
1170            "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(),
1171            felt_hex!("2AAAAAAAAAAAAB05555555555555556"),
1172        );
1173        let mut exec_scopes = scope![("excluded", 1)];
1174        //Initialize fp
1175        vm.run_context.fp = 3;
1176        //Insert ids into memory
1177        vm.segments = segments![((1, 0), 1), ((1, 1), (1, 0)), ((1, 2), (2, 0))];
1178        let ids_data = ids_data!["a", "b", "range_check_builtin"];
1179        //Execute the hint
1180        assert_matches!(
1181            run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants),
1182            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "b"
1183        );
1184    }
1185
1186    #[test]
1187    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1188    fn run_is_nn_hint_out_of_range_false() {
1189        let hint_code =
1190            "memory[ap] = 0 if 0 <= ((-ids.a - 1) % PRIME) < range_check_builtin.bound else 1";
1191        let mut vm = vm_with_range_check!();
1192        //Initialize fp
1193        vm.run_context.fp = 5;
1194        //Insert ids into memory
1195        vm.segments = segments![((1, 4), 2)];
1196        add_segments!(vm, 1);
1197        //Create ids_data
1198        let ids_data = ids_data!["a"];
1199        //Execute the hint
1200        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
1201        check_memory![vm.segments.memory, ((1, 0), 1)];
1202    }
1203
1204    #[test]
1205    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1206    fn run_is_nn_hint_out_of_range_true() {
1207        let hint_code =
1208            "memory[ap] = 0 if 0 <= ((-ids.a - 1) % PRIME) < range_check_builtin.bound else 1";
1209        let mut vm = vm_with_range_check!();
1210        //Initialize fp
1211        vm.run_context.fp = 5;
1212        //Insert ids into memory
1213        vm.segments = segments![((1, 4), (-1))];
1214        add_segments!(vm, 1);
1215        //Create ids_data
1216        let ids_data = ids_data!["a"];
1217        //Execute the hint
1218        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
1219        check_memory![vm.segments.memory, ((1, 0), 0)];
1220    }
1221    #[test]
1222    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1223    fn run_assert_not_equal_int_false() {
1224        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1225        let mut vm = vm!();
1226        //Initialize fp
1227        vm.run_context.fp = 10;
1228        //Insert ids into memory
1229        vm.segments = segments![((1, 8), 1), ((1, 9), 1)];
1230        let ids_data = ids_data!["a", "b"];
1231        //Execute the hint
1232        assert_matches!(
1233            run_hint!(vm, ids_data, hint_code),
1234            Err(HintError::AssertNotEqualFail(bx))
1235            if *bx == (MaybeRelocatable::from(Felt252::ONE), MaybeRelocatable::from(Felt252::ONE))
1236        );
1237    }
1238
1239    #[test]
1240    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1241    fn run_assert_not_equal_int_true() {
1242        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1243        let mut vm = vm!();
1244        //Initialize fp
1245        vm.run_context.fp = 10;
1246        //Insert ids into memory
1247        vm.segments = segments![((1, 8), 1), ((1, 9), 3)];
1248        let ids_data = ids_data!["a", "b"];
1249        //Execute the hint
1250        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1251    }
1252
1253    #[test]
1254    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1255    fn run_assert_not_equal_int_bignum_true() {
1256        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1257        let mut vm = vm!();
1258        add_segments!(vm, 2);
1259        //Initialize fp
1260        vm.run_context.fp = 10;
1261        //Insert ids into memory
1262        vm.segments = segments![
1263            ((1, 8), (-1)),
1264            (
1265                (1, 9),
1266                (
1267                    "618502788666131213697322783095070105623107215331596699973092056135872020480",
1268                    10
1269                )
1270            )
1271        ];
1272        let ids_data = ids_data!["a", "b"];
1273        //Execute the hint
1274        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1275    }
1276
1277    #[test]
1278    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1279    fn run_assert_not_equal_relocatable_false() {
1280        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1281        let mut vm = vm!();
1282        //Initialize fp
1283        vm.run_context.fp = 10;
1284        //Insert ids into memory
1285        vm.segments = segments![((1, 8), (1, 0)), ((1, 9), (1, 0))];
1286        let ids_data = ids_data!["a", "b"];
1287        //Execute the hint
1288        assert_matches!(
1289            run_hint!(vm, ids_data, hint_code),
1290            Err(HintError::AssertNotEqualFail(bx))
1291            if *bx == (MaybeRelocatable::from((1, 0)), MaybeRelocatable::from((1, 0)))
1292        );
1293    }
1294
1295    #[test]
1296    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1297    fn run_assert_not_equal_relocatable_true() {
1298        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1299        let mut vm = vm!();
1300        //Initialize fp
1301        vm.run_context.fp = 10;
1302        //Insert ids into memory
1303        vm.segments = segments![((1, 8), (0, 1)), ((1, 9), (0, 0))];
1304        let ids_data = ids_data!["a", "b"];
1305        //Execute the hint
1306        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1307    }
1308
1309    #[test]
1310    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1311    fn run_assert_non_equal_relocatable_diff_index() {
1312        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1313        let mut vm = vm!();
1314        //Initialize fp
1315        vm.run_context.fp = 10;
1316        //Insert ids into memory
1317        vm.segments = segments![((1, 8), (2, 0)), ((1, 9), (1, 0))];
1318        let ids_data = ids_data!["a", "b"];
1319        //Execute the hint
1320        assert_matches!(
1321            run_hint!(vm, ids_data, hint_code),
1322            Err(HintError::Internal(VirtualMachineError::DiffIndexComp(bx)))
1323            if *bx == (relocatable!(2, 0), relocatable!(1, 0))
1324        );
1325    }
1326
1327    #[test]
1328    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1329    fn run_assert_not_equal_relocatable_and_integer() {
1330        let hint_code = "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n    isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n    ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n    f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'";
1331        let mut vm = vm!();
1332        //Initialize fp
1333        vm.run_context.fp = 10;
1334        //Insert ids into memory
1335        vm.segments = segments![((1, 8), (1, 0)), ((1, 9), 1)];
1336        let ids_data = ids_data!["a", "b"];
1337        //Execute the hint
1338        assert_matches!(
1339            run_hint!(vm, ids_data, hint_code),
1340            Err(HintError::Internal(
1341                VirtualMachineError::DiffTypeComparison(bx)
1342            )) if *bx == (MaybeRelocatable::from((1, 0)), MaybeRelocatable::from(Felt252::ONE))
1343        );
1344    }
1345
1346    #[test]
1347    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1348    fn run_assert_not_zero_true() {
1349        let hint_code =
1350    "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.value)\nassert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'";
1351        let mut vm = vm!();
1352        // //Initialize fp
1353        vm.run_context.fp = 5;
1354        //Insert ids into memory
1355        vm.segments = segments![((1, 4), 5)];
1356        //Create ids
1357        let ids_data = ids_data!["value"];
1358
1359        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1360    }
1361
1362    #[test]
1363    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1364    fn run_assert_not_zero_false() {
1365        let hint_code =
1366    "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.value)\nassert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'";
1367        let mut vm = vm!();
1368        // //Initialize fp
1369        vm.run_context.fp = 5;
1370        //Insert ids into memory
1371        vm.segments = segments![((1, 4), 0)];
1372        //Create ids
1373        let ids_data = ids_data!["value"];
1374        assert_matches!(
1375            run_hint!(vm, ids_data, hint_code),
1376            Err(HintError::AssertNotZero(bx)) if *bx == (Felt252::ZERO, crate::utils::PRIME_STR.to_string())
1377        );
1378    }
1379
1380    #[test]
1381    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1382    fn run_assert_not_zero_incorrect_id() {
1383        let hint_code =
1384    "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.value)\nassert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'";
1385        let mut vm = vm!();
1386        // //Initialize fp
1387        vm.run_context.fp = 5;
1388        //Insert ids into memory
1389        vm.segments = segments![((1, 4), 0)];
1390        //Create invalid id key
1391        let ids_data = ids_data!["incorrect_id"];
1392        assert_matches!(
1393            run_hint!(vm, ids_data, hint_code),
1394            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "value"
1395        );
1396    }
1397
1398    #[test]
1399    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1400    fn run_assert_not_zero_expected_integer_error() {
1401        let hint_code =
1402    "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.value)\nassert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'";
1403        let mut vm = vm!();
1404        // //Initialize fp
1405        vm.run_context.fp = 5;
1406        //Insert ids into memory
1407        vm.segments = segments![((1, 4), (1, 0))];
1408        //Create ids_data & hint_data
1409        let ids_data = ids_data!["value"];
1410        assert_matches!(
1411            run_hint!(vm, ids_data, hint_code),
1412            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "value"
1413        );
1414    }
1415
1416    #[test]
1417    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1418    fn run_split_int_assertion_invalid() {
1419        let hint_code = "assert ids.value == 0, 'split_int(): value is out of range.'";
1420        let mut vm = vm!();
1421        //Initialize fp
1422        vm.run_context.fp = 5;
1423        //Insert ids into memory
1424        vm.segments = segments![((1, 4), 1)];
1425        let ids_data = ids_data!["value"];
1426        //Execute the hint
1427        assert_matches!(
1428            run_hint!(vm, ids_data, hint_code),
1429            Err(HintError::SplitIntNotZero)
1430        );
1431    }
1432
1433    #[test]
1434    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1435    fn run_split_int_assertion_valid() {
1436        let hint_code = "assert ids.value == 0, 'split_int(): value is out of range.'";
1437        let mut vm = vm!();
1438        //Initialize fp
1439        vm.run_context.fp = 5;
1440        //Insert ids into memory
1441        vm.segments = segments![((1, 4), 0)];
1442        let ids_data = ids_data!["value"];
1443        //Execute the hint
1444        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1445    }
1446
1447    #[test]
1448    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1449    fn run_split_int_valid() {
1450        let hint_code = "memory[ids.output] = res = (int(ids.value) % PRIME) % ids.base\nassert res < ids.bound, f'split_int(): Limb {res} is out of range.'";
1451        let mut vm = vm!();
1452        //Initialize fp
1453        vm.run_context.fp = 4;
1454        //Insert ids into memory
1455        vm.segments = segments![((1, 0), (2, 0)), ((1, 1), 2), ((1, 2), 10), ((1, 3), 100)];
1456        add_segments!(vm, 2);
1457        let ids_data = ids_data!["output", "value", "base", "bound"];
1458        //Execute the hint
1459        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1460        check_memory![vm.segments.memory, ((2, 0), 2)];
1461    }
1462
1463    #[test]
1464    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1465    fn run_split_int_invalid() {
1466        let hint_code = "memory[ids.output] = res = (int(ids.value) % PRIME) % ids.base\nassert res < ids.bound, f'split_int(): Limb {res} is out of range.'";
1467        let mut vm = vm!();
1468        //Initialize fp
1469        vm.run_context.fp = 4;
1470        //Insert ids into memory
1471        vm.segments = segments![
1472            ((1, 0), (2, 0)),
1473            ((1, 1), 100),
1474            ((1, 2), 10000),
1475            ((1, 3), 10)
1476        ];
1477        add_segments!(vm, 2);
1478        let ids_data = ids_data!["output", "value", "base", "bound"];
1479        //Execute the hint
1480        assert_matches!(
1481            run_hint!(vm, ids_data, hint_code),
1482            Err(HintError::SplitIntLimbOutOfRange(bx)) if *bx == Felt252::from(100)
1483        );
1484    }
1485
1486    #[test]
1487    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1488    fn run_is_positive_hint_true() {
1489        let hint_code =
1490        "from starkware.cairo.common.math_utils import is_positive\nids.is_positive = 1 if is_positive(\n    value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0";
1491        let mut vm = vm_with_range_check!();
1492        //Initialize fp
1493        vm.run_context.fp = 2;
1494        //Insert ids.value into memory
1495        vm.segments = segments![((1, 0), 250)];
1496        //Dont insert ids.is_positive as we need to modify it inside the hint
1497        //Create ids
1498        let ids_data = ids_data!["value", "is_positive"];
1499        //Execute the hint
1500        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
1501        //Check that is_positive now contains 1 (true)
1502        check_memory![vm.segments.memory, ((1, 1), 1)];
1503    }
1504
1505    #[test]
1506    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1507    fn run_is_positive_hint_false() {
1508        let hint_code =
1509        "from starkware.cairo.common.math_utils import is_positive\nids.is_positive = 1 if is_positive(\n    value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0";
1510        let mut vm = vm_with_range_check!();
1511        //Initialize fp
1512        vm.run_context.fp = 2;
1513        //Insert ids.value into memory
1514        vm.segments = segments![((1, 0), (-250))];
1515        //Dont insert ids.is_positive as we need to modify it inside the hint
1516        let ids_data = ids_data!["value", "is_positive"];
1517        //Execute the hint
1518        run_hint!(vm, ids_data, hint_code).expect("Error while executing hint");
1519        //Check that is_positive now contains 0 (false)
1520        check_memory![vm.segments.memory, ((1, 1), 0)];
1521    }
1522
1523    #[test]
1524    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1525    fn run_is_positive_hint_outside_valid_range() {
1526        let hint_code =
1527        "from starkware.cairo.common.math_utils import is_positive\nids.is_positive = 1 if is_positive(\n    value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0";
1528        let mut vm = vm_with_range_check!();
1529        //Initialize fp
1530        vm.run_context.fp = 2;
1531        //Insert ids.value into memory
1532        vm.segments = segments![(
1533            (1, 0),
1534            (
1535                "618502761706184546546682988428055018603476541694452277432519575032261771265",
1536                10
1537            )
1538        )];
1539        //Dont insert ids.is_positive as we need to modify it inside the hint
1540        let ids_data = ids_data!["value", "is_positive"];
1541        //Execute the hint
1542        assert_matches!(
1543            run_hint!(vm, ids_data, hint_code),
1544            Err(HintError::ValueOutsideValidRange(bx)) if *bx == felt_str!(
1545                "618502761706184546546682988428055018603476541694452277432519575032261771265"
1546            )
1547        );
1548    }
1549
1550    #[test]
1551    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1552    fn run_is_positive_hint_is_positive_not_empty() {
1553        let hint_code ="from starkware.cairo.common.math_utils import is_positive\nids.is_positive = 1 if is_positive(\n    value=ids.value, prime=PRIME, rc_bound=range_check_builtin.bound) else 0";
1554        let mut vm = vm_with_range_check!();
1555        add_segments!(vm, 2);
1556        //Initialize fp
1557        vm.run_context.fp = 2;
1558        //Insert ids into memory
1559        vm.segments = segments![((1, 0), 2), ((1, 1), 4)];
1560        let ids_data = ids_data!["value", "is_positive"];
1561        //Execute the hint
1562        assert_matches!(
1563            run_hint!(vm, ids_data, hint_code),
1564            Err(HintError::Memory(
1565                MemoryError::InconsistentMemory(bx)
1566            )) if *bx == (Relocatable::from((1, 1)),
1567                    MaybeRelocatable::from(Felt252::from(4)),
1568                    MaybeRelocatable::from(Felt252::ONE))
1569        );
1570    }
1571
1572    #[test]
1573    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1574    fn run_sqrt_valid() {
1575        let hint_code = "from starkware.python.math_utils import isqrt\nvalue = ids.value % PRIME\nassert value < 2 ** 250, f\"value={value} is outside of the range [0, 2**250).\"\nassert 2 ** 250 < PRIME\nids.root = isqrt(value)";
1576        let mut vm = vm!();
1577        //Initialize fp
1578        vm.run_context.fp = 2;
1579        //Insert ids.value into memory
1580        vm.segments = segments![((1, 0), 81)];
1581        //Create ids
1582        let ids_data = ids_data!["value", "root"];
1583        //Execute the hint
1584        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1585        //Check that root (0,1) has the square root of 81
1586        check_memory![vm.segments.memory, ((1, 1), 9)];
1587    }
1588
1589    #[test]
1590    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1591    fn run_sqrt_invalid_negative_number() {
1592        let hint_code = "from starkware.python.math_utils import isqrt\nvalue = ids.value % PRIME\nassert value < 2 ** 250, f\"value={value} is outside of the range [0, 2**250).\"\nassert 2 ** 250 < PRIME\nids.root = isqrt(value)";
1593        let mut vm = vm!();
1594        //Initialize fp
1595        vm.run_context.fp = 2;
1596        //Insert ids.value into memory
1597        vm.segments = segments![((1, 0), (-81))];
1598        //Create ids
1599        let ids_data = ids_data!["value", "root"];
1600        //Execute the hint
1601        assert_matches!(
1602            run_hint!(vm, ids_data, hint_code),
1603            Err(HintError::ValueOutside250BitRange(bx)) if *bx == felt_str!(
1604                "3618502788666131213697322783095070105623107215331596699973092056135872020400"
1605            )
1606        );
1607    }
1608
1609    #[test]
1610    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1611    fn run_sqrt_invalid_mismatched_root() {
1612        let hint_code = "from starkware.python.math_utils import isqrt\nvalue = ids.value % PRIME\nassert value < 2 ** 250, f\"value={value} is outside of the range [0, 2**250).\"\nassert 2 ** 250 < PRIME\nids.root = isqrt(value)";
1613        let mut vm = vm!();
1614        //Initialize fp
1615        vm.run_context.fp = 2;
1616        //Insert ids.value into memory
1617        vm.segments = segments![((1, 0), 81), ((1, 1), 7)];
1618        //Create ids
1619        let ids_data = ids_data!["value", "root"];
1620        //Execute the hint
1621        assert_matches!(
1622            run_hint!(vm, ids_data, hint_code),
1623            Err(HintError::Memory(
1624                MemoryError::InconsistentMemory(bx)
1625            )) if *bx == (Relocatable::from((1, 1)),
1626                    MaybeRelocatable::from(Felt252::from(7)),
1627                    MaybeRelocatable::from(Felt252::from(9)))
1628        );
1629    }
1630
1631    #[test]
1632    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1633    fn unsigned_div_rem_success() {
1634        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\nids.q, ids.r = divmod(ids.value, ids.div)";
1635        let mut vm = vm_with_range_check!();
1636        //Initialize fp
1637        vm.run_context.fp = 4;
1638        //Insert ids into memory
1639        vm.segments = segments![((1, 2), 5), ((1, 3), 7)];
1640        //Create ids
1641        let ids_data = ids_data!["r", "q", "div", "value"];
1642        //Execute the hint
1643        assert!(run_hint!(vm, ids_data, hint_code).is_ok());
1644        check_memory![vm.segments.memory, ((1, 0), 2), ((1, 1), 1)];
1645    }
1646
1647    #[test]
1648    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1649    fn unsigned_div_rem_out_of_range() {
1650        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\nids.q, ids.r = divmod(ids.value, ids.div)";
1651        let mut vm = vm_with_range_check!();
1652        //Initialize fp
1653        vm.run_context.fp = 4;
1654        //Insert ids into memory
1655        vm.segments = segments![((1, 2), (-5)), ((1, 3), 7)];
1656        //Create ids
1657        let ids_data = ids_data!["r", "q", "div", "value"];
1658        //Execute the hint
1659        assert_matches!(
1660            run_hint!(vm, ids_data, hint_code),
1661            Err(HintError::OutOfValidRange(bx))
1662            if *bx == (Felt252::from(-5), felt_str!("340282366920938463463374607431768211456"))
1663        )
1664    }
1665
1666    #[test]
1667    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1668    fn unsigned_div_rem_no_range_check_builtin() {
1669        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\nids.q, ids.r = divmod(ids.value, ids.div)";
1670        let mut vm = vm!();
1671        //Initialize fp
1672        vm.run_context.fp = 4;
1673        //Insert ids into memory
1674        vm.segments = segments![((1, 2), 5), ((1, 3), 7)];
1675        //Create ids_data
1676        let ids_data = ids_data!["r", "q", "div", "value"];
1677        assert_matches!(
1678            run_hint!(vm, ids_data, hint_code),
1679            Err(HintError::Internal(
1680                VirtualMachineError::NoRangeCheckBuiltin
1681            ))
1682        );
1683    }
1684
1685    #[test]
1686    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1687    fn unsigned_div_rem_inconsitent_memory() {
1688        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\nids.q, ids.r = divmod(ids.value, ids.div)";
1689        let mut vm = vm_with_range_check!();
1690        //Initialize fp
1691        vm.run_context.fp = 4;
1692        //Insert ids into memory
1693        vm.segments = segments![((1, 0), 5), ((1, 2), 5), ((1, 3), 7)];
1694        //Create ids_data
1695        let ids_data = ids_data!["r", "q", "div", "value"];
1696        //Execute the hint
1697        assert_matches!(
1698            run_hint!(vm, ids_data, hint_code),
1699            Err(HintError::Memory(
1700                MemoryError::InconsistentMemory(bx)
1701            )) if *bx == (Relocatable::from((1, 0)),
1702                    MaybeRelocatable::Int(Felt252::from(5)),
1703                    MaybeRelocatable::Int(Felt252::from(2)))
1704        );
1705    }
1706
1707    #[test]
1708    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1709    fn unsigned_div_rem_incorrect_ids() {
1710        let hint_code = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\nids.q, ids.r = divmod(ids.value, ids.div)";
1711        let mut vm = vm_with_range_check!();
1712        //Initialize fp
1713        vm.run_context.fp = 4;
1714        //Insert ids into memory
1715        vm.segments = segments![((1, 2), 5), ((1, 3), 7)];
1716        //Create ids
1717        let ids_data = ids_data!["a", "b", "iv", "vlue"];
1718        //Execute the hint
1719        assert_matches!(
1720            run_hint!(vm, ids_data, hint_code),
1721            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "div"
1722        )
1723    }
1724
1725    #[test]
1726    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1727    fn signed_div_rem_success() {
1728        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1729        let mut vm = vm_with_range_check!();
1730        //Initialize fp
1731        vm.run_context.fp = 6;
1732        //Insert ids into memory
1733        vm.segments = segments![((1, 3), 5), ((1, 4), 10), ((1, 5), 29)];
1734        //Create ids
1735        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1736        //Execute the hint
1737        assert!(run_hint!(vm, ids_data, hint_code).is_ok());
1738        check_memory![vm.segments.memory, ((1, 0), 0), ((1, 1), 31)];
1739    }
1740
1741    #[test]
1742    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1743    fn signed_div_rem_negative_quotient() {
1744        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1745        let mut vm = vm_with_range_check!();
1746        //Initialize fp
1747        vm.run_context.fp = 6;
1748        //Insert ids into memory
1749        vm.segments = segments![((1, 3), 7), ((1, 4), (-10)), ((1, 5), 29)];
1750        //Create ids
1751        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1752        //Execute the hint
1753        assert!(run_hint!(vm, ids_data, hint_code).is_ok());
1754        check_memory![vm.segments.memory, ((1, 0), 4), ((1, 1), 27)];
1755    }
1756
1757    #[test]
1758    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1759    fn signed_div_rem_out_of_range() {
1760        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1761        let mut vm = vm_with_range_check!();
1762        //Initialize fp
1763        vm.run_context.fp = 6;
1764        //Insert ids into memory
1765        vm.segments = segments![((1, 3), (-5)), ((1, 4), 10), ((1, 5), 29)];
1766        //Create ids
1767        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1768        //Execute the hint
1769        assert_matches!(
1770            run_hint!(vm, ids_data, hint_code),
1771            Err(HintError::OutOfValidRange(bx))
1772            if *bx == (Felt252::from(-5), felt_str!("340282366920938463463374607431768211456"))
1773        )
1774    }
1775
1776    #[test]
1777    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1778    fn signed_div_rem_out_of_range_bound() {
1779        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1780        let mut vm = vm_with_range_check!();
1781        //Initialize fp
1782        vm.run_context.fp = 6;
1783        //Insert ids into memory
1784        let bound = vm.get_range_check_builtin().unwrap().bound();
1785        vm.segments = segments![((1, 3), (5)), ((1, 4), 10)];
1786        vm.insert_value((1, 5).into(), bound).unwrap();
1787        //Create ids
1788        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1789        //Execute the hint
1790        let builtin_bound = felt_str!("340282366920938463463374607431768211456");
1791        assert_matches!(
1792            run_hint!(vm, ids_data, hint_code),
1793            Err(HintError::OutOfValidRange(bx))
1794            if *bx == (*bound, builtin_bound.field_div(&Felt252::TWO.try_into().unwrap()))
1795        )
1796    }
1797
1798    #[test]
1799    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1800    fn signed_div_rem_no_range_check_builtin() {
1801        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1802        let mut vm = vm!();
1803        //Initialize fp
1804        vm.run_context.fp = 6;
1805        //Insert ids into memory
1806        vm.segments = segments![((1, 3), 5), ((1, 4), 10), ((1, 5), 29)];
1807        //Create ids
1808        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1809        assert_matches!(
1810            run_hint!(vm, ids_data, hint_code),
1811            Err(HintError::Internal(
1812                VirtualMachineError::NoRangeCheckBuiltin
1813            ))
1814        );
1815    }
1816
1817    #[test]
1818    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1819    fn signed_div_rem_inconsitent_memory() {
1820        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1821        let mut vm = vm_with_range_check!();
1822        //Initialize fp
1823        vm.run_context.fp = 6;
1824        //Insert ids into memory
1825        vm.segments = segments![((1, 1), 10), ((1, 3), 5), ((1, 4), 10), ((1, 5), 29)];
1826        //Create ids
1827        let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
1828        //Execute the hint
1829        assert_matches!(
1830            run_hint!(vm, ids_data, hint_code),
1831            Err(HintError::Memory(
1832                MemoryError::InconsistentMemory(bx)
1833            )) if *bx == (Relocatable::from((1, 1)),
1834                    MaybeRelocatable::Int(Felt252::from(10)),
1835                    MaybeRelocatable::Int(Felt252::from(31)))
1836        );
1837    }
1838
1839    #[test]
1840    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1841    fn signed_div_rem_incorrect_ids() {
1842        let hint_code = "from starkware.cairo.common.math_utils import as_int, assert_integer\n\nassert_integer(ids.div)\nassert 0 < ids.div <= PRIME // range_check_builtin.bound, \\\n    f'div={hex(ids.div)} is out of the valid range.'\n\nassert_integer(ids.bound)\nassert ids.bound <= range_check_builtin.bound // 2, \\\n    f'bound={hex(ids.bound)} is out of the valid range.'\n\nint_value = as_int(ids.value, PRIME)\nq, ids.r = divmod(int_value, ids.div)\n\nassert -ids.bound <= q < ids.bound, \\\n    f'{int_value} / {ids.div} = {q} is out of the range [{-ids.bound}, {ids.bound}).'\n\nids.biased_q = q + ids.bound";
1843        let mut vm = vm_with_range_check!();
1844        //Initialize fp
1845        vm.run_context.fp = 6;
1846        //Insert ids into memory
1847        vm.segments = segments![((1, 3), 5), ((1, 4), 10), ((1, 5), 29)];
1848        //Create ids
1849        let ids_data = ids_data!["r", "b", "r", "d", "v", "b"];
1850        //Execute the hint
1851        assert_matches!(
1852            run_hint!(vm, ids_data, hint_code),
1853            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "div"
1854        )
1855    }
1856
1857    #[test]
1858    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1859    fn run_assert_250_bit_valid() {
1860        let hint_code = hint_code::ASSERT_250_BITS;
1861        let constants = HashMap::from([
1862            ("UPPER_BOUND".to_string(), Felt252::from(15)),
1863            ("SHIFT".to_string(), Felt252::from(5)),
1864        ]);
1865        let mut vm = vm!();
1866        //Initialize fp
1867        vm.run_context.fp = 3;
1868        //Insert ids into memory
1869        vm.segments = segments![((1, 0), 1)];
1870        //Create ids
1871        let ids_data = ids_data!["value", "high", "low"];
1872        //Execute the hint
1873        assert_matches!(
1874            run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), &constants),
1875            Ok(())
1876        );
1877        //Hint would return an error if the assertion fails
1878        //Check ids.high and ids.low values
1879        check_memory![vm.segments.memory, ((1, 1), 0), ((1, 2), 1)];
1880    }
1881
1882    #[test]
1883    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1884    fn run_assert_250_bit_invalid() {
1885        let hint_code = hint_code::ASSERT_250_BITS;
1886        let constants = HashMap::from([
1887            ("UPPER_BOUND".to_string(), Felt252::from(15)),
1888            ("SHIFT".to_string(), Felt252::from(5)),
1889        ]);
1890        let mut vm = vm!();
1891        //Initialize fp
1892        vm.run_context.fp = 3;
1893        //Insert ids into memory
1894        //ids.value
1895        vm.segments = segments![(
1896            (1, 0),
1897            (
1898                "3618502788666131106986593281521497120414687020801267626233049500247285301248",
1899                10
1900            )
1901        )];
1902        //Create ids
1903        let ids_data = ids_data!["value", "high", "low"];
1904        //Execute the hint
1905        assert_matches!(
1906            run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), &constants),
1907            Err(HintError::ValueOutside250BitRange(bx)) if *bx == pow2_const(251)
1908        );
1909    }
1910
1911    #[test]
1912    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1913    fn run_is_250_bits_valid() {
1914        let hint_code = "ids.is_250 = 1 if ids.addr < 2**250 else 0";
1915        let mut vm = vm!();
1916        //Initialize fp
1917        vm.run_context.fp = 2;
1918        //Insert ids into memory
1919        vm.segments = segments![((1, 0), 1152251)];
1920        //Create ids
1921        let ids_data = ids_data!["addr", "is_250"];
1922        //Execute the hint
1923        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1924        //Check ids.is_low
1925        check_memory![vm.segments.memory, ((1, 1), 1)];
1926    }
1927
1928    #[test]
1929    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1930    fn run_is_250_bits_invalid() {
1931        let hint_code = "ids.is_250 = 1 if ids.addr < 2**250 else 0";
1932        let mut vm = vm!();
1933        //Initialize fp
1934        vm.run_context.fp = 2;
1935        //Insert ids into memory
1936        //ids.value
1937        vm.segments = segments![(
1938            (1, 0),
1939            (
1940                "3618502788666131106986593281521497120414687020801267626233049500247285301248",
1941                10
1942            )
1943        )];
1944        //Create ids
1945        let ids_data = ids_data!["addr", "is_250"];
1946        //Execute the hint
1947        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
1948        //Check ids.is_low
1949        check_memory![vm.segments.memory, ((1, 1), 0)];
1950    }
1951
1952    #[test]
1953    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1954    fn run_is_addr_bounded_ok() {
1955        let hint_code = hint_code::IS_ADDR_BOUNDED;
1956        let mut vm = vm!();
1957        let addr_bound = felt_str!(
1958            "3618502788666131106986593281521497120414687020801267626233049500247285301000"
1959        );
1960        //Initialize fp
1961        vm.run_context.fp = 2;
1962        //Insert ids into memory
1963        vm.segments = segments![(
1964            (1, 0),
1965            (
1966                "1809251394333067160431340899751024102169435851563236335319518532916477952000",
1967                10
1968            )
1969        ),];
1970        //Create ids
1971        let ids_data = ids_data!["addr", "is_small"];
1972        //Execute the hint
1973        assert_matches!(
1974            run_hint!(
1975                vm,
1976                ids_data,
1977                hint_code,
1978                exec_scopes_ref!(),
1979                &[(ADDR_BOUND, addr_bound)]
1980                    .into_iter()
1981                    .map(|(k, v)| (k.to_string(), v))
1982                    .collect()
1983            ),
1984            Ok(())
1985        );
1986        //Check ids.is_low
1987        check_memory![vm.segments.memory, ((1, 1), 1)];
1988    }
1989
1990    #[test]
1991    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1992    fn run_is_addr_bounded_assert_fail() {
1993        let hint_code = hint_code::IS_ADDR_BOUNDED;
1994        let mut vm = vm!();
1995        let addr_bound = Felt252::ONE;
1996        //Initialize fp
1997        vm.run_context.fp = 2;
1998        //Insert ids into memory
1999        vm.segments = segments![(
2000            (1, 0),
2001            (
2002                "3618502788666131106986593281521497120414687020801267626233049500247285301000",
2003                10
2004            )
2005        ),];
2006        //Create ids
2007        let ids_data = ids_data!["addr", "is_small"];
2008        //Execute the hint
2009        assert_matches!(
2010            run_hint!(
2011                vm,
2012                ids_data,
2013                hint_code,
2014                exec_scopes_ref!(),
2015                &HashMap::from([(ADDR_BOUND.to_string(), addr_bound)])
2016            ),
2017            Err(HintError::AssertionFailed(bx))
2018                if bx.as_ref() == "normalize_address() cannot be used with the current constants."
2019        );
2020    }
2021
2022    #[test]
2023    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2024    fn run_is_addr_bounded_missing_const() {
2025        let hint_code = hint_code::IS_ADDR_BOUNDED;
2026        let mut vm = vm!();
2027        //Initialize fp
2028        vm.run_context.fp = 2;
2029        //Insert ids into memory
2030        vm.segments = segments![((1, 0), 0),];
2031        //Create ids
2032        let ids_data = ids_data!["addr", "is_small"];
2033        //Execute the hint
2034        assert_matches!(
2035            run_hint!(vm, ids_data, hint_code),
2036            Err(HintError::MissingConstant(bx)) if *bx == ADDR_BOUND
2037        );
2038    }
2039
2040    #[test]
2041    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2042    fn run_split_felt_ok() {
2043        let hint_code =
2044        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2045        let mut vm = vm_with_range_check!();
2046        vm.segments = segments![
2047            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2048            ((1, 4), (2, 0))
2049        ];
2050        add_segments!(vm, 1);
2051        //Initialize fp
2052        vm.run_context.fp = 7;
2053        //Create ids
2054        let ids_data = HashMap::from([
2055            ("value".to_string(), HintReference::new_simple(-4)),
2056            (
2057                "low".to_string(),
2058                HintReference::new(-3, 0, true, true, true),
2059            ),
2060            (
2061                "high".to_string(),
2062                HintReference::new(-3, 1, true, true, true),
2063            ),
2064        ]);
2065        //Execute the hint
2066        assert_matches!(
2067            run_hint!(
2068                vm,
2069                ids_data,
2070                hint_code,
2071                exec_scopes_ref!(),
2072                &HashMap::from([
2073                    ("MAX_LOW".to_string(), Felt252::ZERO),
2074                    (
2075                        "MAX_HIGH".to_string(),
2076                        felt_str!("10633823966279327296825105735305134080")
2077                    )
2078                ])
2079            ),
2080            Ok(())
2081        );
2082        //Check hint memory inserts
2083        check_memory![
2084            vm.segments.memory,
2085            ((2, 0), ("335438970432432812899076431678123043273", 10)),
2086            ((2, 1), 0)
2087        ];
2088    }
2089
2090    #[test]
2091    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2092    fn run_split_felt_incorrect_ids() {
2093        let hint_code =
2094        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2095        let mut vm = vm_with_range_check!();
2096        vm.segments = segments![
2097            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2098            ((1, 4), (2, 0))
2099        ];
2100        //Initialize fp
2101        vm.run_context.fp = 7;
2102        //Create incomplete ids
2103        //Create ids_data & hint_data
2104        let ids_data = ids_data!["low"];
2105        //Execute the hint
2106        assert_matches!(
2107            run_hint!(
2108                vm,
2109                ids_data,
2110                hint_code,
2111                exec_scopes_ref!(),
2112                &HashMap::from([
2113                    ("MAX_LOW".to_string(), Felt252::ZERO),
2114                    (
2115                        "MAX_HIGH".to_string(),
2116                        felt_str!("10633823966279327296825105735305134080")
2117                    )
2118                ])
2119            ),
2120            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "value"
2121        );
2122    }
2123
2124    #[test]
2125    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2126    fn run_split_felt_fails_first_insert() {
2127        let hint_code =
2128        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2129        let mut vm = vm_with_range_check!();
2130        vm.segments = segments![
2131            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2132            ((1, 4), (2, 0)),
2133            ((2, 0), 99)
2134        ];
2135        //Initialize fp
2136        vm.run_context.fp = 7;
2137        //Create ids_data & hint_data
2138        let ids_data = HashMap::from([
2139            ("value".to_string(), HintReference::new_simple(-4)),
2140            (
2141                "low".to_string(),
2142                HintReference::new(-3, 0, true, true, true),
2143            ),
2144            (
2145                "high".to_string(),
2146                HintReference::new(-3, 1, true, true, true),
2147            ),
2148        ]);
2149
2150        //Execute the hint
2151        assert_matches!(
2152            run_hint!(
2153                vm,
2154                ids_data,
2155                hint_code,
2156                exec_scopes_ref!(),
2157                &HashMap::from([
2158                    ("MAX_LOW".to_string(), Felt252::ZERO),
2159                    (
2160                        "MAX_HIGH".to_string(),
2161                        felt_str!("10633823966279327296825105735305134080")
2162                    )
2163                ])
2164            ),
2165            Err(HintError::Memory(
2166                MemoryError::InconsistentMemory(bx)
2167            )) if *bx == (Relocatable::from((2, 0)),
2168                    MaybeRelocatable::from(Felt252::from(99)),
2169                    MaybeRelocatable::from(felt_str!("335438970432432812899076431678123043273")))
2170        );
2171    }
2172
2173    #[test]
2174    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2175    fn run_split_felt_fails_second_insert() {
2176        let hint_code =
2177        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2178        let mut vm = vm_with_range_check!();
2179        vm.segments = segments![
2180            ((1, 4), (2, 0)),
2181            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2182            ((2, 1), 99)
2183        ];
2184        add_segments!(vm, 1);
2185        //Initialize fp
2186        vm.run_context.fp = 7;
2187        //Create ids_data & hint_data
2188        let ids_data = HashMap::from([
2189            ("value".to_string(), HintReference::new_simple(-4)),
2190            (
2191                "low".to_string(),
2192                HintReference::new(-3, 0, true, true, true),
2193            ),
2194            (
2195                "high".to_string(),
2196                HintReference::new(-3, 1, true, true, true),
2197            ),
2198        ]);
2199        //Execute the hint
2200        assert_matches!(
2201            run_hint!(
2202                vm,
2203                ids_data,
2204                hint_code,
2205                exec_scopes_ref!(),
2206                &HashMap::from([
2207                    ("MAX_LOW".to_string(), Felt252::ZERO),
2208                    (
2209                        "MAX_HIGH".to_string(),
2210                        felt_str!("10633823966279327296825105735305134080")
2211                    )
2212                ])
2213            ),
2214            Err(HintError::Memory(
2215                MemoryError::InconsistentMemory(bx)
2216            )) if *bx == (Relocatable::from((2, 1)),
2217                    MaybeRelocatable::from(Felt252::from(99)),
2218                    MaybeRelocatable::from(Felt252::from(0)))
2219        );
2220    }
2221
2222    #[test]
2223    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2224    fn run_split_felt_value_is_not_integer() {
2225        let hint_code =
2226        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2227        let mut vm = vm_with_range_check!();
2228        vm.segments = segments![((1, 3), (1, 0)), ((1, 4), (2, 0))];
2229        //Initialize fp
2230        vm.run_context.fp = 7;
2231        //Create ids_data & hint_data
2232        let ids_data = HashMap::from([
2233            ("value".to_string(), HintReference::new_simple(-4)),
2234            (
2235                "low".to_string(),
2236                HintReference::new(-3, 0, true, true, true),
2237            ),
2238            (
2239                "high".to_string(),
2240                HintReference::new(-3, 1, true, true, true),
2241            ),
2242        ]);
2243        //Execute the hint
2244        assert_matches!(
2245            run_hint!(
2246                vm,
2247                ids_data,
2248                hint_code,
2249                exec_scopes_ref!(),
2250                &HashMap::from([
2251                    ("MAX_LOW".to_string(), Felt252::ZERO),
2252                    (
2253                        "MAX_HIGH".to_string(),
2254                        felt_str!("10633823966279327296825105735305134080")
2255                    )
2256                ])
2257            ),
2258            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "value"
2259        );
2260    }
2261
2262    #[test]
2263    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2264    fn run_split_felt_no_constants() {
2265        let hint_code =
2266        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2267        let mut vm = vm_with_range_check!();
2268        vm.segments = segments![
2269            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2270            ((1, 4), (2, 0))
2271        ];
2272        add_segments!(vm, 1);
2273        //Initialize fp
2274        vm.run_context.fp = 7;
2275        //Create ids
2276        let ids_data = HashMap::from([
2277            ("value".to_string(), HintReference::new_simple(-4)),
2278            (
2279                "low".to_string(),
2280                HintReference::new(-3, 0, true, true, true),
2281            ),
2282            (
2283                "high".to_string(),
2284                HintReference::new(-3, 1, true, true, true),
2285            ),
2286        ]);
2287        //Execute the hint
2288        assert_matches!(
2289            run_hint!(vm, ids_data, hint_code),
2290            Err(HintError::MissingConstant(x)) if (*x) == "MAX_HIGH"
2291        );
2292    }
2293
2294    #[test]
2295    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2296    fn run_split_felt_constants_over_128_bits() {
2297        let hint_code =
2298        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2299        let mut vm = vm_with_range_check!();
2300        vm.segments = segments![
2301            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2302            ((1, 4), (2, 0))
2303        ];
2304        add_segments!(vm, 1);
2305        //Initialize fp
2306        vm.run_context.fp = 7;
2307        //Create ids
2308        let ids_data = HashMap::from([
2309            ("value".to_string(), HintReference::new_simple(-4)),
2310            (
2311                "low".to_string(),
2312                HintReference::new(-3, 0, true, true, true),
2313            ),
2314            (
2315                "high".to_string(),
2316                HintReference::new(-3, 1, true, true, true),
2317            ),
2318        ]);
2319        //Execute the hint
2320        assert_matches!(
2321            run_hint!(
2322                vm,
2323                ids_data,
2324                hint_code,
2325                exec_scopes_ref!(),
2326                &HashMap::from([
2327                    ("MAX_LOW".to_string(), Felt252::from(-1)),
2328                    (
2329                        "MAX_HIGH".to_string(),
2330                        Felt252::from(-1),
2331                    )
2332                ])
2333            ),
2334            Err(HintError::AssertionFailed(x)) if &(*x) == "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128"
2335        );
2336    }
2337
2338    #[test]
2339    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2340    fn run_split_felt_wrong_constants() {
2341        let hint_code =
2342        "from starkware.cairo.common.math_utils import assert_integer\nassert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128\nassert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW\nassert_integer(ids.value)\nids.low = ids.value & ((1 << 128) - 1)\nids.high = ids.value >> 128";
2343        let mut vm = vm_with_range_check!();
2344        vm.segments = segments![
2345            ((1, 3), ("335438970432432812899076431678123043273", 10)),
2346            ((1, 4), (2, 0))
2347        ];
2348        add_segments!(vm, 1);
2349        //Initialize fp
2350        vm.run_context.fp = 7;
2351        //Create ids
2352        let ids_data = HashMap::from([
2353            ("value".to_string(), HintReference::new_simple(-4)),
2354            (
2355                "low".to_string(),
2356                HintReference::new(-3, 0, true, true, true),
2357            ),
2358            (
2359                "high".to_string(),
2360                HintReference::new(-3, 1, true, true, true),
2361            ),
2362        ]);
2363        //Execute the hint
2364        assert_matches!(
2365            run_hint!(
2366                vm,
2367                ids_data,
2368                hint_code,
2369                exec_scopes_ref!(),
2370                &HashMap::from([
2371                    ("MAX_LOW".to_string(), Felt252::ZERO),
2372                    (
2373                        "MAX_HIGH".to_string(),
2374                        Felt252::ZERO,
2375                    )
2376                ])
2377            ),
2378            Err(HintError::AssertionFailed(x)) if &(*x) == "assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW"
2379        );
2380    }
2381
2382    #[test]
2383    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2384    fn run_assert_lt_felt_ok() {
2385        let hint_code =
2386        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2387        let mut vm = vm_with_range_check!();
2388        //Initialize fp
2389        vm.run_context.fp = 3;
2390        //Insert ids into memory
2391        vm.segments = segments![((1, 1), 1), ((1, 2), 2)];
2392        //Create ids
2393        let ids_data = ids_data!["a", "b"];
2394        //Execute the hint
2395        assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
2396    }
2397
2398    #[test]
2399    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2400    fn run_assert_lt_felt_assert_fails() {
2401        let hint_code =
2402        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2403        let mut vm = vm_with_range_check!();
2404        //Initialize fp
2405        vm.run_context.fp = 3;
2406        vm.segments = segments![((1, 1), 3), ((1, 2), 2)];
2407        let ids_data = ids_data!["a", "b"];
2408        //Execute the hint
2409        assert_matches!(
2410            run_hint!(vm, ids_data, hint_code),
2411            Err(HintError::AssertLtFelt252(bx)) if *bx == (Felt252::from(3), Felt252::from(2))
2412        );
2413    }
2414
2415    #[test]
2416    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2417    fn run_assert_lt_felt_incorrect_ids() {
2418        let hint_code =
2419        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2420        let mut vm = vm_with_range_check!();
2421        //Initialize fp
2422        vm.run_context.fp = 3;
2423        vm.segments = segments![((1, 1), 1), ((1, 2), 2)];
2424        //Create Incorrects ids
2425        let ids_data = ids_data!["a"];
2426        //Execute the hint
2427        assert_matches!(
2428            run_hint!(vm, ids_data, hint_code),
2429            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "b"
2430        );
2431    }
2432
2433    #[test]
2434    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2435    fn run_assert_lt_felt_a_is_not_integer() {
2436        let hint_code =
2437        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2438        let mut vm = vm_with_range_check!();
2439        //Initialize fp
2440        vm.run_context.fp = 3;
2441        vm.segments = segments![((1, 1), (1, 0)), ((1, 2), 2)];
2442        let ids_data = ids_data!["a", "b"];
2443        //Execute the hint
2444        assert_matches!(
2445            run_hint!(vm, ids_data, hint_code),
2446            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "a"
2447        );
2448    }
2449
2450    #[test]
2451    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2452    fn run_assert_lt_felt_b_is_not_integer() {
2453        let hint_code =
2454        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2455        let mut vm = vm_with_range_check!();
2456        //Initialize fp
2457        vm.run_context.fp = 3;
2458        vm.segments = segments![((1, 1), 1), ((1, 2), (1, 0))];
2459        let ids_data = ids_data!["a", "b"];
2460        //Execute the hint
2461        assert_matches!(
2462            run_hint!(vm, ids_data, hint_code),
2463            Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "b"
2464        );
2465    }
2466
2467    #[test]
2468    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2469    fn run_assert_lt_felt_ok_failed_to_get_ids() {
2470        let hint_code =
2471        "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) < (ids.b % PRIME), \\\n    f'a = {ids.a % PRIME} is not less than b = {ids.b % PRIME}.'";
2472        let mut vm = vm_with_range_check!();
2473        //Initialize fp
2474        vm.run_context.fp = 3;
2475        //Insert ids.a into memory
2476        vm.segments = segments![((1, 1), 1)];
2477        let ids_data = ids_data!["a", "b"];
2478        //Execute the hint
2479        assert_matches!(
2480            run_hint!(vm, ids_data, hint_code),
2481            Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "b"
2482        );
2483    }
2484
2485    #[test]
2486    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2487    fn run_is_assert_le_felt_v_0_6_assertion_fail() {
2488        let mut vm = vm_with_range_check!();
2489        vm.set_fp(2);
2490        vm.segments = segments![((1, 0), 17), ((1, 1), 7)];
2491        //Initialize ap
2492        //Create ids_data & hint_data
2493        let ids_data = ids_data!["a", "b"];
2494        //Execute the hint
2495        assert_matches!(
2496            run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT_V_0_6),
2497            Err(HintError::NonLeFelt252(bx)) if *bx == (17_u32.into(), 7_u32.into())
2498        );
2499    }
2500
2501    #[test]
2502    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2503    fn run_is_assert_le_felt_v_0_8_assertion_fail() {
2504        let mut vm = vm_with_range_check!();
2505        vm.set_fp(2);
2506        vm.segments = segments![((1, 0), 17), ((1, 1), 7)];
2507        //Initialize ap
2508        //Create ids_data & hint_data
2509        let ids_data = ids_data!["a", "b"];
2510        //Execute the hint
2511        assert_matches!(
2512            run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT_V_0_8),
2513            Err(HintError::NonLeFelt252(bx)) if *bx == (17_u32.into(), 7_u32.into())
2514        );
2515    }
2516
2517    #[cfg(not(target_arch = "wasm32"))]
2518    proptest! {
2519        #[test]
2520        // Proptest to check is_quad_residue hint function
2521        fn run_is_quad_residue(ref x in "([1-9][0-9]*)") {
2522            let mut vm = vm!();
2523            vm.run_context.fp = 2;
2524            vm.segments = segments![((1, 1), (&x[..], 10))];
2525            let ids_data = ids_data!["y", "x"];
2526
2527            assert_matches!(run_hint!(vm, ids_data, hint_code::IS_QUAD_RESIDUE), Ok(()));
2528
2529            let x = felt_str!(x);
2530
2531            if x.is_zero() || x == Felt252::ONE {
2532                assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().as_ref(), &x);
2533            } else if x.pow_felt(&Felt252::MAX.field_div(&Felt252::TWO.try_into().unwrap())) == Felt252::ONE {
2534                assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().into_owned(), x.sqrt().unwrap());
2535            } else {
2536                assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().into_owned(), (x.field_div(&(Felt252::from(3).try_into().unwrap())).sqrt().unwrap()));
2537            }
2538        }
2539    }
2540}