diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 6d06e0129..e706de2f4 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -287,6 +287,8 @@ testname: - CallEcrecover_Overflow_d4g0v0_Cancun - CallEcrecover_Overflow_d5g0v0_Cancun - CallRipemd160_5_d0g0v0_Cancun + - modexpRandomInput_d0g0v0_Cancun + - modexpRandomInput_d0g1v0_Cancun stPreCompiledContracts: - idPrecomps_d2g0v0_Cancun - idPrecomps_d7g0v0_Cancun @@ -333,46 +335,6 @@ testname: - precompsEIP2929Cancun_d81g0v0_Cancun - precompsEIP2929Cancun_d92g0v0_Cancun - precompsEIP2929Cancun_d99g0v0_Cancun - - modexp_d11g0v0_Cancun - - modexp_d11g1v0_Cancun - - modexp_d11g2v0_Cancun - - modexp_d11g3v0_Cancun - - modexp_d14g0v0_Cancun - - modexp_d14g1v0_Cancun - - modexp_d14g2v0_Cancun - - modexp_d14g3v0_Cancun - - modexp_d16g0v0_Cancun - - modexp_d16g1v0_Cancun - - modexp_d16g2v0_Cancun - - modexp_d16g3v0_Cancun - - modexp_d17g0v0_Cancun - - modexp_d17g1v0_Cancun - - modexp_d17g2v0_Cancun - - modexp_d17g3v0_Cancun - - modexp_d25g0v0_Cancun - - modexp_d25g1v0_Cancun - - modexp_d25g2v0_Cancun - - modexp_d25g3v0_Cancun - - modexp_d26g0v0_Cancun - - modexp_d26g1v0_Cancun - - modexp_d26g2v0_Cancun - - modexp_d26g3v0_Cancun - - modexp_d27g0v0_Cancun - - modexp_d27g1v0_Cancun - - modexp_d27g2v0_Cancun - - modexp_d27g3v0_Cancun - - modexp_d29g0v0_Cancun - - modexp_d29g1v0_Cancun - - modexp_d29g2v0_Cancun - - modexp_d29g3v0_Cancun - - modexp_d30g0v0_Cancun - - modexp_d30g1v0_Cancun - - modexp_d30g2v0_Cancun - - modexp_d30g3v0_Cancun - - modexp_d33g0v0_Cancun - - modexp_d33g1v0_Cancun - - modexp_d33g2v0_Cancun - - modexp_d33g3v0_Cancun - precompsEIP2929Cancun_d10g0v0_Cancun - precompsEIP2929Cancun_d115g0v0_Cancun - precompsEIP2929Cancun_d133g0v0_Cancun @@ -385,6 +347,18 @@ testname: - precompsEIP2929Cancun_d313g0v0_Cancun - precompsEIP2929Cancun_d79g0v0_Cancun - precompsEIP2929Cancun_d97g0v0_Cancun + - modexp_d27g0v0_Cancun + - modexp_d27g1v0_Cancun + - modexp_d27g2v0_Cancun + - modexp_d27g3v0_Cancun + - modexp_d29g0v0_Cancun + - modexp_d29g1v0_Cancun + - modexp_d29g2v0_Cancun + - modexp_d29g3v0_Cancun + - modexp_d30g0v0_Cancun + - modexp_d30g1v0_Cancun + - modexp_d30g2v0_Cancun + - modexp_d30g3v0_Cancun stQuadraticComplexityTest: - Call20KbytesContract50_1_d0g0v0_Cancun - Call20KbytesContract50_2_d0g0v0_Cancun @@ -422,6 +396,7 @@ testname: - randomStatetest645_d0g0v0_Cancun - randomStatetest645_d0g0v1_Cancun - randomStatetest476_d0g0v0_Cancun + - randomStatetest650_d0g0v0_Cancun stRandom: - randomStatetest111_d0g0v0_Cancun - randomStatetest14_d0g0v0_Cancun @@ -476,6 +451,10 @@ testname: - revertRetDataSize_d7g0v0_Cancun - revertRetDataSize_d8g0v0_Cancun - revertRetDataSize_d9g0v0_Cancun + # Next three tests are skipped because the input size is > 48 bits + - modexp_modsize0_returndatasize_d2g0v0_Cancun + - modexp_modsize0_returndatasize_d3g0v0_Cancun + - modexp_modsize0_returndatasize_d4g0v0_Cancun stRevertTest: - LoopCallsDepthThenRevert2_d0g0v0_Cancun - LoopCallsDepthThenRevert3_d0g0v0_Cancun diff --git a/cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo index d2b35b73e..e6455433b 100644 --- a/cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo @@ -1,26 +1,25 @@ +use core::circuit::CircuitElement as CE; +use core::circuit::CircuitInput as CI; +use core::circuit::{ + u384, circuit_add, circuit_sub, circuit_mul, EvalCircuitTrait, CircuitOutputsTrait, + CircuitModulus, CircuitInputs, AddInputResultTrait +}; use core::cmp::{min, max}; - use core::num::traits::Bounded; -use core::num::traits::OverflowingAdd; -// CREDITS: The implementation has take reference from -// [revm](https://github.com/bluealloy/revm/blob/main/crates/precompile/src/modexp.rs) - -use core::option::OptionTrait; +use core::num::traits::Zero; use core::starknet::EthAddress; -use core::traits::TryInto; use crate::errors::EVMError; - use crate::precompiles::Precompile; -use utils::crypto::modexp::lib::modexp; -use utils::traits::bytes::{U8SpanExTrait, FromBytes}; + +use utils::traits::bytes::{U8SpanExTrait, FromBytes, ToBytes}; use utils::traits::integer::BitsUsed; +const MAX_INPUT_BYTE_SIZE: usize = 48; // Supports input up to 384 bits const HEADER_LENGTH: usize = 96; const MIN_GAS: u64 = 200; pub impl ModExp of Precompile { - #[inline(always)] fn address() -> EthAddress { 0x5.try_into().unwrap() } @@ -57,69 +56,205 @@ pub impl ModExp of Precompile { } }; + // We only support inputs up to 48 bytes. We can early return with an empty span if any size + // is larger than that. + if base_len > MAX_INPUT_BYTE_SIZE + || exp_len > MAX_INPUT_BYTE_SIZE + || mod_len > MAX_INPUT_BYTE_SIZE { + return Result::Err(EVMError::InvalidParameter('input greater than 48 bytes')); + } + // Handle a special case when both the base and mod length is zero if base_len == 0 && mod_len == 0 { return Result::Ok((MIN_GAS, [].span())); } // Used to extract ADJUSTED_EXPONENT_LENGTH. - let exp_highp_len = min(exp_len, 32); + let exp_start = HEADER_LENGTH + base_len; + let exp_head = input + .slice_right_padded(exp_start, min(32, exp_len)) + .from_be_bytes_partial() + .expect('exp_head parsing failed'); + + let gas = calc_gas(base_len.into(), exp_len.into(), mod_len.into(), exp_head); - let input = if input.len() >= HEADER_LENGTH { - input.slice(HEADER_LENGTH, input.len() - HEADER_LENGTH) + // OPERATION + + // Padding is needed if the input does not contain all 3 values. + let mod_start_idx = exp_start + exp_len; + let base = input + .slice_right_padded(HEADER_LENGTH, base_len) + .pad_left_with_zeroes(MAX_INPUT_BYTE_SIZE); + let exponent = input + .slice_right_padded(exp_start, exp_len) + .pad_left_with_zeroes(MAX_INPUT_BYTE_SIZE); + let modulus = input + .slice_right_padded(mod_start_idx, mod_len) + .pad_left_with_zeroes(MAX_INPUT_BYTE_SIZE); + + // inputs are guaranteed to be 48 bytes by the previous checks. safe unwraps. + let base: u384 = base.from_be_bytes().unwrap(); + let exponent: u384 = exponent.from_be_bytes().unwrap(); + let modulus: u384 = modulus.from_be_bytes().unwrap(); + + let output = modexp_circuit(base, exponent, modulus); + let limb0_128: u128 = Into::<_, felt252>::into(output.limb0).try_into().unwrap(); + let limb1_128: u128 = Into::<_, felt252>::into(output.limb1).try_into().unwrap(); + let limb2_128: u128 = Into::<_, felt252>::into(output.limb2).try_into().unwrap(); + let limb3_128: u128 = Into::<_, felt252>::into(output.limb3).try_into().unwrap(); + + let mut result_bytes = array![]; + if mod_len > 12 * 3 { + result_bytes + .append_span(limb3_128.to_be_bytes().pad_left_with_zeroes(mod_len - 12 * 3)); + result_bytes.append_span(limb2_128.to_be_bytes().pad_left_with_zeroes(12)); + result_bytes.append_span(limb1_128.to_be_bytes().pad_left_with_zeroes(12)); + result_bytes.append_span(limb0_128.to_be_bytes().pad_left_with_zeroes(12)); + } else if mod_len > 12 * 2 { + result_bytes + .append_span(limb2_128.to_be_bytes().pad_left_with_zeroes(mod_len - 12 * 2)); + result_bytes.append_span(limb1_128.to_be_bytes().pad_left_with_zeroes(12)); + result_bytes.append_span(limb0_128.to_be_bytes().pad_left_with_zeroes(12)); + } else if mod_len > 12 * 1 { + result_bytes + .append_span(limb1_128.to_be_bytes().pad_left_with_zeroes(mod_len - 12 * 1)); + result_bytes.append_span(limb0_128.to_be_bytes().pad_left_with_zeroes(12)); } else { - [].span() - }; + result_bytes.append_span(limb0_128.to_be_bytes().pad_left_with_zeroes(mod_len)); + } - let exp_highp = { - // get right padded bytes so if data.len is less then exp_len we will get right padded - // zeroes. - let right_padded_highp = input.slice_right_padded(base_len, 32); - // If exp_len is less then 32 bytes get only exp_len bytes and do left padding. - let out = right_padded_highp.slice(0, exp_highp_len).pad_left_with_zeroes(32); - match out.from_be_bytes() { - Option::Some(result) => result, - Option::None => { - return Result::Err(EVMError::InvalidParameter('failed to extract exp_highp')); - } - } - }; + Result::Ok((gas.into(), result_bytes.span())) + } +} - let gas = calc_gas(base_len.into(), exp_len.into(), mod_len.into(), exp_highp); - // Padding is needed if the input does not contain all 3 values. - let base = input.slice_right_padded(0, base_len); - let exponent = input.slice_right_padded(base_len, exp_len); +fn mod_exp_loop_inner(n: u384, bit: u384, base: u384, res: u384) -> (u384, u384) { + let (_one, _base, _bit, _res) = ( + CE::> {}, CE::> {}, CE::> {}, CE::> {} + ); + + // Circuit + // base_if_bit_else_one = (1 - bit)*(one) + bit*base + // new_res = res * base_if_bit_else_one + // new_base = base * base + let base_if_bit_else_one = circuit_add( + circuit_mul(circuit_sub(_one, _bit), _one), circuit_mul(_bit, _base) + ); + let new_res = circuit_mul(base_if_bit_else_one, _res); + let new_base = circuit_mul(_base, _base); + + let modulus = TryInto::<_, CircuitModulus>::try_into([n.limb0, n.limb1, n.limb2, n.limb3]) + .unwrap(); + + let mut circuit_inputs = (new_res, new_base,).new_inputs(); + // Fill inputs: + circuit_inputs = circuit_inputs.next([1, 0, 0, 0]); + circuit_inputs = circuit_inputs.next(base); + circuit_inputs = circuit_inputs.next(bit); + circuit_inputs = circuit_inputs.next(res); + + let outputs = circuit_inputs.done().eval(modulus).unwrap(); + (outputs.get_output(new_res), outputs.get_output(new_base)) +} - let (mod_start_idx, _) = base_len.overflowing_add(exp_len); +/// Computes the modular exponentiation x^y mod n up to 384 bits. +/// The algorithm uses the binary expansion of the exponent from right to left, +/// and use iterated squaring-and-multiply implemented using a circuit. +/// Resource: +/// +/// # Arguments +/// +/// * `x` a `u384` value representing the base. +/// * `y` a `u384` value representing the exponent. +/// * `n` a `u384` value representing the modulus. +/// +/// # Returns +/// +/// * `u384` - The result of the modular exponentiation x^y mod n. +pub fn modexp_circuit(x: u384, y: u384, n: u384) -> u384 { + if n.is_zero() || n == 1.into() { + return 0.into(); + } + if y.is_zero() { + return 1.into(); + } + if x.is_zero() { + return 0.into(); + } - let modulus = input.slice_right_padded(mod_start_idx, mod_len); + let bits = get_u384_bits_little(y); + let mut res = 1.into(); + let mut base = x; + for bit in bits { + let (_res, _base) = mod_exp_loop_inner(n, bit.into(), base, res); + res = _res; + base = _base; + }; - let output = modexp(base, exponent, modulus); + res +} - let return_data = output.pad_left_with_zeroes(mod_len); - Result::Ok((gas.into(), return_data)) + +// Returns the bits of the 384 bit integer in little endian format. +fn get_u384_bits_little(s: u384) -> Array { + let mut bits = array![]; + let mut s_limb0: u128 = Into::<_, felt252>::into(s.limb0).try_into().unwrap(); + while s_limb0 != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_limb0, 2); + bits.append(r.into()); + s_limb0 = q; + }; + let mut s_limb1: u128 = Into::<_, felt252>::into(s.limb1).try_into().unwrap(); + if s_limb1 != 0 { + while bits.len() != 96 { + bits.append(0); + } } + while s_limb1 != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_limb1, 2); + bits.append(r.into()); + s_limb1 = q; + }; + let mut s_limb2: u128 = Into::<_, felt252>::into(s.limb2).try_into().unwrap(); + if s_limb2 != 0 { + while bits.len() != 192 { + bits.append(0); + } + } + while s_limb2 != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_limb2, 2); + bits.append(r.into()); + s_limb2 = q; + }; + let mut s_limb3: u128 = Into::<_, felt252>::into(s.limb3).try_into().unwrap(); + if s_limb3 != 0 { + while bits.len() != 288 { + bits.append(0); + } + } + while s_limb3 != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_limb3, 2); + bits.append(r.into()); + s_limb3 = q; + }; + bits } // Calculate gas cost according to EIP 2565: // https://eips.ethereum.org/EIPS/eip-2565 -fn calc_gas(base_length: u64, exp_length: u64, mod_length: u64, exp_highp: u256) -> u64 { +fn calc_gas(base_length: u64, exp_length: u64, mod_length: u64, exp_head: u256) -> u64 { let multiplication_complexity = calculate_multiplication_complexity(base_length, mod_length); - - let iteration_count = calculate_iteration_count(exp_length, exp_highp); - + let iteration_count = calculate_iteration_count(exp_length, exp_head); let gas = (multiplication_complexity * iteration_count.into()) / 3; let gas: u64 = gas.try_into().unwrap_or(Bounded::::MAX); - max(gas, 200) + max(gas, MIN_GAS) } fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> u256 { let max_length = max(base_length, mod_length); - let _8: NonZero = 8_u64.try_into().unwrap(); - let (words, rem) = DivRem::div_rem(max_length, _8); + let (words, rem) = DivRem::div_rem(max_length, 8); let words: u256 = if rem != 0 { (words + 1).into() @@ -130,17 +265,17 @@ fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> u25 words * words } -fn calculate_iteration_count(exp_length: u64, exp_highp: u256) -> u64 { +fn calculate_iteration_count(exp_length: u64, exp_head: u256) -> u64 { let mut iteration_count: u64 = if exp_length < 33 { - if exp_highp == 0 { + if exp_head == 0 { 0 } else { - (exp_highp.bits_used() - 1).into() + (exp_head.bits_used() - 1).into() } } else { let length_part = 8 * (exp_length - 32); - let bits_part = if exp_highp != 0 { - exp_highp.bits_used() - 1 + let bits_part = if exp_head != 0 { + exp_head.bits_used() - 1 } else { 0 }; @@ -151,152 +286,1007 @@ fn calculate_iteration_count(exp_length: u64, exp_highp: u256) -> u64 { max(iteration_count, 1) } -#[cfg(tests)] +#[cfg(test)] mod tests { + use core::circuit::u384; use core::result::ResultTrait; - use core::starknet::EthAddress; - use core::starknet::testing::set_contract_address; - use crate::instructions::SystemOperationsTrait; - - use crate::memory::MemoryTrait; - use crate::precompiles::Precompiles; - use crate::stack::StackTrait; - use crate::test_utils::{VMBuilderTrait, native_token, other_starknet_address}; - use evm_tests::test_precompiles::test_data::test_data_modexp::{ + use crate::precompiles::modexp::ModExp; + use crate::test_data::test_data_modexp::{ test_modexp_modsize0_returndatasizeFiller_data, test_modexp_create2callPrecompiles_test0_berlin_data, test_modexp_eip198_example_1_data, test_modexp_eip198_example_2_data, test_modexp_nagydani_1_square_data, test_modexp_nagydani_1_qube_data }; - use snforge_std::{start_mock_call, test_address}; - use utils::helpers::U256Trait; + use super::modexp_circuit; + use utils::traits::bytes::{U8SpanExTrait, ToBytes}; + + const TWO_31: u256 = 2147483648; + const PREV_PRIME_384: u384 = + u384 { + limb0: 0xfffffffffffffffffffffec3, + limb1: 0xffffffffffffffffffffffff, + limb2: 0xffffffffffffffffffffffff, + limb3: 0xffffffffffffffffffffffff + }; + const PREV_PRIME_384_MINUS_1: u384 = + u384 { + limb0: 0xfffffffffffffffffffffec2, + limb1: 0xffffffffffffffffffffffff, + limb2: 0xffffffffffffffffffffffff, + limb3: 0xffffffffffffffffffffffff + }; + const PREV_PRIME_384_MINUS_2: u384 = + u384 { + limb0: 0xfffffffffffffffffffffec1, + limb1: 0xffffffffffffffffffffffff, + limb2: 0xffffffffffffffffffffffff, + limb3: 0xffffffffffffffffffffffff + }; - // the tests are taken from - // [revm](https://github.com/bluealloy/revm/blob/0629883f5a40e913a5d9498fa37886348c858c70/crates/precompile/src/modexp.rs#L175) + #[test] + fn test_modexp_circuit() { + let TWO_31_MINUS_1: u384 = 2147483647.into(); + let TWO_31_MINUS_2: u384 = 2147483646.into(); + assert_eq!(modexp_circuit(2.into(), TWO_31_MINUS_2, TWO_31_MINUS_1), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(3.into(), TWO_31_MINUS_2, TWO_31_MINUS_1), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(5.into(), TWO_31_MINUS_2, TWO_31_MINUS_1), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(7.into(), TWO_31_MINUS_2, TWO_31_MINUS_1), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(11.into(), TWO_31_MINUS_2, TWO_31_MINUS_1), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(2.into(), TWO_31_MINUS_2, TWO_31_MINUS_1.into()), 1.into(), "wrong result"); + assert_eq!(modexp_circuit(2.into(), 5.into(), 30.into()), 2.into(), "wrong result"); + assert_eq!( + modexp_circuit( + 123456789.into(), 987654321.into(), 11111111111111111111111111111111.into() + ), + 6929919895158922141640454333396.into(), + "wrong result" + ); + } #[test] - fn test_modexp_modsize0_returndatasizeFiller_filler() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_circuit_worst_case() { + assert_eq!( + modexp_circuit(PREV_PRIME_384_MINUS_2, PREV_PRIME_384_MINUS_1, PREV_PRIME_384), + 1.into(), + "wrong result" + ); + } - let (calldata, expected) = test_modexp_modsize0_returndatasizeFiller_data(); + #[test] + fn test_modexp_edge_case_circuit() { + assert_eq!(modexp_circuit(12.into(), 42.into(), 0.into()), 0.into()); + assert_eq!(modexp_circuit(12.into(), 42.into(), 1.into()), 0.into()); + assert_eq!(modexp_circuit(0.into(), 42.into(), 42.into()), 0.into()); + assert_eq!(modexp_circuit(42.into(), 0.into(), 42.into()), 1.into()); + assert_eq!(modexp_circuit(0.into(), 0.into(), 42.into()), 1.into()); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; + #[test] + fn test_modexp_precompile_input_output_worst() { + let mut calldata = array![]; + let l0f: u128 = Into::<_, felt252>::into(PREV_PRIME_384_MINUS_2.limb0).try_into().unwrap(); + let l1f: u128 = Into::<_, felt252>::into(PREV_PRIME_384_MINUS_2.limb1).try_into().unwrap(); + let size = array![48_u8].span().pad_left_with_zeroes(32); + calldata.append_span(size); + calldata.append_span(size); + calldata.append_span(size); + + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l0f.to_be_bytes()); + + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span((l0f + 1).to_be_bytes()); + + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span(l1f.to_be_bytes()); + calldata.append_span((l0f + 2).to_be_bytes()); + + let (gas, result) = ModExp::exec(calldata.span()).unwrap(); + let expected_result = array![1].span().pad_left_with_zeroes(48); + let expected_gas = 4596; + assert_eq!(result, expected_result); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_precompile_size_gt_48_should_err() { + let mut calldata = array![]; + let size = array![49_u8].span().pad_left_with_zeroes(32); + calldata.append_span(size); + calldata.append_span(size); + calldata.append_span(size); + + let result = ModExp::exec(calldata.span()); + assert!(result.is_err()); + } - let expected_gas = 44_954; + #[test] + fn test_modexp_precompile_base_and_exp_zero_should_return_empty() { + let mut calldata = array![]; + let size_zero = array![0].span().pad_left_with_zeroes(32); + let size_not_zero = array![48].span().pad_left_with_zeroes(32); - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + calldata.append_span(size_zero); + calldata.append_span(size_not_zero); + calldata.append_span(size_zero); - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + let (gas, result) = ModExp::exec(calldata.span()).unwrap(); + let expected_result = [].span(); + let expected_gas = 200; + assert_eq!(result, expected_result); + assert_eq!(gas, expected_gas); } + // To test all input sizes, we use the fact that: + // For prime p, a^(p-1) mod p = 1, for all a. (Fermat's little theorem) + // Using prime_deltas we get a p = 256^(i+1) + prime_deltas[i] + // The array prime_delta has been computed such that p is prime. + // That way, p is a prime of size m bytes for all 2 <= m <= 48. + // We use a = p - 2 to do the modexp check: (p-2)^(p-1) = 1 mod p + // We construct p as the u8 array [1, 0, 0, 0, ... , 0, 0, 0, prime_delta[i]] + // |----- i zeros ----| #[test] - fn test_modexp_create2callPrecompiles_test0_berlin() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_precompile_input_output_all_sizes() { + #[cairofmt::skip] + let prime_deltas = array![7_u16, 3, 43, 15, 15, 21, 81, 13, 15, 13, 7, 61, 111, 25, 451, + 51, 85, 175, 253, 7, 87, 427, 27, 133, 235, 375, 423, 735, 357, 115, 81, 297, 175, + 57, 45, 127, 61, 37, 91, 27, 15, 241, 231, 55, 105, 127, 115]; + + let mut size = 2_u32; + for delta in prime_deltas { + let mut modulus: Array = array![]; + modulus.append(1); + for _i in 2..size - 1 { + modulus.append(0); + }; + if size > 2 { + modulus.append((delta.into() / 256_u16).try_into().unwrap()); + } + modulus.append((delta % 256).try_into().unwrap()); + + let mut base: Array = Default::default(); + let delta_base = delta - 2; + base.append(1); + for _i in 2..size - 1 { + base.append(0); + }; + if size > 2 { + base.append((delta_base.into() / 256_u16).try_into().unwrap()); + } + base.append((delta_base % 256).try_into().unwrap()); + + let delta_exponent = delta - 1; + let mut exponent: Array = Default::default(); + exponent.append(1); + for _i in 2..size - 1 { + exponent.append(0); + }; + if size > 2 { + exponent.append((delta_exponent.into() / 256_u16).try_into().unwrap()); + } + exponent.append((delta_exponent % 256).try_into().unwrap()); - let (calldata, expected) = test_modexp_create2callPrecompiles_test0_berlin_data(); + let size_bytes = size.to_be_bytes().pad_left_with_zeroes(32); + let mut calldata = array![]; + calldata.append_span(size_bytes); + calldata.append_span(size_bytes); + calldata.append_span(size_bytes); + calldata.append_span(base.span()); + calldata.append_span(exponent.span()); + calldata.append_span(modulus.span()); - vm.message.data = calldata; - vm.message.target.evm = EthAddress { address: 5 }; - let expected_gas = 1_360; + let (_, result) = ModExp::exec(calldata.span()).unwrap(); + let expected_result_bytes = 1_u8.to_be_bytes(); - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + assert_eq!(result, expected_result_bytes.pad_left_with_zeroes(size)); - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + size = size + 1; + } } #[test] fn test_modexp_eip198_example_1() { - let mut vm = VMBuilderTrait::new_with_presets().build(); - let (calldata, expected) = test_modexp_eip198_example_1_data(); + let expected_gas = 1_360; + let (gas, result) = ModExp::exec(calldata).unwrap(); + assert_eq!(result, expected); + assert_eq!(gas, expected_gas); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; + #[test] + fn test_modexp_eip198_example_2() { + let (calldata, expected) = test_modexp_eip198_example_2_data(); let expected_gas = 1_360; + let (gas, result) = ModExp::exec(calldata).unwrap(); + assert_eq!(result, expected); + assert_eq!(gas, expected_gas); + } - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + #[test] + fn test_modexp_berlin_empty_input() { + let calldata = [].span(); + let expected = [].span(); + let expected_gas = 200; + let (gas, result) = ModExp::exec(calldata).unwrap(); + assert_eq!(result, expected); + assert_eq!(gas, expected_gas); + } - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + + + #[test] + fn test_modexp_random_inputs_0_0_0__46700b4d40ac5c35af2c22dda2787a91eb567b06() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + #[cairofmt::skip] + let expected_result = array![]; + let expected_gas = 200; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); } + #[test] + fn test_modexp_random_inputs_228_122_121__c8da329a38766a62e69170c92eada1ef6e774b25() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xcd, 0x76, 0x6f, 0xac, 0xc4, 0xc1, 0xeb, 0xe7, 0x8a, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0xf2, 0x00, 0x6e, 0x62, 0x12, 0x7a, 0xe4, 0xae, 0xd5, 0xdc, 0x99, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_111_131_70__f3c197f8a398ad9b42c7f6ee74e625bba3d77f2e() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfb, 0xbe, 0x41, 0x03, 0xc4, 0xa8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x01, 0x9e, 0x11, 0xd1, 0x02, 0x41, 0x00, 0x20, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_15_124_164__3736531daeddf220e62f5c5957fa8aef2850acbc() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xa7, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_192_63_83__d17d6182863e3e5c093849d65f735087b81f1d7b() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_203_128_45__df5f8981b7f8117c138c5a526251389ff43d7b5a() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x90, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb6, 0x9c, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_203_256_53__30b5bf6e6046013296d804fec3b4ece7fc016910() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_203_256_53__445d0c3f9559396cbc2de2b570fd2a55aad4d0ef() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_203_256_53__703505c21d3e7679ab742bfce4b0971fced2d050() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_195_130_93__320a8a5f7dee17677f5b77c8914d4aeb9556070e() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa4, 0xb3, 0x6a, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x81, 0xb1, 0x77, 0x93, 0x97, 0x1c, 0x89, 0xc5, 0x3d, 0x0c, 0x36, 0x26, 0xe5, 0x86, 0x04, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_195_130_93__c052da0d0d0d4131dd4a4f83c835121c7da1db3b() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x81, 0xb1, 0x77, 0x93, 0x97, 0x1c, 0x89, 0xc5, 0x3d, 0x0c, 0x36, 0x26, 0xe5, 0x86, 0x04, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x81, 0xb1, 0x77, 0x93, 0x97, 0x1c, 0x89, 0xc5, 0x3d, 0x0c, 0x36, 0x26, 0xe5, 0x86, 0x04, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_195_130_93__7c603e3e0e065ca63bf8cc896d5c847d61c59c2c() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x81, 0xb1, 0x77, 0x93, 0x97, 0x1c, 0x89, 0xc5, 0x3d, 0x0c, 0x36, 0x26, 0xe5, 0x86, 0x04, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_195_256_256__0fc1f505c295042258dcaf05ab3f21686a077344() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x36, 0x81, 0xb1, 0x77, 0x93, 0x97, 0x1c, 0x89, 0xc5, 0x3d, 0x0c, 0x36, 0x26, 0xe5, 0x86, 0x04, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x97, 0x6a, 0x14, 0xcb, 0xb0, 0xf3, 0x5d, 0x59, 0xee, 0xd0, 0xfc, 0x9a, 0x87, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xa7, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_1_1_256__908947385b2480867064cbc5a0c466a530cdad1c() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0xa7, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_226_133__d4bd68fd5073a41dbbde6c08ba049b888ecd2ad3() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x4a, 0xc4, 0x00, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x2c, 0xf2, 0x4a, 0x59, 0x22, 0x07, 0xb9, 0x28, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_226_133__525b0fe69af0a680deb36a49539aeda01279eaa5() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x4a, 0xc4, 0x00, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x2c, 0xf2, 0x4a, 0x22, 0x22, 0x07, 0xb9, 0x28, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_226_133__c27d38c2e26b80213f5e72b8c169c03d07b69e28() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x4a, 0xc4, 0x00, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x2c, 0xf2, 0x4a, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_226_133__c5fffa3e2ccf2c338d2802e1e057007060bbc10c() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x4a, 0xc4, 0x00, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_256_0__06189e8781259cd15dcae0d329578d260a1f4c4b() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_153_0_3__a1ddd0ab4a281889c4d8c4ac5352c823c09c80d6() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x07, 0xea, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x31, 0xa5]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_211_36__5a312b1c23eb4c794f427a1b6d9bebc93bd88089() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_36_36__94805d4cb0222911ec996b081069b06cb8a66b17() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_36_53__f43b13d6e8953ca38ea312a628b99511bc1d58d4() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_53_53__7a6f3ac3012eab744911ad44e0c143f78dc70bb7() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_53_53__d3e8d008c4f3139316631be6a17e23ec1782f3fc() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xef, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_0_0__60403adc5084f54ddd5bcb6244091bee6f5606bf() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x07, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_53_0_4__e9aed1f9f5b4978b227466aae3a97c20bc009b82() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x07, 0xef, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_0_62_13__7b23519bf720a22e909439addbcb7e3bb32a4fb9() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7c, 0x00, 0xbf, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_0_62_13__64d05097b8bdc48827c3ebecf3785d0c7a4839f1() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7c, 0x00, 0xbf, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_0_62_13__78c469607d17f54d99dbcd1111d3395662dff56f() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x7c, 0xbf, 0xbf, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_0_62_0__a9e84e095185194823d489d16b30e9422b5c7d7a() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xbf, 0xbf, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_114_62_141__8b0305981f08f76f0fb89e3e970a12214dc4c720() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x52, 0xb2, 0x18, 0xd8, 0x1e, 0x56, 0x20, 0xb3, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_62_62_141__b7a92da401f429913c145faa0421a0f65e5a305f() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x52, 0xb2, 0x18, 0xd8, 0x1e, 0x56, 0x20, 0xb3, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_62_62_141__363ae3bd166fa513958db13ba9fcd5ae28277c4f() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_62_62_141__66331ac2ce6b0e3254b54f8fe754595433951643() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + + #[test] + fn test_modexp_random_inputs_62_62_141__590745efb856e01e8acce2bf1bb8290398601edc() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + } + + #[test] - fn test_modexp_eip198_example_2() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_non_empty_outputs_28_7_18() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xc1, 0x63, 0x70, 0x0f, 0x80, 0x67, 0xda, 0x2a, 0xf7, 0xd3, 0xb0, 0xe1, 0x97, 0x08, 0xd8, 0x96, 0xa7, 0x96, 0xc9, 0xa5, 0xcc, 0x49, 0x4e, 0x1a, 0x35, 0xe5, 0x57, 0x06, 0xf4, 0xdf, 0xc5, 0x36, 0xaf, 0x47, 0x0e, 0x75, 0xfa, 0x64, 0x3f, 0x04, 0xb1, 0xb3, 0xeb, 0xda, 0x1e, 0x2c, 0xb2, 0x9a, 0x78, 0x76, 0x94, 0xe4, 0xa9]; + #[cairofmt::skip] + let expected_result = array![0x07, 0x4f, 0x1b, 0xd7, 0x15, 0x36, 0x09, 0xb9, 0xaf, 0x37, 0xf9, 0xe4, 0x33, 0x15, 0x08, 0x3c, 0x9a, 0xd4]; + let expected_gas = 293; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - let (calldata, expected) = test_modexp_eip198_example_2_data(); + #[test] + fn test_modexp_non_empty_outputs_26_16_10() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x9e, 0x21, 0x82, 0x6f, 0xed, 0xfb, 0x58, 0x3f, 0x44, 0x0d, 0xd9, 0x8b, 0xb7, 0x1e, 0x33, 0xa9, 0xfe, 0x89, 0x7b, 0xeb, 0x81, 0x12, 0xb0, 0xb4, 0x7c, 0x34, 0xe4, 0xbf, 0x05, 0x98, 0xe3, 0x34, 0xa4, 0xbf, 0xa2, 0x03, 0x49, 0x50, 0xfe, 0xd7, 0xdc, 0xc3, 0x61, 0x3f, 0x1c, 0xac, 0xb5, 0x31, 0xc3, 0xb0, 0x64]; + #[cairofmt::skip] + let expected_result = array![0xb2, 0x7a, 0xd9, 0x50, 0xa1, 0x4c, 0x19, 0xb8, 0x41, 0x18]; + let expected_gas = 666; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; - let expected_gas = 1_360; + #[test] + fn test_modexp_non_empty_outputs_2_39_4() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x1b, 0x29, 0x1d, 0x44, 0x69, 0xe1, 0x34, 0x92, 0xad, 0x43, 0x29, 0xa3, 0x1a, 0xc6, 0x1b, 0x24, 0x4e, 0x9e, 0xc8, 0xe3, 0x3b, 0x5c, 0x32, 0x3b, 0x46, 0xc8, 0x71, 0xcb, 0xc9, 0x75, 0xd7, 0x30, 0xb1, 0x58, 0xf0, 0x23, 0x79, 0x5e, 0x92, 0x0c, 0xc7, 0x95, 0x00, 0x0b, 0x2a]; + #[cairofmt::skip] + let expected_result = array![0x1e, 0xaa, 0x64, 0x9f]; + let expected_gas = 200; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_24_17_15() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xed, 0x9b, 0x26, 0x87, 0x3c, 0x7a, 0xce, 0x44, 0x59, 0x36, 0x40, 0x1a, 0xdb, 0x27, 0x37, 0x1a, 0xf8, 0xed, 0x9e, 0x2c, 0x91, 0x2f, 0x0e, 0x56, 0xaf, 0xa6, 0x49, 0x23, 0x8e, 0x6a, 0x03, 0xd8, 0xa2, 0x3d, 0xf6, 0x7b, 0xc9, 0xd6, 0xa3, 0xcd, 0x29, 0xee, 0x86, 0xfd, 0x74, 0x9f, 0xde, 0x9b, 0x0d, 0x46, 0xf8, 0x03, 0xd3, 0xa1, 0x52, 0xdb]; + #[cairofmt::skip] + let expected_result = array![0xdd, 0x2c, 0xfd, 0x56, 0x5e, 0xae, 0x04, 0x99, 0xdc, 0x3b, 0xd7, 0xe4, 0x46, 0xd9, 0x7c]; + let expected_gas = 405; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_46_15_1() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4c, 0xcf, 0x18, 0x8d, 0x29, 0xd4, 0x57, 0x93, 0xf5, 0xa3, 0xaa, 0xa9, 0xfa, 0x02, 0xc8, 0x56, 0xde, 0xb3, 0x3a, 0x21, 0x54, 0xc6, 0x63, 0x8f, 0xfd, 0x93, 0x35, 0x1d, 0xa1, 0xaa, 0xf9, 0x91, 0xbd, 0x9d, 0x61, 0x0d, 0xb8, 0x1d, 0xf8, 0xc6, 0x64, 0x30, 0x43, 0x1e, 0xf2, 0x49, 0x81, 0x52, 0xf0, 0x4f, 0x11, 0xaa, 0xec, 0xeb, 0xea, 0xa5, 0x26, 0xc9, 0xaf, 0x2d, 0xa0, 0x14]; + #[cairofmt::skip] + let expected_result = array![0x01]; + let expected_gas = 1428; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_21_43_7() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6e, 0x2c, 0x9d, 0x83, 0x7f, 0xe8, 0x61, 0x5f, 0x07, 0x32, 0xb9, 0x08, 0xc0, 0x01, 0xf6, 0x4d, 0xc7, 0x5d, 0xf5, 0xfa, 0xe9, 0x69, 0xfe, 0xc8, 0x2f, 0x85, 0x2b, 0xff, 0xa0, 0x21, 0xf6, 0xfa, 0x13, 0xdf, 0x33, 0x73, 0xa5, 0xb1, 0x80, 0xec, 0x35, 0x80, 0x78, 0xb3, 0xff, 0xa8, 0xa3, 0xa5, 0x78, 0x60, 0x30, 0x8d, 0xcb, 0xc9, 0xe0, 0xb1, 0x74, 0x8b, 0x05, 0x8f, 0xb6, 0x64, 0xb5, 0xf5, 0xae, 0x32, 0x96, 0x4e, 0x22, 0xa1, 0x30]; + #[cairofmt::skip] + let expected_result = array![0x69, 0xb0, 0xaa, 0x64, 0x19, 0x65, 0xd9]; + let expected_gas = 1026; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_8_1_8() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x53, 0x09, 0x51, 0x83, 0xd4, 0x47, 0x99, 0xee, 0xc4, 0x8f, 0x39, 0xe6, 0xbd, 0x00, 0x79, 0x91, 0xb7]; + #[cairofmt::skip] + let expected_result = array![0x8b, 0x00, 0xa8, 0x96, 0xeb, 0xe7, 0x06, 0xf4]; + let expected_gas = 200; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + #[test] + fn test_modexp_non_empty_outputs_28_42_48() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x8f, 0x4b, 0x7e, 0xa4, 0x43, 0x1c, 0x00, 0x58, 0x8e, 0xec, 0x8c, 0x55, 0xc1, 0xb2, 0x08, 0x11, 0x19, 0xbd, 0x88, 0xa1, 0xc0, 0x5c, 0x9a, 0xad, 0x21, 0xab, 0x83, 0xca, 0xe9, 0xdd, 0xe6, 0x94, 0xd3, 0xc5, 0x95, 0xce, 0x25, 0x1d, 0x69, 0xeb, 0xb8, 0x23, 0xaa, 0xd3, 0x4e, 0x74, 0x70, 0xa9, 0xc9, 0x17, 0x88, 0x87, 0x1d, 0x3c, 0x0e, 0x02, 0x03, 0xfb, 0x17, 0x1c, 0xbc, 0xa0, 0xd0, 0xee, 0xef, 0x4d, 0xba, 0x0e, 0x41, 0x33, 0xcc, 0x02, 0x20, 0xc8, 0x3f, 0xa8, 0x22, 0xf2, 0x23, 0x6a, 0xde, 0x8c, 0xab, 0x2d, 0x5a, 0x83, 0xe4, 0xa7, 0x09, 0x19, 0x33, 0xa8, 0xb4, 0x48, 0xfb, 0x1b, 0x0c, 0x46, 0x0d, 0x64, 0x63, 0xe5, 0xdd, 0xd7, 0xc2, 0x33, 0xe6, 0x19, 0x81, 0x33, 0xba, 0x3c, 0xf5, 0x3f, 0x98, 0x04, 0xee, 0x79]; + #[cairofmt::skip] + let expected_result = array![0x4c, 0x94, 0x8a, 0xae, 0xe7, 0x91, 0x5c, 0xe0, 0x96, 0xb0, 0x1e, 0xed, 0x81, 0xb1, 0xc4, 0x87, 0x18, 0x3a, 0x63, 0x8d, 0x7b, 0xce, 0xaa, 0x2c, 0xf9, 0x5d, 0x78, 0xf6, 0xe9, 0x9f, 0x9b, 0xb7, 0x3f, 0x61, 0x20, 0x2f, 0xa3, 0xd0, 0x3e, 0xca, 0x50, 0x4e, 0x04, 0xd7, 0xd3, 0x7f, 0x0c, 0x8e]; + let expected_gas = 4020; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_39_5_16() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0xec, 0xbc, 0x9b, 0xe9, 0x07, 0x7a, 0x1a, 0x88, 0x2c, 0x49, 0xcb, 0x2a, 0xb4, 0xda, 0x9e, 0xcd, 0x08, 0xf3, 0xd3, 0x64, 0x76, 0xb7, 0x67, 0x3d, 0xbb, 0xb1, 0x74, 0xbc, 0x97, 0x3c, 0x68, 0xb3, 0xc0, 0x78, 0xad, 0xd4, 0x38, 0xc4, 0x57, 0x57, 0x59, 0x58, 0xa0, 0x30, 0x51, 0x0d, 0x67, 0xbf, 0x79, 0xef, 0xda, 0x28, 0x99, 0x03, 0x22, 0xaf, 0x98, 0xf2, 0x33]; + #[cairofmt::skip] + let expected_result = array![0x1d, 0xe5, 0x9e, 0x9f, 0xf6, 0x64, 0x6e, 0x2a, 0x4b, 0x40, 0xed, 0xa9, 0xf5, 0x14, 0x81, 0x05]; + let expected_gas = 316; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_30_32_14() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20]; + #[cairofmt::skip] + let expected_result = array![0x23, 0xf0, 0x67, 0x50, 0x68, 0x07, 0x13, 0xef, 0x63, 0x46, 0x95, 0xee, 0x25, 0x60]; + let expected_gas = 1360; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_30_32_30() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20, 0xa0, 0x53, 0x89, 0x00, 0xb6, 0xfb, 0x07, 0xf0, 0xe9, 0x05, 0xba, 0xbf, 0x88, 0x04, 0x3c, 0x45]; + #[cairofmt::skip] + let expected_result = array![0x2b, 0xf0, 0x82, 0x43, 0x2d, 0x79, 0x51, 0x0e, 0xe5, 0x2c, 0x1e, 0x02, 0x4f, 0x5f, 0x0d, 0x70, 0x1a, 0x3a, 0x05, 0xe3, 0x16, 0x49, 0x79, 0xeb, 0xaf, 0x53, 0x83, 0x2d, 0x83, 0x5a]; + let expected_gas = 1360; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_30_32_32() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20, 0xa0, 0x53, 0x89, 0x00, 0xb6, 0xfb, 0x07, 0xf0, 0xe9, 0x05, 0xba, 0xbf, 0x88, 0x04, 0x3c, 0x45, 0x9f, 0x57]; + #[cairofmt::skip] + let expected_result = array![0x27, 0x78, 0x4b, 0x28, 0x3d, 0xbf, 0x91, 0x47, 0xf2, 0x42, 0x73, 0x89, 0xe1, 0xb0, 0xfe, 0xa0, 0x0f, 0x23, 0xd0, 0xfc, 0xba, 0x22, 0x4c, 0x3f, 0xae, 0xfe, 0x2e, 0x59, 0xc9, 0x77, 0xf5, 0x39]; + let expected_gas = 1360; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_30_30_32() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20, 0xa0, 0x53, 0x89, 0x00, 0xb6, 0xfb, 0x07, 0xf0, 0xe9, 0x05, 0xba, 0xbf, 0x88, 0x04, 0x3c, 0x45]; + #[cairofmt::skip] + let expected_result = array![0x19, 0xd3, 0x08, 0x71, 0xe3, 0xe2, 0xe7, 0x69, 0xe2, 0x0c, 0x28, 0x8d, 0x10, 0x27, 0x10, 0xaf, 0xb2, 0xf9, 0xee, 0x71, 0x31, 0x8a, 0xb8, 0xd8, 0xe3, 0x9f, 0xae, 0x5e, 0x07, 0xb3, 0x81, 0x37]; + let expected_gas = 1274; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + #[test] + fn test_modexp_non_empty_outputs_32_30_32() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20, 0xa0, 0x53, 0x89, 0x00, 0xb6, 0xfb, 0x07, 0xf0, 0xe9, 0x05, 0xba, 0xbf, 0x88, 0x04, 0x3c, 0x45, 0xdf, 0x90]; + #[cairofmt::skip] + let expected_result = array![0x13, 0x72, 0xc9, 0x3a, 0x9c, 0x8a, 0x70, 0x34, 0xc6, 0xcd, 0xb2, 0x4d, 0x98, 0xa3, 0x74, 0xf3, 0x23, 0x14, 0x6c, 0x9f, 0x6e, 0xad, 0x80, 0x5d, 0x66, 0x85, 0x68, 0x91, 0x73, 0x77, 0xc0, 0x47]; + let expected_gas = 1253; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); } + #[test] + fn test_modexp_non_empty_outputs_32_32_32() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x86, 0xd7, 0x0f, 0x75, 0x4d, 0x38, 0x76, 0xa1, 0x31, 0xda, 0x03, 0xbc, 0x00, 0xa2, 0x6f, 0x76, 0xc0, 0x43, 0xc4, 0x45, 0xd2, 0xd9, 0xae, 0x07, 0x8a, 0x93, 0x50, 0xa4, 0xa6, 0xb0, 0x3a, 0x43, 0x51, 0x67, 0xb0, 0x53, 0x75, 0xd9, 0xb5, 0x86, 0xa0, 0x99, 0x9b, 0x69, 0x7f, 0x20, 0xa0, 0x53, 0x89, 0x00, 0xb6, 0xfb, 0x07, 0xf0, 0xe9, 0x05, 0xba, 0xbf, 0x88, 0x04, 0x3c, 0x45, 0xdf, 0x90, 0xb2, 0xac]; + #[cairofmt::skip] + let expected_result = array![0x27, 0xd1, 0x08, 0x1f, 0x46, 0xe1, 0x33, 0x4e, 0x1b, 0xf4, 0x3d, 0x41, 0x43, 0x62, 0x0d, 0x45, 0x2e, 0x16, 0x48, 0x51, 0x4c, 0x3e, 0x3e, 0x56, 0xae, 0x55, 0x36, 0xbe, 0x6e, 0xdb, 0x75, 0xff]; + let expected_gas = 1338; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } #[test] - fn test_modexp_nagydani_1_square() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_non_empty_outputs_9_35_9() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x3c, 0xd9, 0xa5, 0x8d, 0xa9, 0x29, 0xcb, 0xb5, 0x58, 0xfd, 0x0d, 0x71, 0x76, 0x6d, 0x44, 0x82, 0x79, 0xc3, 0xa7, 0x85, 0x4e, 0xc6, 0x38, 0xf5, 0x17, 0xce, 0x03, 0x0c, 0x40, 0xfc, 0xb5, 0x9e, 0x44, 0x76, 0x0e, 0xca, 0xd5, 0x73, 0x6d, 0x9a, 0xc2, 0xcf, 0x01, 0xc1, 0x7a]; + #[cairofmt::skip] + let expected_result = array![0x15, 0xf7, 0xa0, 0xaf, 0x8d, 0x4f, 0xac, 0x3e, 0xf6]; + let expected_gas = 372; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - let (calldata, expected) = test_modexp_nagydani_1_square_data(); + #[test] + fn test_modexp_non_empty_outputs_35_9_35() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x3c, 0xd9, 0xa5, 0x8d, 0xa9, 0x29, 0xcb, 0xb5, 0x58, 0xfd, 0x0d, 0x71, 0x76, 0x6d, 0x44, 0x82, 0x79, 0xc3, 0xa7, 0x85, 0x4e, 0xc6, 0x38, 0xf5, 0x17, 0xce, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x3c, 0xd9, 0xa5, 0x8d, 0xa9, 0x29, 0xcb, 0xb5, 0x58, 0xfd, 0x0d, 0x71, 0x76, 0x6d, 0x44, 0x82, 0x79, 0xc3, 0xa7, 0x85, 0x4e, 0xc6, 0x38, 0xf5, 0x17, 0xce, 0xca, 0xd5, 0x73, 0x6d, 0x9a, 0xc2, 0xcf, 0x01, 0xc1]; + #[cairofmt::skip] + let expected_result = array![0x29, 0xc8, 0xdc, 0x5a, 0x4e, 0xbe, 0xd9, 0x00, 0x09, 0x47, 0x7f, 0x88, 0xe8, 0x35, 0x50, 0xa8, 0x28, 0x96, 0xc4, 0x04, 0x05, 0x36, 0x45, 0x42, 0x4e, 0x8f, 0x6a, 0xfa, 0x6b, 0x83, 0x0e, 0x81, 0xb9, 0x5e, 0xaf]; + let expected_gas = 558; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_9_9_35() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x3c, 0xd9, 0xa5, 0x8d, 0xa9, 0x29, 0xcb, 0xb5, 0x58, 0xfd, 0x0d, 0x71, 0x76, 0x6d, 0x44, 0x82, 0x79, 0xc3, 0xa7, 0x85, 0x4e, 0xc6, 0x38, 0xf5, 0x17, 0xce, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x3c, 0xd9, 0xa5, 0x8d, 0xa9, 0x29, 0xcb, 0xb5, 0x58]; + #[cairofmt::skip] + let expected_result = array![0xb1, 0xf8, 0xc0, 0xe3, 0xe9, 0xf5, 0x5e, 0x16, 0x14, 0xd4, 0xdb, 0xae, 0xc3, 0x2d, 0x57, 0x18, 0x68, 0x52, 0xc0, 0x2e, 0x16, 0x09, 0x07, 0x6b, 0xde, 0x62, 0xdd, 0xed, 0xfb, 0x03, 0x82, 0x18, 0x93, 0x67, 0x10]; + let expected_gas = 575; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; + #[test] + fn test_modexp_non_empty_outputs_9_9_9() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0x08, 0xe8, 0x18, 0x28, 0xd0, 0x11, 0xb4, 0x48, 0x7e, 0xfd, 0x0d, 0x71, 0x76, 0x6d, 0x44, 0x82, 0x79, 0xc3]; + #[cairofmt::skip] + let expected_result = array![0xe1, 0xed, 0xf1, 0x76, 0x32, 0x33, 0x3a, 0x17, 0x6f]; let expected_gas = 200; - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + #[test] + fn test_modexp_non_empty_outputs_27_21_37() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0xa2, 0x6e, 0x92, 0x29, 0xe0, 0x56, 0xd4, 0x31, 0xd8, 0xd2, 0xb7, 0x0a, 0xd1, 0xc7, 0x27, 0x7e, 0x8f, 0xee, 0x27, 0x48, 0x10, 0xc2, 0x33, 0xb4, 0xa2, 0x45, 0x59, 0x29, 0x79, 0x1c, 0x12, 0x55, 0x7e, 0x87, 0x87, 0x92, 0xa9, 0xe4, 0xbb, 0x09, 0x9b, 0x04, 0xcd]; + #[cairofmt::skip] + let expected_result = array![0x77, 0x21, 0x41, 0xb8, 0xf3, 0x33, 0xc3, 0x5b, 0x12, 0x8e, 0xea, 0x92, 0x1e, 0x78, 0xb9, 0x05, 0x74, 0x02, 0xd8, 0x07, 0xea, 0x5c, 0x80, 0x1d, 0x59, 0x9e, 0x3e, 0xd1, 0xfd, 0x1b, 0x20, 0x3b, 0xee, 0x4a, 0x16, 0x95, 0x6a]; + let expected_gas = 1391; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); } #[test] - fn test_modexp_nagydani_1_qube() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_non_empty_outputs_27_21_21() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0xa2, 0x6e, 0x92, 0x29, 0xe0, 0x56, 0xd4, 0x31, 0xd8, 0xd2, 0xb7, 0x0a, 0xd1, 0xc7, 0x27, 0x7e, 0x8f, 0xee, 0x27, 0x48, 0x10, 0xc2, 0x33, 0xb4, 0xa2, 0x45, 0x59]; + #[cairofmt::skip] + let expected_result = array![0xa6, 0xf3, 0x83, 0x39, 0xee, 0x8b, 0x9c, 0xea, 0x48, 0xb9, 0x06, 0x43, 0x33, 0x30, 0x83, 0x81, 0x52, 0x7e, 0x90, 0x04, 0x30]; + let expected_gas = 890; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - let (calldata, expected) = test_modexp_nagydani_1_qube_data(); + #[test] + fn test_modexp_non_empty_outputs_21_21_21() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0x39, 0xd4, 0xa4, 0x9b, 0x78, 0xd3, 0xbd, 0x79, 0x52, 0xc8, 0xbd, 0x4a, 0x41, 0x98, 0x23, 0x74, 0x71, 0x91, 0x1e, 0x07, 0x94, 0xa2, 0x6e, 0x92, 0x29, 0xe0, 0x56, 0xd4, 0x31, 0xd8, 0xd2, 0xb7, 0x0a, 0xd1, 0xc7, 0x27, 0x7e, 0x8f, 0xee, 0x27, 0x48, 0x10]; + #[cairofmt::skip] + let expected_result = array![0x50, 0x29, 0x1d, 0x4d, 0x0f, 0xa5, 0x5d, 0x2b, 0x9e, 0x89, 0x96, 0xc2, 0x89, 0x75, 0x7a, 0x70, 0xc3, 0x08, 0xf9, 0xdd, 0x70]; + let expected_gas = 495; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; + #[test] + fn test_modexp_non_empty_outputs_41_5_5() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xd7, 0x47, 0x6a, 0xe6, 0xb4, 0xd7, 0x47, 0x6a, 0xe6, 0xb4, 0x75, 0x76, 0xca, 0xfe, 0x92, 0x88, 0xdd, 0x9f, 0xee, 0xbc, 0x1f, 0xbf, 0xd9, 0x27, 0x16, 0x0d, 0xf8, 0x9e, 0x95, 0x4e, 0x8f, 0x18, 0x58, 0xd4, 0x39, 0xf3, 0x0b, 0xc0, 0x53, 0x1a, 0xe1, 0x72, 0x3c, 0xf0, 0x89, 0xff, 0x4d, 0xe5, 0xe2, 0x85, 0xab]; + #[cairofmt::skip] + let expected_result = array![0x2d, 0x57, 0x69, 0xa6, 0xa2]; + let expected_gas = 456; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_5_5_24() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x47, 0x6a, 0xe6, 0xb4, 0x75, 0x47, 0x6a, 0xe6, 0xb4, 0x75, 0x76, 0xca, 0xfe, 0x92, 0x88, 0xdd, 0x9f, 0xee, 0xbc, 0x1f, 0xbf, 0xd9, 0x27, 0x16, 0x0d, 0xf8, 0x9e, 0x95, 0x4e, 0x8f, 0x18, 0x58, 0xd4, 0x39]; + #[cairofmt::skip] + let expected_result = array![0x19, 0xd9, 0xbd, 0x67, 0x91, 0xb3, 0x8c, 0x18, 0x66, 0x41, 0xdf, 0x8e, 0x3b, 0x16, 0x68, 0x67, 0x81, 0xa5, 0xa9, 0x86, 0x44, 0x5d, 0x63, 0xec]; let expected_gas = 200; - let gas_before = vm.gas_left; - Precompiles::exec_precompile(ref vm).unwrap(); - let gas_after = vm.gas_left; + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - assert_eq!(gas_before - gas_after, expected_gas); - assert_eq!(vm.return_data, expected); + #[test] + fn test_modexp_non_empty_outputs_24_5_24() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x47, 0x6a, 0xe6, 0xb4, 0x75, 0x47, 0x6a, 0xe6, 0xb4, 0x75, 0x76, 0xca, 0xfe, 0x92, 0x88, 0xdd, 0x9f, 0xee, 0xbc, 0x1f, 0xbf, 0xd9, 0x27, 0x16, 0x0d, 0xf8, 0x9e, 0x95, 0x4e, 0x8f, 0x18, 0x58, 0xd4, 0x39, 0x58, 0xc1, 0xea, 0xcc, 0x45, 0x98, 0xef, 0xa9, 0x76, 0x42, 0x83, 0xbe, 0x19, 0xcb, 0xb5, 0x59, 0xe3, 0xd4, 0xa7]; + #[cairofmt::skip] + let expected_result = array![0x1d, 0x70, 0xcf, 0x07, 0xf0, 0x22, 0xac, 0xa4, 0x14, 0x1e, 0x8d, 0x73, 0xda, 0x24, 0x85, 0x2b, 0x8b, 0xa0, 0xde, 0x85, 0xb0, 0x4d, 0x8b, 0x42]; + let expected_gas = 200; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); } #[test] - fn test_modexp_berlin_empty_input() { - let mut vm = VMBuilderTrait::new_with_presets().build(); + fn test_modexp_non_empty_outputs_39_27_2() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x60, 0x47, 0x02, 0x9e, 0x6b, 0x16, 0x19, 0xd3, 0x62, 0xd6, 0x80, 0x57, 0xe7, 0xc5, 0x54, 0x7e, 0x40, 0x58, 0xdf, 0x83, 0x2f, 0xc5, 0x3d, 0x9f, 0x94, 0xd9, 0xe5, 0x76, 0x43, 0x7b, 0xef, 0x2c, 0x61, 0xd9, 0xba, 0x21, 0xbd, 0xe9, 0xdb, 0x60, 0x47, 0x02, 0x9e, 0x6b, 0x16, 0x19, 0xd3, 0x62, 0xd6, 0x80, 0x57, 0xe7, 0xc5, 0x54, 0x7e, 0x40, 0x58, 0xdf, 0x83, 0x2f, 0xc5, 0x3d, 0x9f, 0x94, 0xd9, 0xe5, 0x76, 0x43]; + #[cairofmt::skip] + let expected_result = array![0x44, 0xf8]; + let expected_gas = 1783; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - let calldata = [].span(); - let expected = [].span(); + #[test] + fn test_modexp_non_empty_outputs_2_27_2() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x9e, 0x6b, 0x16, 0x19, 0xd3, 0x62, 0xd6, 0x80, 0x57, 0xe7, 0xc5, 0x54, 0x7e, 0x40, 0x58, 0xdf, 0x83, 0x2f, 0xc5, 0x3d, 0x9f, 0x94, 0xd9, 0xe5, 0x76, 0x43, 0x02, 0x9e, 0x6b, 0x16]; + #[cairofmt::skip] + let expected_result = array![0x26, 0xc2]; + let expected_gas = 200; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - vm.message.target.evm = EthAddress { address: 5 }; - vm.message.data = calldata; + #[test] + fn test_modexp_non_empty_outputs_2_2_2() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6b, 0x16, 0x6b, 0x16, 0x19, 0xd3]; + #[cairofmt::skip] + let expected_result = array![0x11, 0xda]; + let expected_gas = 200; - Precompiles::exec_precompile(ref vm).unwrap(); + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } - assert_eq!(vm.return_data, expected); + #[test] + fn test_modexp_non_empty_outputs_31_29_16() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xfb, 0x6e, 0xcd, 0x5b, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xfb, 0x6e, 0xcd, 0x5b, 0xe6, 0x24, 0x27, 0x8f, 0x87, 0x44, 0x81, 0x84, 0x5e, 0x73, 0x92, 0x99, 0xf6, 0x81]; + #[cairofmt::skip] + let expected_result = array![0x98, 0x66, 0x83, 0x23, 0x4a, 0x28, 0x2e, 0xcb, 0x12, 0x26, 0xaf, 0x52, 0x40, 0x08, 0x86, 0xca]; + let expected_gas = 1210; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_29_29_16() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xfb, 0x6e, 0xcd, 0x5b, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xfb, 0x6e, 0xcd, 0x5b, 0xe6, 0x24, 0x27, 0x8f, 0x87, 0x44, 0x81, 0x84, 0x5e, 0x73, 0x92, 0x99]; + #[cairofmt::skip] + let expected_result = array![0x91, 0x1c, 0xb6, 0xd1, 0x16, 0x18, 0xf2, 0xba, 0x3f, 0xa3, 0x40, 0xf7, 0xa4, 0x90, 0x90, 0x6a]; + let expected_gas = 1232; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_29_29_29() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x3a, 0x1c, 0xcd, 0x5b, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xcd, 0x5b, 0x0b, 0x2d, 0xb7, 0x2d, 0x2e, 0xcc, 0xe8, 0x07, 0x1c, 0x30, 0x01, 0x57, 0x2c, 0x06, 0x08, 0x8b, 0x37, 0xc3, 0xae, 0xf5, 0xb9, 0xf4, 0xca, 0x8b, 0x06, 0xbe, 0xcd, 0xfb, 0x6e, 0xcd, 0x5b, 0xe6, 0x24, 0x27, 0x8f, 0x87, 0x44, 0x81, 0x84, 0x5e, 0x73, 0x92, 0x99, 0x4c, 0xeb, 0x81, 0x91, 0x40, 0x43, 0x8c, 0x0c, 0x6a, 0x1a, 0x46]; + #[cairofmt::skip] + let expected_result = array![0x33, 0xbb, 0xf6, 0x82, 0x7b, 0x3a, 0x90, 0xdf, 0xea, 0x53, 0x05, 0xeb, 0x31, 0xb2, 0xa6, 0x47, 0xd9, 0xe4, 0xc2, 0x3b, 0x30, 0x7c, 0x0c, 0x05, 0xcb, 0x7b, 0xce, 0x6f, 0x6c]; + let expected_gas = 1232; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_5_25_39() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x28, 0xf4, 0x1a, 0xba, 0xcf, 0x35, 0xe8, 0x54, 0x92, 0x7f, 0xd8, 0xbc, 0x5c, 0xe1, 0x37, 0xa2, 0x2e, 0x39, 0x15, 0x26, 0x85, 0x1a, 0x1e, 0xea, 0x77, 0xb0, 0x29, 0x70, 0xe8, 0xe8, 0xce, 0x0e, 0xc8, 0xc8, 0x67, 0x35, 0x64, 0x59, 0xd9, 0xd8, 0xdf, 0x96, 0xd7, 0xf3, 0x5b, 0xb4, 0x15, 0x2e, 0x42, 0x8f, 0x24, 0x48, 0x6b, 0x25, 0x60, 0x9f, 0x7a, 0xfc, 0x03, 0x35, 0xb4, 0x42, 0x9c, 0xba, 0xb8, 0x98, 0x42, 0xce, 0x4b]; + #[cairofmt::skip] + let expected_result = array![0xc4, 0xa9, 0xbd, 0x9f, 0x62, 0x48, 0x51, 0x65, 0x27, 0xc8, 0xd2, 0xf7, 0x22, 0xda, 0x5b, 0x41, 0x4e, 0x6d, 0x29, 0xab, 0xbc, 0x18, 0x59, 0x7d, 0x89, 0x10, 0x80, 0x38, 0x48, 0xea, 0x78, 0x7f, 0x36, 0xcf, 0xe2, 0x05, 0x76, 0xb9, 0xd1]; + let expected_gas = 1641; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_39_25_39() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x28, 0xf4, 0x1a, 0xba, 0xcf, 0x35, 0xe8, 0x54, 0x92, 0x7f, 0xd8, 0xbc, 0x5c, 0xe1, 0x37, 0xa2, 0x2e, 0x39, 0x15, 0x26, 0x85, 0x1a, 0x1e, 0xea, 0x77, 0xb0, 0x29, 0x70, 0xe8, 0xe8, 0xce, 0x0e, 0xc8, 0xc8, 0x67, 0x35, 0x64, 0x59, 0xd9, 0xd8, 0xdf, 0x96, 0xd7, 0xf3, 0x5b, 0xb4, 0x15, 0x2e, 0x42, 0x8f, 0x24, 0x48, 0x6b, 0x25, 0x60, 0x9f, 0x7a, 0xfc, 0x03, 0x35, 0xb4, 0x42, 0x9c, 0xba, 0xb8, 0x98, 0x42, 0xce, 0x4b, 0xaf, 0x7f, 0x50, 0xee, 0x9a, 0x29, 0x8d, 0xf8, 0x3a, 0xa9, 0x09, 0xf3, 0x78, 0x56, 0x70, 0xd8, 0xc6, 0x4b, 0x11, 0x51, 0x6d, 0x1d, 0x63, 0x29, 0x75, 0x71, 0x95, 0x11, 0x17, 0xc7, 0x89, 0x7c, 0xb5, 0x76]; + #[cairofmt::skip] + let expected_result = array![0x7c, 0x44, 0x9d, 0xbf, 0x6e, 0x6f, 0xa1, 0xd1, 0x8b, 0x3d, 0x5f, 0xab, 0xd7, 0x61, 0x27, 0x62, 0x39, 0x81, 0xcc, 0x19, 0xf6, 0x69, 0x24, 0xc7, 0xb5, 0x55, 0x41, 0x7d, 0x63, 0x86, 0x29, 0x6b, 0x13, 0x24, 0x13, 0xed, 0xd4, 0x01, 0x11]; + let expected_gas = 1658; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + } + + #[test] + fn test_modexp_non_empty_outputs_39_25_25() { + #[cairofmt::skip] + let input = array![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x28, 0xf4, 0x1a, 0xba, 0xcf, 0x35, 0xe8, 0x54, 0x92, 0x7f, 0xd8, 0xbc, 0x5c, 0xe1, 0x37, 0xa2, 0x2e, 0x39, 0x15, 0x26, 0x85, 0x1a, 0x1e, 0xea, 0x77, 0xb0, 0x29, 0x70, 0xe8, 0xe8, 0xce, 0x0e, 0xc8, 0xc8, 0x67, 0x35, 0x64, 0x59, 0xd9, 0xd8, 0xdf, 0x96, 0xd7, 0xf3, 0x5b, 0xb4, 0x15, 0x2e, 0x42, 0x8f, 0x24, 0x48, 0x6b, 0x25, 0x60, 0x9f, 0x7a, 0xfc, 0x03, 0x35, 0xb4, 0x42, 0x9c, 0xba, 0xb8, 0x98, 0x42, 0xce, 0x4b, 0xaf, 0x7f, 0x50, 0xee, 0x9a, 0x29, 0x8d, 0xf8, 0x3a, 0xa9, 0x09, 0xf3, 0x78, 0x56, 0x70, 0xd8, 0xc6, 0x4b, 0x11, 0x51]; + #[cairofmt::skip] + let expected_result = array![0x16, 0xc6, 0x02, 0xb3, 0x15, 0x80, 0xfc, 0x84, 0x92, 0x05, 0x58, 0xf1, 0xca, 0xb8, 0x9d, 0x86, 0x1b, 0x66, 0xcf, 0xa4, 0x2d, 0x42, 0x8d, 0x9d, 0xc9]; + let expected_gas = 1658; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); } } diff --git a/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo b/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo index c11e97103..ad3ec13a0 100644 --- a/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo @@ -1,1552 +1,122 @@ -fn test_modexp_modsize0_returndatasizeFiller_data() -> (Span, Span) { - let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 100, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 100, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 100, - 84, - 66, - 221, - 194, - 183, - 15, - 102, - 193, - 246, - 210, - 178, - 150, - 192, - 168, - 117, - 190, - 126, - 221, - 208, - 168, - 9, - 88, - 203, - 199, - 66, - 95, - 24, - 153, - 204, - 249, - 5, - 17, - 165, - 195, - 24, - 34, - 110, - 72, - 238, - 35, - 241, - 48, - 180, - 77, - 193, - 122, - 105, - 28, - 230, - 107, - 229, - 218, - 24, - 184, - 94, - 215, - 148, - 53, - 53, - 178, - 5, - 170, - 18, - 94, - 159, - 89, - 41, - 74, - 0, - 240, - 81, - 85, - 194, - 62, - 151, - 218, - 198, - 179, - 160, - 11, - 12, - 99, - 200, - 65, - 27, - 248, - 21, - 252, - 24, - 59, - 66, - 11, - 77, - 157, - 197, - 247, - 21, - 4, - 13, - 92, - 96, - 149, - 127, - 82, - 211, - 52, - 184, - 67, - 25, - 122, - 222, - 197, - 140, - 19, - 28, - 144, - 124, - 217, - 96, - 89, - 252, - 90, - 220, - 233, - 221, - 163, - 81, - 181, - 223, - 61, - 102, - 111, - 207, - 62, - 182, - 60, - 70, - 133, - 28, - 24, - 22, - 227, - 35, - 242, - 17, - 158, - 189, - 245, - 239, - 53 +pub fn test_modexp_modsize0_returndatasizeFiller_data() -> (Span, Span) { + #[cairofmt::skip] + let calldata = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 84, 66, 221, 194, + 183, 15, 102, 193, 246, 210, 178, 150, 192, 168, 117, 190, 126, 221, 208, 168, 9, 88, 203, 199, 66, 95, 24, + 153, 204, 249, 5, 17, 165, 195, 24, 34, 110, 72, 238, 35, 241, 48, 180, 77, 193, 122, 105, 28, 230, 107, 229, + 218, 24, 184, 94, 215, 148, 53, 53, 178, 5, 170, 18, 94, 159, 89, 41, 74, 0, 240, 81, 85, 194, 62, 151, 218, + 198, 179, 160, 11, 12, 99, 200, 65, 27, 248, 21, 252, 24, 59, 66, 11, 77, 157, 197, 247, 21, 4, 13, 92, 96, + 149, 127, 82, 211, 52, 184, 67, 25, 122, 222, 197, 140, 19, 28, 144, 124, 217, 96, 89, 252, 90, 220, 233, 221, + 163, 81, 181, 223, 61, 102, 111, 207, 62, 182, 60, 70, 133, 28, 24, 22, 227, 35, 242, 17, 158, 189, 245, 239, 53 ].span(); - + #[cairofmt::skip] let expected = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ].span(); + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ].span(); (calldata, expected) } -fn test_modexp_create2callPrecompiles_test0_berlin_data() -> (Span, Span) { +pub fn test_modexp_create2callPrecompiles_test0_berlin_data() -> (Span, Span) { + #[cairofmt::skip] let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 3, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 254, - 255, - 255, - 252, - 46, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 47 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 3, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 46, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 47 ].span(); - + #[cairofmt::skip] let expected = [ - 22, - 46, - 173, - 130, - 202, - 222, - 250, - 234, - 246, - 233, - 40, - 50, - 72, - 253, - 242, - 242, - 132, - 95, - 99, - 150, - 246, - 241, - 124, - 77, - 90, - 57, - 248, - 32, - 182, - 246, - 181, + 22, 46, 173, 130, 202, 222, 250, 234, 246, 233, 40, 50, 72, 253, 242, 242, 132, 95, 99, 150, 246, 241, 124, 77, 90, 57, 248, 32, 182, 246, 181, 249 ].span(); (calldata, expected) } -fn test_modexp_eip198_example_1_data() -> (Span, Span) { +pub fn test_modexp_eip198_example_1_data() -> (Span, Span) { + #[cairofmt::skip] let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 3, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 254, - 255, - 255, - 252, - 46, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 254, - 255, - 255, - 252, - 47 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 46, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 47 ].span(); - + #[cairofmt::skip] let expected = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ].span(); (calldata, expected) } -fn test_modexp_eip198_example_2_data() -> (Span, Span) { +pub fn test_modexp_eip198_example_2_data() -> (Span, Span) { + #[cairofmt::skip] let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 32, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 254, - 255, - 255, - 252, - 46, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 254, - 255, - 255, - 252, - 47 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 46, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 252, 47 ].span(); - + #[cairofmt::skip] let expected = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 ].span(); (calldata, expected) } -fn test_modexp_nagydani_1_square_data() -> (Span, Span) { +pub fn test_modexp_nagydani_1_square_data() -> (Span, Span) { + #[cairofmt::skip] let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 64, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 64, - 224, - 154, - 217, - 103, - 84, - 101, - 197, - 58, - 16, - 159, - 172, - 102, - 164, - 69, - 201, - 27, - 41, - 45, - 43, - 178, - 197, - 38, - 138, - 221, - 179, - 12, - 216, - 47, - 128, - 252, - 176, - 3, - 63, - 249, - 124, - 128, - 165, - 252, - 111, - 57, - 25, - 58, - 233, - 105, - 198, - 237, - 230, - 113, - 10, - 107, - 122, - 194, - 112, - 120, - 160, - 109, - 144, - 239, - 28, - 114, - 229, - 200, - 95, - 181, - 2, - 252, - 158, - 31, - 107, - 235, - 129, - 81, - 101, - 69, - 151, - 82, - 24, - 7, - 94, - 194, - 175, - 17, - 140, - 216, - 121, - 141, - 246, - 224, - 138, - 20, - 124, - 96, - 253, - 96, - 149, - 172, - 43, - 176, - 44, - 41, - 8, - 207, - 77, - 215, - 200, - 31, - 17, - 194, - 137, - 228, - 188, - 233, - 143, - 53, - 83, - 118, - 143, - 57, - 42, - 128, - 206, - 34, - 191, - 92, - 79, - 74, - 36, - 140, - 107 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 224, 154, 217, 103, 84, 101, 197, 58, + 16, 159, 172, 102, 164, 69, 201, 27, 41, 45, 43, 178, 197, 38, 138, 221, 179, 12, 216, 47, 128, 252, 176, 3, 63, 249, + 124, 128, 165, 252, 111, 57, 25, 58, 233, 105, 198, 237, 230, 113, 10, 107, 122, 194, 112, 120, 160, 109, 144, 239, 28, 114, + 229, 200, 95, 181, 2, 252, 158, 31, 107, 235, 129, 81, 101, 69, 151, 82, 24, 7, 94, 194, 175, 17, 140, 216, 121, 141, + 246, 224, 138, 20, 124, 96, 253, 96, 149, 172, 43, 176, 44, 41, 8, 207, 77, 215, 200, 31, 17, 194, 137, 228, 188, 233, + 143, 53, 83, 118, 143, 57, 42, 128, 206, 34, 191, 92, 79, 74, 36, 140, 107 ].span(); - + #[cairofmt::skip] let expected = [ - 96, - 0, - 143, - 22, - 20, - 204, - 1, - 220, - 251, - 107, - 251, - 9, - 198, - 37, - 207, - 144, - 180, - 125, - 68, - 104, - 219, - 129, - 181, - 248, - 183, - 163, - 157, - 66, - 243, - 50, - 234, - 185, - 178, - 218, - 143, - 45, - 149, - 49, - 22, - 72, - 168, - 242, - 67, - 244, - 187, - 19, - 207, - 179, - 216, - 247, - 242, - 163, - 192, - 20, - 18, - 46, - 187, - 62, - 212, - 27, - 2, - 120, - 58, - 220 + 96, 0, 143, 22, 20, 204, 1, 220, 251, 107, 251, 9, 198, 37, 207, 144, 180, 125, 68, 104, 219, 129, 181, 248, 183, 163, + 157, 66, 243, 50, 234, 185, 178, 218, 143, 45, 149, 49, 22, 72, 168, 242, 67, 244, 187, 19, 207, 179, 216, 247, 242, 163, + 192, 20, 18, 46, 187, 62, 212, 27, 2, 120, 58, 220 ].span(); (calldata, expected) } -fn test_modexp_nagydani_1_qube_data() -> (Span, Span) { +pub fn test_modexp_nagydani_1_qube_data() -> (Span, Span) { + #[cairofmt::skip] let calldata = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 64, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 64, - 224, - 154, - 217, - 103, - 84, - 101, - 197, - 58, - 16, - 159, - 172, - 102, - 164, - 69, - 201, - 27, - 41, - 45, - 43, - 178, - 197, - 38, - 138, - 221, - 179, - 12, - 216, - 47, - 128, - 252, - 176, - 3, - 63, - 249, - 124, - 128, - 165, - 252, - 111, - 57, - 25, - 58, - 233, - 105, - 198, - 237, - 230, - 113, - 10, - 107, - 122, - 194, - 112, - 120, - 160, - 109, - 144, - 239, - 28, - 114, - 229, - 200, - 95, - 181, - 3, - 252, - 158, - 31, - 107, - 235, - 129, - 81, - 101, - 69, - 151, - 82, - 24, - 7, - 94, - 194, - 175, - 17, - 140, - 216, - 121, - 141, - 246, - 224, - 138, - 20, - 124, - 96, - 253, - 96, - 149, - 172, - 43, - 176, - 44, - 41, - 8, - 207, - 77, - 215, - 200, - 31, - 17, - 194, - 137, - 228, - 188, - 233, - 143, - 53, - 83, - 118, - 143, - 57, - 42, - 128, - 206, - 34, - 191, - 92, - 79, - 74, - 36, - 140, - 107 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 224, 154, 217, 103, 84, 101, 197, 58, + 16, 159, 172, 102, 164, 69, 201, 27, 41, 45, 43, 178, 197, 38, 138, 221, 179, 12, 216, 47, 128, 252, 176, 3, 63, 249, + 124, 128, 165, 252, 111, 57, 25, 58, 233, 105, 198, 237, 230, 113, 10, 107, 122, 194, 112, 120, 160, 109, 144, 239, 28, 114, + 229, 200, 95, 181, 3, 252, 158, 31, 107, 235, 129, 81, 101, 69, 151, 82, 24, 7, 94, 194, 175, 17, 140, 216, 121, 141, + 246, 224, 138, 20, 124, 96, 253, 96, 149, 172, 43, 176, 44, 41, 8, 207, 77, 215, 200, 31, 17, 194, 137, 228, 188, 233, + 143, 53, 83, 118, 143, 57, 42, 128, 206, 34, 191, 92, 79, 74, 36, 140, 107 ].span(); - + #[cairofmt::skip] let expected = [ - 72, - 52, - 164, - 107, - 165, - 101, - 219, - 39, - 144, - 59, - 28, - 114, - 12, - 157, - 89, - 62, - 132, - 228, - 203, - 214, - 173, - 46, - 100, - 179, - 24, - 133, - 217, - 68, - 246, - 140, - 216, - 1, - 249, - 34, - 37, - 168, - 150, - 28, - 149, - 45, - 223, - 39, - 151, - 250, - 71, - 1, - 179, - 48, - 200, - 92, - 75, - 54, - 55, - 152, - 16, - 11, - 146, - 26, - 26, - 34, - 164, - 106, - 127, - 236 + 72, 52, 164, 107, 165, 101, 219, 39, 144, 59, 28, 114, 12, 157, 89, 62, 132, 228, 203, 214, 173, 46, 100, 179, 24, 133, + 217, 68, 246, 140, 216, 1, 249, 34, 37, 168, 150, 28, 149, 45, 223, 39, 151, 250, 71, 1, 179, 48, 200, 92, 75, 54, + 55, 152, 16, 11, 146, 26, 26, 34, 164, 106, 127, 236 ].span(); (calldata, expected) diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto.cairo index 261fd6b16..a4b6fd47f 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto.cairo @@ -1,2 +1 @@ pub mod blake2_compress; -pub mod modexp; diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp.cairo deleted file mode 100644 index 0fde2f4c2..000000000 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp.cairo +++ /dev/null @@ -1,3 +0,0 @@ -pub mod arith; -pub mod lib; -pub mod mpnat; diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo deleted file mode 100644 index 95a53bd37..000000000 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo +++ /dev/null @@ -1,2524 +0,0 @@ -// CREDITS: The implementation has been take from -// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) -use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; - -use core::num::traits::{WideMul, OverflowingAdd, OverflowingSub, WrappingMul}; -use core::option::OptionTrait; -use crate::felt_vec::{Felt252VecTrait}; -use crate::helpers::{u128_split}; -use crate::math::WrappingBitshift; -use crate::math::{Bitshift}; -use crate::traits::BoolIntoNumeric; -use crate::traits::integer::U128Trait; -use super::mpnat::{MPNat, Word, DoubleWord, WORD_BITS, BASE, DOUBLE_WORD_MAX, WORD_MAX}; - -// Computes the "Montgomery Product" of two numbers. -// See Coarsely Integrated Operand Scanning (CIOS) Method in -// https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf -// In short, computes `xy (r^-1) mod n`, where `r = 2^(8*4*s)` and `s` is the number of -// digits needs to represent `n`. `n_prime` has the property that `r(r^(-1)) - nn' = 1`. -// Note: This algorithm only works if `xy < rn` (generally we will either have both `x < n`, `y < n` -// or we will have `x < r`, `y < n`). -pub fn monpro(ref x: MPNat, ref y: MPNat, ref n: MPNat, n_prime: Word, ref out: Felt252Vec) { - let s = out.len() - 2; - - let mut i = 0; - loop { - if i == s { - break; - } - - let mut c = 0; - let mut j = 0; - - loop { - if j == s { - break; - } - - let (prod, carry) = shifted_carrying_mul( - out[j], x.digits.get(j).unwrap_or(0), y.digits.get(i).unwrap_or(0), c, - ); - out.set(j, prod); - c = carry; - - j += 1; - }; - - let (sum, carry) = carrying_add(out[s], c, false); - out.set(s, sum); - out.set(s + 1, carry.into()); - - let m = out[0].wrapping_mul(n_prime); - let (_, carry) = shifted_carrying_mul(out[0], m, n.digits.get(0).unwrap_or(0), 0); - c = carry; - - let mut j = 1; - loop { - if j == s { - break; - } - - let (prod, carry) = shifted_carrying_mul(out[j], m, n.digits.get(j).unwrap_or(0), c); - out.set(j - 1, prod); - c = carry; - - j += 1; - }; - - let (sum, carry) = carrying_add(out[s], c, false); - out.set(s - 1, sum); - out.set(s, out[s + 1] + (carry.into())); // overflow impossible at this stage - - i += 1; - }; - - // Result is only in the first s + 1 words of the output. - out.set(s + 1, 0); - - let mut j = s + 1; - let should_return = loop { - if j == 0 { - break false; - } - - let i = j - 1; - - if out[i] > n.digits.get(i).unwrap_or(0) { - break false; - } else if out[i] < n.digits.get(i).unwrap_or(0) { - break true; - } - - j -= 1; - }; - - if should_return { - return; - } - - let mut b = false; - let mut i: u32 = 0; - loop { - if i == s || i == out.len { - break; - } - - let out_digit = out[i]; - - let (diff, borrow) = borrowing_sub(out_digit, n.digits.get(i).unwrap_or(0), b); - out.set(i, diff); - b = borrow; - - i += 1; - }; - - let (diff, _) = borrowing_sub(out[s], 0, b); - out.set(s, diff); -} - -// Equivalent to `monpro(x, x, n, n_prime, out)`, but more efficient. -pub fn monsq(ref x: MPNat, ref n: MPNat, n_prime: Word, ref out: Felt252Vec) { - let s = n.digits.len(); - - big_sq(ref x, ref out); - let mut i = 0; - - loop { - if i == s { - break false; - } - - let mut c: Word = 0; - let m = out[i].wrapping_mul(n_prime); - - let mut j = 0; - loop { - if j == s { - break; - } - - let (prod, carry) = shifted_carrying_mul( - out[i + j], m, n.digits.get(j).unwrap_or(0), c - ); - out.set(i + j, prod); - c = carry; - - j += 1; - }; - - let mut j = i + s; - loop { - if c == 0 { - break; - } - let (sum, carry) = carrying_add(out[j], c, false); - out.set(j, sum); - c = carry.into(); - - j += 1; - }; - - i += 1; - }; - - // Only keep the last `s + 1` digits in `out`. - let mut new_vec: Felt252Vec = out.clone_slice(s, s + 1); - - // safe unwrap, since new_vec.len <= out.len - new_vec.expand(out.len).unwrap(); - out = new_vec; - - let mut k = s + 1; - let should_return = loop { - if k == 0 { - break false; - } - - let i = k - 1; - - if out[i] < n.digits.get(i).unwrap_or(0) { - break true; - } - if out[i] > n.digits.get(i).unwrap_or(0) { - break false; - } - - k -= 1; - }; - - if should_return { - return; - } - - let mut b = false; - let mut i = 0; - loop { - if i == s || i == out.len { - break; - } - - let out_digit = out[i]; - let (diff, borrow) = borrowing_sub(out_digit, n.digits.get(i).unwrap_or(0), b); - out.set(i, diff); - b = borrow; - - i += 1; - }; - - let (diff, _) = borrowing_sub(out[s], 0, b); - out.set(s, diff); -} - - -/// Computes `base ^ exp`, ignoring overflow. -pub fn big_wrapping_pow( - ref base: MPNat, exp: Span, ref scratch_space: Felt252Vec -) -> MPNat { - let mut digits = Felt252VecImpl::new(); - digits.expand(scratch_space.len()).unwrap(); - let mut result = MPNat { digits }; - result.digits.set(0, 1); - - let mut i = 0; - loop { - if i == exp.len() { - break; - } - - let b = *exp[i]; - let mut mask: u8 = 128; - - loop { - if mask == 0 { - break; - } - - // TODO: investigae if deep clone can be avoided - let digits = result.digits.duplicate(); - let mut tmp = MPNat { digits }; - - big_wrapping_mul(ref result, ref tmp, ref scratch_space); - result.digits.copy_from_vec_le(ref scratch_space).unwrap(); - scratch_space.reset(); // zero-out the scratch space - - if (b & mask) != 0 { - big_wrapping_mul(ref result, ref base, ref scratch_space); - result.digits.copy_from_vec_le(ref scratch_space).unwrap(); - scratch_space.reset(); // zero-out the scratch space - } - - mask = mask.shr(1); - }; - - i += 1; - }; - - result -} - -/// Computes `(x * y) mod 2^(WORD_BITS*out.len())`. -pub fn big_wrapping_mul(ref x: MPNat, ref y: MPNat, ref out: Felt252Vec) { - let s = out.len(); - let mut i = 0; - - loop { - if i == s { - break; - } - - let mut c: Word = 0; - - let mut j = 0; - let stop_condition = s - i; - loop { - if j == stop_condition { - break; - } - - let (prod, carry) = shifted_carrying_mul( - out[i + j], x.digits.get(j).unwrap_or(0), y.digits.get(i).unwrap_or(0), c - ); - c = carry; - out.set(i + j, prod); - - j += 1; - }; - - i += 1; - } -} - -// Given x odd, computes `x^(-1) mod 2^32`. -// See `MODULAR-INVERSE` in https://link.springer.com/content/pdf/10.1007/3-540-46877-3_21.pdf -pub fn mod_inv(x: Word) -> Word { - let mut y = 1; - let mut i = 2; - - loop { - if i == WORD_BITS { - break; - } - - let mask: u64 = 1_u64.shl(i) - 1; - let xy = x.wrapping_mul(y) & mask; - let q = (mask + 1) / 2; - if xy >= q { - y += q; - } - i += 1; - }; - - let xy = x.wrapping_mul(y); - let q = 1_u64.wrapping_shl((WORD_BITS - 1)); - if xy >= q { - y += q; - } - y -} - -/// Computes R mod n, where R = 2^(WORD_BITS*k) and k = n.digits.len() -/// Note that if R = qn + r, q must be smaller than 2^WORD_BITS since `2^(WORD_BITS) * n > R` -/// (adding a whole additional word to n is too much). -/// Uses the two most significant digits of n to approximate the quotient, -/// then computes the difference to get the remainder. It is possible that this -/// quotient is too big by 1; we can catch that case by looking for overflow -/// in the subtraction. -pub fn compute_r_mod_n(ref n: MPNat, ref out: Felt252Vec) { - let k = n.digits.len(); - - if k == 1 { - let r = BASE; - let result = r % (n.digits[0].into()); - out.set(0, result.as_u64()); - return; - } - - let approx_n = join_as_double(n.digits[k - 1], n.digits[k - 2]); - let approx_q = DOUBLE_WORD_MAX / approx_n; - let mut approx_q: Word = approx_q.as_u64(); - - loop { - let mut c = 0; - let mut b = false; - - let mut i: usize = 0; - loop { - if i == n.digits.len || i == out.len { - break; - } - - let n_digit = n.digits[i]; - - let (prod, carry) = carrying_mul(approx_q, n_digit, c); - c = carry; - - let (diff, borrow) = borrowing_sub(0, prod, b); - b = borrow; - out.set(i, diff); - - i += 1; - }; - - let (_, borrow) = borrowing_sub(1, c, b); - if borrow { - // approx_q was too large so `R - approx_q*n` overflowed. - // try again with approx_q -= 1 - approx_q -= 1; - } else { - break; - } - } -} - -/// Computes `a + xy + c` where any overflow is captured as the "carry", -/// the second part of the output. The arithmetic in this function is -/// guaranteed to never overflow because even when all 4 variables are -/// equal to `WORD_MAX` the output is smaller than `DOUBLEWORD_MAX`. -pub fn shifted_carrying_mul(a: Word, x: Word, y: Word, c: Word) -> (Word, Word) { - let res: DoubleWord = a.into() + x.wide_mul(y) + c.into(); - let (top_word, bottom_word) = u128_split(res); - (bottom_word, top_word) -} - -/// Computes `xy + c` where any overflow is captured as the "carry", -/// the second part of the output. The arithmetic in this function is -/// guaranteed to never overflow because even when all 3 variables are -/// equal to `Word::MAX` the output is smaller than `DoubleWord::MAX`. -pub fn carrying_mul(x: Word, y: Word, c: Word) -> (Word, Word) { - let wide = x.wide_mul(y) + c.into(); - let (top_word, bottom_word) = u128_split(wide); - (bottom_word, top_word) -} - -/// computes x + y accounting for any carry from a previous addition -pub fn carrying_add(x: Word, y: Word, carry: bool) -> (Word, bool) { - let (a, b) = x.overflowing_add(y); - let (c, d) = a.overflowing_add(carry.into()); - (c, b | d) -} - -// Computes `x - y` accounting for any borrow from a previous subtraction -pub fn borrowing_sub(x: Word, y: Word, borrow: bool) -> (Word, bool) { - let (a, b) = x.overflowing_sub(y); - let (c, d) = a.overflowing_sub(borrow.into()); - (c, b | d) -} - -/// Takes 2 words and joins them into a double word -/// -/// # Arguments -/// `hi` is the most significant word -/// `lo` is the least significant word -/// -/// # Returns -/// The double word obtained by joining `hi` and `lo` -pub fn join_as_double(hi: Word, lo: Word) -> DoubleWord { - let hi: DoubleWord = hi.into(); - hi.shl(WORD_BITS).into() + lo.into() -} - -/// Computes `x^2`, storing the result in `out`. -fn big_sq(ref x: MPNat, ref out: Felt252Vec) { - let s = x.digits.len(); - let mut i = 0; - - loop { - if i == s { - break; - } - - let (product, carry) = shifted_carrying_mul(out[i + i], x.digits[i], x.digits[i], 0); - out.set(i + i, product); - let mut c: DoubleWord = carry.into(); - - let mut j = i + 1; - - loop { - if j == s { - break; - } - - let mut new_c: DoubleWord = 0; - let res: DoubleWord = (x.digits[i].into()) * (x.digits[j].into()); - let (res, overflow) = res.overflowing_add(res); - if overflow { - new_c += BASE; - } - - let (res, overflow) = out[i + j].into().overflowing_add(res); - if overflow { - new_c += BASE; - } - - let (res, overflow) = res.overflowing_add(c); - if overflow { - new_c += BASE; - } - - out.set(i + j, res.as_u64()); - c = new_c + res.shr(WORD_BITS); - - j += 1; - }; - - let (sum, carry) = carrying_add(out[i + s], c.as_u64(), false); - out.set(i + s, sum); - out.set(i + s + 1, (c.shr(WORD_BITS) + (carry.into())).as_u64()); - - i += 1; - } -} - -// Performs `a <<= shift`, returning the overflow -pub fn in_place_shl(ref a: Felt252Vec, shift: u32) -> Word { - let mut c: Word = 0; - let carry_shift = WORD_BITS - shift; - - let mut i = 0; - loop { - if i == a.len { - break; - } - - let mut a_digit = a[i]; - let carry = a_digit.wrapping_shr(carry_shift); - a_digit = a_digit.wrapping_shl(shift) | c; - a.set(i, a_digit); - - c = carry; - - i += 1; - }; - - c -} - -// Performs `a >>= shift`, returning the overflow -pub fn in_place_shr(ref a: Felt252Vec, shift: u32) -> Word { - let mut b: Word = 0; - let borrow_shift = WORD_BITS - shift; - - let mut i = a.len; - loop { - if i == 0 { - break; - } - - let j = i - 1; - - let mut a_digit = a[j]; - let borrow = a_digit.wrapping_shl(borrow_shift); - a_digit = a_digit.wrapping_shr(shift) | b; - a.set(j, a_digit); - - b = borrow; - - i -= 1; - }; - - b -} - -// Performs a += b, returning if there was overflow -pub fn in_place_add(ref a: Felt252Vec, ref b: Felt252Vec) -> bool { - let mut c = false; - - let mut i = 0; - - loop { - if i == a.len() || i == b.len() { - break; - } - - let a_digit = a[i]; - let b_digit = b[i]; - - let (sum, carry) = carrying_add(a_digit, b_digit, c); - a.set(i, sum); - c = carry; - - i += 1; - }; - - c -} - -// Performs `a -= xy`, returning the "borrow". -pub fn in_place_mul_sub(ref a: Felt252Vec, ref x: Felt252Vec, y: Word) -> Word { - // a -= x*0 leaves a unchanged, so return early - if y == 0 { - return 0; - } - - // carry is between -big_digit::MAX and 0, so to avoid overflow we store - // offset_carry = carry + big_digit::MAX - let mut offset_carry = WORD_MAX; - - let mut i = 0; - - loop { - if i == a.len() || i == x.len() { - break; - } - - let a_digit = a[i]; - let x_digit = x[i]; - - // We want to calculate sum = x - y * c + carry. - // sum >= -(big_digit::MAX * big_digit::MAX) - big_digit::MAX - // sum <= big_digit::MAX - // Offsetting sum by (big_digit::MAX << big_digit::BITS) puts it in DoubleBigDigit range. - let offset_sum = join_as_double(WORD_MAX, a_digit) - - WORD_MAX.into() - + offset_carry.into() - - ((x_digit.into()) * (y.into())); - - let new_offset_carry = (offset_sum.shr(WORD_BITS)).as_u64(); - let new_x = offset_sum.as_u64(); - offset_carry = new_offset_carry; - a.set(i, new_x); - - i += 1; - }; - - // Return the borrow. - WORD_MAX - offset_carry -} - - -#[cfg(test)] -mod tests { - use alexandria_data_structures::vec::VecTrait; - use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; - use core::num::traits::{WrappingSub, WrappingMul}; - use core::result::ResultTrait; - use core::traits::Into; - - use crate::crypto::modexp::arith::{ - mod_inv, monsq, monpro, compute_r_mod_n, in_place_shl, in_place_shr, big_wrapping_pow, - big_wrapping_mul, big_sq, borrowing_sub, shifted_carrying_mul - }; - use crate::crypto::modexp::mpnat::{ - MPNat, MPNatTrait, WORD_MAX, DOUBLE_WORD_MAX, BASE, Word, WORD_BYTES - }; - use crate::crypto::modexp::mpnat::{mp_nat_to_u128}; - use crate::felt_vec::{Felt252VecTrait}; - use crate::math::{WrappingBitshift, WrappingExponentiation}; - use crate::traits::bytes::ToBytes; - - // the tests are taken from - // [aurora-engine](https://github.com/aurora-is-near/aurora-engine/blob/1213f2c7c035aa523601fced8f75bef61b4728ab/engine-modexp/src/arith.rs#L401) - - fn check_monsq(x: u128, n: u128) { - let mut a = MPNatTrait::from_big_endian(x.to_be_bytes_padded()); - let mut m = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); - let n_prime = WORD_MAX - mod_inv(m.digits[0]) + 1; - - let mut output = Felt252VecImpl::new(); - output.expand(2 * m.digits.len() + 1).unwrap(); - - monsq(ref a, ref m, n_prime, ref output); - let mut result = MPNat { digits: output }; - - let mut output = Felt252VecImpl::new(); - output.expand(m.digits.len() + 2).unwrap(); - let mut tmp = MPNat { digits: a.digits.duplicate() }; - monpro(ref a, ref tmp, ref m, n_prime, ref output); - - let mut expected = MPNat { digits: output }; - - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - fn check_monpro(x: u128, y: u128, n: u128, ref expected: MPNat) { - let mut a = MPNatTrait::from_big_endian(x.to_be_bytes_padded()); - let mut b = MPNatTrait::from_big_endian(y.to_be_bytes_padded()); - let mut m = MPNatTrait::from_big_endian(n.to_be_bytes()); - let n_prime = WORD_MAX - mod_inv(m.digits[0]) + 1; - - let mut output = Felt252VecImpl::new(); - output.expand(m.digits.len() + 2).unwrap(); - monpro(ref a, ref b, ref m, n_prime, ref output); - let mut result = MPNat { digits: output }; - - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - - fn check_r_mod_n(n: u128, ref expected: MPNat) { - let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); - let mut out: Felt252Vec = Felt252VecImpl::new(); - out.expand(x.digits.len()).unwrap(); - compute_r_mod_n(ref x, ref out); - let mut result = MPNat { digits: out }; - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - fn check_in_place_shl(n: u128, shift: u32) { - let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); - in_place_shl(ref x.digits, shift); - let mut result = mp_nat_to_u128(ref x); - - let mask = BASE.wrapping_pow(x.digits.len().into()).wrapping_sub(1); - assert_eq!(result, n.wrapping_shl(shift) & mask); - } - - fn check_in_place_shr(n: u128, shift: u32) { - let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); - in_place_shr(ref x.digits, shift); - let mut result = mp_nat_to_u128(ref x); - - assert_eq!(result, n.wrapping_shr(shift)); - } - - fn check_mod_inv(n: Word) { - let n_inv = mod_inv(n); - assert_eq!(n.wrapping_mul(n_inv), 1); - } - - fn check_big_wrapping_pow(a: u128, b: u32, expected_bytes: Span) { - let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); - let mut y = b.to_be_bytes_padded(); - - let mut scratch = Felt252VecImpl::new(); - scratch.expand(1 + (expected_bytes.len() / WORD_BYTES)).unwrap(); - - let mut result = big_wrapping_pow(ref x, y, ref scratch); - - let mut expected = MPNatTrait::from_big_endian(expected_bytes); - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - fn check_big_wrapping_mul(a: u128, b: u128, output_digits: usize, ref expected: MPNat) { - let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); - let mut y = MPNatTrait::from_big_endian(b.to_be_bytes_padded()); - - let mut out = Felt252VecImpl::new(); - out.expand(output_digits).unwrap(); - - big_wrapping_mul(ref x, ref y, ref out); - let mut result = MPNat { digits: out }; - - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - fn check_big_sq(a: u128, ref expected: MPNat) { - let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); - let mut out = Felt252VecImpl::new(); - out.expand(2 * x.digits.len() + 1).unwrap(); - - big_sq(ref x, ref out); - - let mut result = MPNat { digits: out }; - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - #[test] - fn test_monsq_alpha() { - let mut x = Felt252VecImpl::new(); - x.push(0xf72fc634c83435bc); - x.push(0xa6b0ce70ac511873); - let mut x = MPNat { digits: x }; - - let mut y = Felt252VecImpl::new(); - y.push(0xf3e77eceb2ecfce5); - y.push(0xc4550871a1cfc67a); - let mut y = MPNat { digits: y }; - - let n_prime = 0xa51080a4eb8b9f13; - let mut scratch = Felt252VecImpl::new(); - scratch.expand(5).unwrap(); - - monsq(ref x, ref y, n_prime, ref scratch); - } - - - #[test] - fn test_monsq_0() { - check_monsq(1, 31); - } - - #[test] - fn test_monsq_1() { - check_monsq(6, 31); - } - - #[test] - fn test_monsq_2() { - // This example is intentionally chosen because 5 * 5 = 25 = 0 mod 25, - // therefore it requires the final subtraction step in the algorithm. - check_monsq(5, 25); - } - - #[test] - fn test_monsq_3() { - check_monsq(0x1FFF_FFFF_FFFF_FFF0, 0x1FFF_FFFF_FFFF_FFF1); - } - - #[test] - fn test_monsq_4() { - check_monsq(0x16FF_221F_CB7D, 0x011E_842B_6BAA_5017_EBF2_8293); - } - - #[test] - fn test_monsq_5() { - check_monsq(0x0A2D_63F5_CFF9, 0x1F3B_3BD9_43EF); - } - - #[test] - fn test_monsq_6() { - check_monsq(0xa6b0ce71a380dea7c83435bc, 0xc4550871a1cfc67af3e77eceb2ecfce5,); - } - - #[test] - fn test_monpro_0() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(2); - let mut expected = MPNat { digits: expected_digits }; - - check_monpro(1, 1, 31, ref expected); - } - - #[test] - fn test_monpro_1() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(22); - let mut expected = MPNat { digits: expected_digits }; - - check_monpro(6, 7, 31, ref expected); - } - - #[test] - fn test_monpro_2() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(0); - let mut expected = MPNat { digits: expected_digits }; - - // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, - // therefore it requires the final subtraction step in the algorithm. - check_monpro(5, 7, 35, ref expected); - } - - #[test] - fn test_monpro_3() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(384307168202282284); - - let mut expected = MPNat { digits: expected_digits }; - - // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, - // therefore it requires the final subtraction step in the algorithm. - check_monpro(0x1FFF_FFFF_FFFF_FFF0, 0x1234, 0x1FFF_FFFF_FFFF_FFF1, ref expected); - } - - #[test] - fn test_monpro_4() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(0); - let mut expected = MPNat { digits: expected_digits }; - - // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, - // therefore it requires the final subtraction step in the algorithm. - check_monpro( - 0x16FF_221F_CB7D, 0x0C75_8535_434F, 0x011E_842B_6BAA_5017_EBF2_8293, ref expected - ); - } - - #[test] - fn test_monpro_5() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(4425093052866); - let mut expected = MPNat { digits: expected_digits }; - - // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, - // therefore it requires the final subtraction step in the algorithm. - check_monpro(0x0A2D_63F5_CFF9, 0x1B21_FF3C_FA8E, 0x1F3B_3BD9_43EF, ref expected); - } - - #[test] - fn test_r_mod_n_0() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0x01_00_00_00_01, ref expected); - } - - #[test] - fn test_r_mod_n_1() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(549722259457); - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0x80_00_00_00_01, ref expected); - } - - #[test] - fn test_r_mod_n_2() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0xFFFF_FFFF_FFFF_FFFF, ref expected); - } - - #[test] - fn test_r_mod_n_3() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0x0001_0000_0000_0000_0001, ref expected); - } - - #[test] - fn test_r_mod_n_4() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(18446181123756130305); - expected_digits.push(32767); - - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0x8000_0000_0000_0000_0001, ref expected); - } - - #[test] - fn test_r_mod_n_5() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(3491005389787767287); - expected_digits.push(2668502225); - - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0xbf2d_c9a3_82c5_6e85_b033_7651, ref expected); - } - - #[test] - fn test_r_mod_n_6() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(4294967296); - - let mut expected = MPNat { digits: expected_digits }; - - check_r_mod_n(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ref expected); - } - - #[test] - fn test_in_place_shl() { - check_in_place_shl(0, 0); - check_in_place_shl(1, 10); - check_in_place_shl(WORD_MAX.into(), 5); - check_in_place_shl(DOUBLE_WORD_MAX.into(), 16); - } - - #[test] - fn test_in_place_shr() { - check_in_place_shr(0, 0); - check_in_place_shr(1, 10); - check_in_place_shr(0x1234_5678, 10); - check_in_place_shr(WORD_MAX.into(), 5); - check_in_place_shr(DOUBLE_WORD_MAX, 16); - } - - #[test] - #[available_gas(10000000000000)] - fn test_mod_inv_0() { - let mut i = 1; - loop { - if i == 1025 { - break; - }; - - check_mod_inv(2 * i - 1); - i += 1; - } - } - - #[test] - #[available_gas(10000000000000)] - fn test_mod_inv_1() { - let mut i = 0; - loop { - if i == 1025 { - break; - }; - - check_mod_inv(0xFF_FF_FF_FF - 2 * i); - i += 1; - } - } - - #[test] - fn test_big_wrapping_pow_0() { - let expected_bytes: Span = [1].span(); - check_big_wrapping_pow(1, 1, expected_bytes); - } - - #[test] - fn test_big_wrapping_pow_1() { - let expected_bytes: Span = [100].span(); - - check_big_wrapping_pow(10, 2, expected_bytes); - } - - #[test] - fn test_big_wrapping_pow_2() { - let expected_bytes: Span = [1, 0, 0, 0, 0].span(); - - check_big_wrapping_pow(2, 32, expected_bytes); - } - - #[test] - fn test_big_wrapping_pow_3() { - let expected_bytes: Span = [1, 0, 0, 0, 0, 0, 0, 0, 0].span(); - check_big_wrapping_pow(2, 64, expected_bytes); - } - - #[test] - #[available_gas(10000000000000)] - fn test_big_wrapping_pow_4() { - let expected_bytes: Span = [ - 3, - 218, - 116, - 252, - 230, - 21, - 167, - 46, - 59, - 185, - 199, - 194, - 149, - 140, - 133, - 157, - 60, - 102, - 160, - 27, - 104, - 79, - 16, - 104, - 20, - 104, - 116, - 207, - 214, - 100, - 237, - 159, - 0, - 245, - 249, - 156, - 52, - 33, - 217, - 113, - 130, - 6, - 65, - 78, - 49, - 141, - 141, - 160, - 29, - 125, - 168, - 236, - 88, - 174, - 146, - 81, - 137, - 165, - 242, - 90, - 251, - 115, - 144, - 169, - 141, - 66, - 207, - 230, - 56, - 199, - 140, - 109, - 7, - 99, - 35, - 155, - 88, - 29, - 90, - 192, - 55, - 127, - 112, - 26, - 176, - 181, - 13, - 72, - 107, - 209, - 1, - 210, - 88, - 233, - 185, - 87, - 108, - 122, - 168, - 137, - 255, - 36, - 201, - 185, - 31, - 36, - 51, - 208, - 64, - 154, - 113, - 233, - 71, - 95, - 35, - 253, - 0, - 3, - 159, - 183, - 10, - 83, - 233, - 88, - 96, - 19, - 104, - 229, - 132, - 73, - 219, - 152, - 126, - 215, - 249, - 46, - 110, - 157, - 234, - 2, - 100, - 178, - 150, - 110, - 217, - 246, - 128, - 219, - 121, - 21, - 234, - 55, - 101, - 81, - 207, - 191, - 200, - 201, - 2, - 40, - 13, - 80, - 107, - 226, - 143, - 164, - 254, - 91, - 54, - 46, - 254, - 7, - 14, - 136, - 149, - 194, - 6, - 191, - 14, - 49, - 140, - 193, - 40, - 1, - 138, - 165, - 82, - 34, - 33, - 169, - 41, - 136, - 130, - 47, - 84, - 173, - 58, - 121, - 192, - 247, - 98, - 237, - 165, - 215, - 161, - 198, - 87, - 228, - 76, - 160, - 66, - 78, - 169, - 139, - 234, - 169, - 83, - 15, - 16, - 192, - 170, - 71, - 227, - 232, - 116, - 189, - 81, - 64, - 104, - 182, - 129, - 203, - 191, - 210, - 151, - 132, - 254, - 239, - 19, - 138, - 49, - 113, - 140, - 77, - 38, - 49, - 117, - 127, - 203, - 123, - 127, - 49, - 32, - 61, - 108, - 120, - 133, - 119, - 8, - 232, - 84, - 57, - 103, - 197, - 160, - 65, - 191, - 82, - 253, - 60, - 191, - 209, - 63, - 176, - 43, - 33, - 54, - 75, - 17, - 73, - 222, - 198, - 80, - 5, - 14, - 50, - 117, - 156, - 77, - 147, - 190, - 230, - 143, - 47, - 149, - 180, - 203, - 144, - 202, - 102, - 231, - 2, - 91, - 22, - 101, - 178, - 211, - 233, - 109, - 156, - 72, - 151, - 199, - 189, - 90, - 76, - 21, - 112, - 21, - 2, - 44, - 96, - 42, - 141, - 217, - 142, - 23, - 75, - 248, - 209, - 26, - 3, - 198, - 103, - 227, - 103, - 140, - 99, - 75, - 211, - 152, - 109, - 19, - 72, - 6, - 116, - 67, - 70, - 32, - 45, - 5, - 113, - 179, - 252, - 2, - 202, - 115, - 244, - 68, - 128, - 156, - 233, - 227, - 211, - 5, - 146, - 147, - 186, - 34, - 3, - 105, - 147, - 64, - 79, - 172, - 141, - 14, - 60, - 69, - 249, - 169, - 76, - 252, - 84, - 151, - 49, - 81, - 246, - 185, - 181, - 181, - 226, - 28, - 152, - 30, - 47, - 248, - 103, - 21, - 184, - 140, - 193, - 112, - 139, - 250, - 206, - 35, - 180, - 122, - 32, - 151, - 105, - 30, - 193, - 68, - 232, - 170, - 174, - 254, - 143, - 29, - 165, - 194, - 14, - 164, - 35, - 25, - 250, - 86, - 76, - 213, - 159, - 21, - 0, - 212, - 146, - 21, - 8, - 180, - 73, - 250, - 116, - 137, - 221, - 20, - 22, - 146, - 169, - 120, - 166, - 229, - 226, - 136, - 201, - 177, - 49, - 21, - 228, - 191, - 246, - 26, - 36, - 183, - 175, - 137, - 71, - 4, - 46, - 235, - 197, - 99, - 0, - 142, - 97, - 184, - 34, - 84, - 254, - 41, - 95, - 198, - 178, - 48, - 105, - 215, - 72, - 155, - 238, - 51, - 164, - 52, - 179, - 126, - 254, - 100, - 35, - 236, - 63, - 215, - 238, - 217, - 239, - 229, - 160, - 192, - 33, - 82, - 165, - 81, - 149, - 186, - 53, - 109, - 184, - 187, - 186, - 8, - 43, - 249, - 20, - 37, - 255, - 241, - 18, - 61, - 97, - 229, - 29, - 201, - 144, - 92, - 202, - 215, - 161, - 165, - 133, - 89, - 180, - 246, - 37, - 16, - 133, - 226, - 209, - 23, - 61, - 241, - 25, - 9, - 150, - 154, - 150, - 133, - 210, - 62, - 115, - 34, - 201, - 187, - 217, - 3, - 82, - 102, - 174, - 233, - 33, - 31, - 7, - 4, - 88, - 70, - 173, - 157, - 111, - 96, - 102, - 223, - 157, - 224, - 158, - 235, - 191, - 55, - 219, - 218, - 146, - 233, - 242, - 250, - 170, - 100, - 68, - 37, - 56, - 251, - 109, - 112, - 217, - 209, - 46, - 229, - 198, - 198, - 156, - 198, - 70, - 76, - 131, - 79, - 40, - 25, - 176, - 21, - 43, - 31, - 121, - 204, - 225, - 128, - 182, - 191, - 148, - 72, - 22, - 112, - 63, - 223, - 182, - 155, - 177, - 183, - 72, - 111, - 6, - 196, - 250, - 189, - 45, - 97, - 182, - 14, - 219, - 189, - 50, - 226, - 91, - 1, - 86, - 95, - 131, - 120, - 224, - 0, - 71, - 28, - 151, - 69, - 24, - 93, - 82, - 237, - 136, - 103, - 90, - 247, - 173, - 204, - 121, - 199, - 17, - 164, - 80, - 49, - 183, - 10, - 200, - 235, - 56, - 72, - 72, - 147, - 150, - 223, - 110, - 165, - 60, - 13, - 251, - 42, - 193, - 78, - 212, - 166, - 178, - 103, - 19, - 35, - 69, - 10, - 137, - 62, - 13, - 90, - 203, - 126, - 203, - 207, - 190, - 184, - 89, - 118, - 186, - 203, - 6, - 115, - 158, - 168, - 35, - 206, - 227, - 48, - 221, - 252, - 190, - 166, - 249, - 96, - 92, - 244, - 77, - 213, - 119, - 44, - 207, - 17, - 16, - 118, - 104, - 106, - 188, - 205, - 5, - 240, - 14, - 181, - 227, - 4, - 11, - 32, - 91, - 224, - 78, - 175, - 49, - 19, - 12, - 233, - 131, - 141, - 47, - 32, - 14, - 195, - 214, - 77, - 158, - 39, - 114, - 167, - 37, - 16, - 249, - 73, - 167, - 230, - 165, - 19, - 4, - 199, - 227, - 251, - 184, - 131, - 137, - 74, - 176, - 116, - 35, - 182, - 121, - 62, - 114, - 64, - 163, - 84, - 208, - 111, - 56, - 191, - 88, - 130, - 64, - 64, - 181, - 162, - 53, - 34, - 16, - 179, - 155, - 137, - 138, - 101, - 121, - 73, - 234, - 189, - 100, - 141, - 122, - 123, - 79, - 200, - 90, - 208, - 83, - 253, - 124, - 125, - 116, - 72, - 138, - 63, - 42, - 144, - 200, - 73, - 233, - 113, - 143, - 85, - 140, - 16, - 240, - 230, - 42, - 114, - 137, - 193, - 10, - 129, - 124, - 193, - 104, - 177, - 55, - 156, - 173, - 135, - 168, - 217, - 1, - 46, - 41, - 132, - 17, - 222, - 178, - 226, - 24, - 108, - 117, - 199, - 171, - 232, - 129, - 82, - 225, - 214, - 105, - 94, - 188, - 72, - 62, - 91, - 193, - 188, - 18, - 33, - 131, - 18, - 194, - 70, - 151, - 187, - 42, - 5, - 62, - 85, - 38, - 134, - 252, - 183, - 227, - 120, - 19, - 152, - 243, - 235, - 114, - 208, - 78, - 57, - 113, - 217, - 182, - 125, - 195, - 64, - 229, - 232, - 54, - 118, - 11, - 119, - 163, - 235, - 12, - 67, - 90, - 246, - 76, - 219, - 200, - 124, - 234, - 41, - 172, - 31, - 167, - 213, - 127, - 100, - 163, - 72, - 44, - 107, - 171, - 229, - 189, - 68, - 201, - 244, - 154, - 27, - 172, - 228, - 234, - 192, - 156, - 127, - 170, - 9, - 78, - 166, - 249, - 154, - 178, - 179, - 172, - 220, - 205, - 220, - 60, - 86, - 98, - 134, - 60, - 134, - 89, - 244, - 187, - 231, - 128, - 6, - 109, - 152, - 251, - 44, - 208, - 238, - 169, - 71, - 51, - 192, - 242, - 57, - 8, - 62, - 206, - 94, - 94, - 25, - 220, - 160, - 175, - 35, - 113, - 66, - 42, - 134, - 241, - 57, - 253, - 44, - 244, - 163, - 158, - 152, - 147, - 79, - 142, - 190, - 139, - 222, - 202, - 216, - 220, - 47, - 179, - 207, - 199, - 104, - 1, - 21, - 106, - 142, - 188, - 105, - 247, - 111, - 202, - 78, - 145, - 66, - 216, - 222, - 96, - 138, - 133, - 28, - 235, - 204, - 100, - 183, - 232, - 65, - 138, - 196, - 133, - 23, - 154, - 0, - 187, - 252, - 32, - 106, - 76, - 94, - 129, - 173, - 13, - 79, - 167, - 103, - 54, - 51, - 102, - 224, - 231, - 159, - 127, - 54, - 131, - 122, - 65, - 83, - 195, - 9, - 175, - 45, - 179, - 32, - 118, - 230, - 101, - 85, - 13, - 85, - 234, - 26, - 16, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ].span(); - check_big_wrapping_pow(2766, 844, expected_bytes); - } - - #[test] - fn test_big_wrapping_mul_0() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(0); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(0, 0, 1, ref expected); - } - - - #[test] - fn test_big_wrapping_mul_1() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(1, 1, 1, ref expected); - } - - #[test] - fn test_big_wrapping_mul_2() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(42); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(7, 6, 1, ref expected); - } - - #[test] - fn test_big_wrapping_mul_3() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - expected_digits.push(18446744073709551614); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(WORD_MAX.into(), WORD_MAX.into(), 2, ref expected); - } - - #[test] - fn test_big_wrapping_mul_4() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(WORD_MAX.into(), WORD_MAX.into(), 1, ref expected); - } - - #[test] - fn test_big_wrapping_mul_5() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(42); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(DOUBLE_WORD_MAX - 5, DOUBLE_WORD_MAX - 6, 2, ref expected); - } - - #[test] - fn test_big_wrapping_mul_6() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(6727192404480162174); - expected_digits.push(3070707315540124665); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul(0xa945_aa5e_429a_6d1a, 0x4072_d45d_3355_237b, 3, ref expected); - } - - #[test] - fn test_big_wrapping_mul_7() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(2063196614268007784); - expected_digits.push(7048986299143829482); - expected_digits.push(14065833420641261004); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_wrapping_mul( - 0x8ae1_5515_fc92_b1c0_b473_8ce8_6bbf_7218, - 0x43e9_8b77_1f7c_aa93_6c4c_85e9_7fd0_504f, - 3, - ref expected - ); - } - - #[test] - fn test_big_sq_0() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(0); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0, ref expected); - } - - #[test] - fn test_big_sq_1() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(1, ref expected); - } - - #[test] - fn test_big_sq_2() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - expected_digits.push(18446744073709551614); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(WORD_MAX.into(), ref expected); - } - - #[test] - fn test_big_sq_3() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(4); - expected_digits.push(18446744073709551608); - expected_digits.push(3); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(2 * WORD_MAX.into(), ref expected); - } - - #[test] - fn test_big_sq_4() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(0); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0, ref expected); - } - - #[test] - fn test_big_sq_5() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(2532367871917050473); - expected_digits.push(16327525306720758713); - expected_digits.push(15087745550001425684); - expected_digits.push(5708046406239628566); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0x8e67904953db9a2bf6da64bf8bda866d, ref expected); - } - - - #[test] - fn test_big_sq_6() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(15092604974397072849); - expected_digits.push(3791921091882282235); - expected_digits.push(12594445234582458012); - expected_digits.push(7165619740963215273); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0x9f8dc1c3fc0bf50fe75ac3bbc03124c9, ref expected); - } - - #[test] - fn test_big_sq_7() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(5163998055150312593); - expected_digits.push(8460506958278925118); - expected_digits.push(17089393176389340230); - expected_digits.push(6902937458884066534); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0x9c9a17378f3d064e5eaa80eeb3850cd7, ref expected); - } - - - #[test] - fn test_big_sq_8() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(2009857620356723108); - expected_digits.push(5657228334642978155); - expected_digits.push(88889113116670247); - expected_digits.push(12075559273075793199); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(0xcf2025cee03025d247ad190e9366d926, ref expected); - } - - #[test] - fn test_big_sq_9() { - let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); - expected_digits.push(1); - expected_digits.push(0); - expected_digits.push(18446744073709551614); - expected_digits.push(18446744073709551615); - - let mut expected = MPNat { digits: expected_digits }; - - check_big_sq(DOUBLE_WORD_MAX, ref expected); - } - - // Test for addition overflows in the big_sq inner loop */ - #[test] - fn test_big_sq_10() { - let mut x = MPNatTrait::from_big_endian( - [ - 0xff, - 0xff, - 0xff, - 0xff, - 0x80, - 0x00, - 0x00, - 0x00, - 0x80, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0x80, - 0x00, - 0x00, - 0x00, - ].span() - ); - - let mut out = Felt252VecImpl::new(); - out.expand(2 * x.digits.len() + 1).unwrap(); - - big_sq(ref x, ref out); - let mut result = MPNat { digits: out }; - - let mut expected = MPNatTrait::from_big_endian( - [ - 0xff, - 0xff, - 0xff, - 0xff, - 0x00, - 0x00, - 0x00, - 0x01, - 0x40, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0xff, - 0xff, - 0xff, - 0xfe, - 0x40, - 0x00, - 0x00, - 0x01, - 0x90, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xbf, - 0xff, - 0xff, - 0xff, - 0x00, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - ].span() - ); - - assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); - } - - #[test] - fn test_borrowing_sub() { - assert_eq!(borrowing_sub(0, 0, false), (0, false)); - assert_eq!(borrowing_sub(1, 0, false), (1, false)); - assert_eq!(borrowing_sub(47, 5, false), (42, false)); - assert_eq!(borrowing_sub(101, 7, true), (93, false)); - assert_eq!(borrowing_sub(0x00_00_01_00, 0x00_00_02_00, false), (WORD_MAX - 0xFF, true)); - assert_eq!(borrowing_sub(0x00_00_01_00, 0x00_00_10_00, true), (WORD_MAX - 0x0F_00, true)); - } - - - #[test] - fn test_shifted_carrying_mul() { - assert_eq!(shifted_carrying_mul(0, 0, 0, 0), (0, 0)); - assert_eq!(shifted_carrying_mul(0, 6, 7, 0), (42, 0)); - assert_eq!(shifted_carrying_mul(0, 6, 7, 8), (50, 0)); - assert_eq!(shifted_carrying_mul(5, 6, 7, 8), (55, 0)); - assert_eq!( - shifted_carrying_mul( - WORD_MAX - 0x11, WORD_MAX - 0x1234, WORD_MAX - 0xABCD, WORD_MAX - 0xFF - ), - (0x0C_38_0C_94, WORD_MAX - 0xBE00) - ); - assert_eq!( - shifted_carrying_mul(WORD_MAX, WORD_MAX, WORD_MAX, WORD_MAX), (WORD_MAX, WORD_MAX) - ); - } -} diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo deleted file mode 100644 index a904bf8af..000000000 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo +++ /dev/null @@ -1,19 +0,0 @@ -// CREDITS: The implementation has been take from -// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) - -use crate::crypto::modexp::mpnat::MPNatTrait; -use crate::felt_vec::{Felt252VecTrait}; - -/// Computes `(base ^ exp) % modulus`, where all values are given as big-endian -/// encoded bytes. -pub fn modexp(base: Span, exp: Span, modulus: Span) -> Span { - let mut x = MPNatTrait::from_big_endian(base); - let mut m = MPNatTrait::from_big_endian(modulus); - - if m.digits.len == 1 && m.digits[0] == 0 { - return [].span(); - } - - let mut result = x.modpow(exp, ref m); - result.digits.to_be_bytes() -} diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo deleted file mode 100644 index 2fdefeca3..000000000 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo +++ /dev/null @@ -1,1033 +0,0 @@ -// CREDITS: The implementation has been take from -// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) -use alexandria_data_structures::vec::VecTrait; -use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; -use core::array::SpanTrait; -use core::num::traits::CheckedMul; -use core::option::OptionTrait; -use core::result::ResultTrait; -use crate::felt_vec::{Felt252VecTrait}; -use crate::math::Bitshift; -use crate::traits::bytes::FromBytes; -use crate::traits::integer::{U64Trait, U128Trait, BitsUsed, ByteSize}; - -use super::arith::{ - big_wrapping_pow, mod_inv, compute_r_mod_n, join_as_double, in_place_shl, in_place_shr, - in_place_add, in_place_mul_sub, big_wrapping_mul, monsq, monpro, borrowing_sub, carrying_add -}; - -pub type Word = u64; -pub type DoubleWord = u128; -pub const WORD_BYTES: usize = 8; -pub const WORD_BITS: usize = 64; -pub const WORD_MAX: Word = 18446744073709551615; -// 2**64 -pub const BASE: DoubleWord = 18446744073709551616; -pub const DOUBLE_WORD_MAX: DoubleWord = 340282366920938463463374607431768211455; -/// Multi-precision natural number, represented in base `Word::MAX + 1 = 2^WORD_BITS`. -/// The digits are stored in little-endian order, i.e. digits[0] is the least -/// significant digit. -#[derive(Destruct)] -pub struct MPNat { - pub digits: Felt252Vec -} - - -#[generate_trait] -pub impl MPNatTraitImpl of MPNatTrait { - fn from_big_endian(bytes: Span) -> MPNat { - if bytes.is_empty() { - let mut digits = Default::default(); - digits.expand(1).unwrap(); - return MPNat { digits }; - } - - // Remainder on division by WORD_BYTES - let r = bytes.len() & (WORD_BYTES - 1); - let n_digits: usize = if r == 0 { - bytes.len() / WORD_BYTES - } else { - // Need an extra digit for the remainder - (bytes.len() / WORD_BYTES) + 1 - }; - - let mut digits: Felt252Vec = Felt252VecImpl::new(); - // safe unwrap, since n_digits >= 0; - digits.expand(n_digits).unwrap(); - - // buffer to hold Word-sized slices of the input bytes - // TODO: optimize, see if we can avoid using this Felt252Vec - let mut buf: Felt252Vec = Felt252VecImpl::new(); - // safe unwrap, since WORD_BYTES > 0 - buf.expand(WORD_BYTES).unwrap(); - - let mut i = n_digits - 1; - if r != 0 { - // safe unwrap, since we know index is in bound + no overflow - buf.copy_from_bytes_le((WORD_BYTES - r), bytes.slice(0, r)).unwrap(); - - // safe unwrap, since we know that bytes won't overflow - let word = buf.to_le_bytes().from_be_bytes().expect('mpnat_from_big_endian_word'); - digits.set(i, word); - - if i == 0 { - // Special case where there is just one digit - return MPNat { digits }; - } - - i -= 1; - }; - - let mut j = r; - loop { - let next_j = j + WORD_BYTES; - // safe unwrap, since we know index is in bound + no overflow - buf.copy_from_bytes_le(0, bytes.slice(j, next_j - j)).unwrap(); - - // safe unwrap, since we know that bytes won't overflow - let word: u64 = buf.to_le_bytes().from_be_bytes().expect('mpnat_from_big_endian_word'); - digits.set(i, word); - - if i == 0 { - break; - } - - i -= 1; - j = next_j; - }; - - digits.remove_trailing_zeroes(); - - if digits.len() == 0 { - digits.expand(1).unwrap(); - } - - MPNat { digits } - } - - /// Makes `self` have the same number of digits as `other` by - /// pushing 0s or dropping higher order digits as needed. - /// This is equivalent to reducing `self` modulo `2^(WORD_BITS*k)` where - /// `k` is the number of digits in `other`. - fn sub_to_same_size(ref self: MPNat, ref other: MPNat) { - self.digits.remove_trailing_zeroes(); - if (self.digits.len() == 0) { - self.digits.expand(1).unwrap(); - } - - let n = other.digits.len(); - let s = self.digits.len(); - let m = if n >= s { - return; - } else { - s - n - }; - - let other_most_sig: DoubleWord = other.digits[other.digits.len() - 1].into(); - - if self.digits.len() == 2 { // This is the smallest case since `n >= 1` and `m > 0` - // implies that `self.digits.len() >= 2`. - // In this case we can use DoubleWord-sized arithmetic - // to get the answer directly. - let self_most_sig = self.digits.pop().unwrap(); - let a = join_as_double(self_most_sig, self.digits[0]); - let b = other_most_sig; - self.digits.set(0, (a % b).as_u64()); - return; - }; - - if n == 1 { - // The divisor is only 1 digit, so the long-division - // algorithm is easy. - let k = self.digits.len() - 1; - let mut i = k; - loop { - if i == 0 { - break; - }; - - i -= 1; - - let self_most_sig = self.digits.pop().unwrap(); - let self_second_sig = self.digits[i]; - let r = join_as_double(self_most_sig, self_second_sig) % other_most_sig; - self.digits.set(i, r.as_u64()); - }; - - return; - } - - // At this stage we know that `n >= 2` and `self.digits.len() >= 3`. - // The smaller cases are covered in the if-statements above. - - // The algorithm below only works well when the divisor's - // most significant digit is at least `BASE / 2`. - // If it is too small then we "normalize" by multiplying - // both numerator and denominator by a common factor - // and run the algorithm on those numbers. - // See Knuth The Art of Computer Programming vol. 2 section 4.3 for details. - let shift: u32 = other_most_sig.as_u64().count_leading_zeroes().into(); - if shift > 0 { - // Normalize self - let overflow = in_place_shl(ref self.digits, shift); - self.digits.push(overflow); - - // Normalize other - let mut normalized = other.digits.duplicate(); - in_place_shl(ref normalized, shift); - - let mut v = MPNat { digits: normalized }; - // Run algorithm on normalized values - self.sub_to_same_size(ref v); - - // need to de-normalize to get the correct result - in_place_shr(ref self.digits, shift); - - return; - }; - - let other_second_sig: DoubleWord = other.digits[n - 2].into(); - let mut self_most_sig: Word = 0; - - let mut j = m + 1; - - loop { - if j == 0 { - break; - } - - j -= 1; - - let self_second_sig = self.digits[self.digits.len() - 1]; - let self_third_sig = self.digits[self.digits.len() - 2]; - - let a = join_as_double(self_most_sig, self_second_sig); - let mut q_hat = a / other_most_sig; - let mut r_hat = a % other_most_sig; - - loop { - let a = q_hat * other_second_sig; - let b = join_as_double(r_hat.as_u64(), self_third_sig); - if q_hat >= BASE || a > b { - q_hat -= 1; - r_hat += other_most_sig; - if BASE <= r_hat { - break; - } - } else { - break; - } - }; - - //TODO: optimize with [#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) - let mut a = self.digits.clone_slice(j, self.digits.len() - j); - - let mut borrow = in_place_mul_sub(ref a, ref other.digits, q_hat.as_u64()); - self.digits.insert_vec(j, ref a).unwrap(); - if borrow > self_most_sig { - // q_hat was too large, add back one multiple of the modulus - //TODO: optimize with [#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) - let mut a = self.digits.clone_slice(j, self.digits.len() - j); - in_place_add(ref a, ref other.digits); - self.digits.insert_vec(j, ref a).unwrap(); - borrow -= 1; - } - - self_most_sig = self.digits.pop().unwrap(); - }; - - self.digits.push(self_most_sig); - } - - fn is_power_of_two(ref self: MPNat) -> bool { - // A multi-precision number is a power of 2 iff exactly one digit - // is a power of 2 and all others are zero. - - let mut found_power_of_two = false; - - let mut i = 0; - loop { - if i == self.digits.len() { - break found_power_of_two; - } - - let d = self.digits[i]; - let is_p2 = if d != 0 { - (d & (d - 1)) == 0 - } else { - false - }; - - if ((!is_p2 && d != 0) || (is_p2 && found_power_of_two)) { - break false; - } else if is_p2 { - found_power_of_two = true; - } - - i += 1; - } - } - - fn is_odd(ref self: MPNat) -> bool { - // when the value is 0 - if self.digits.len() == 0 { - return false; - }; - - // A binary number is odd iff its lowest order bit is set. - self.digits[0] & 1 == 1 - } - - // KoƧ's algorithm for inversion mod 2^k - // https://eprint.iacr.org/2017/411.pdf - fn koc_2017_inverse(ref aa: MPNat, k: usize) -> MPNat { - let length = k / WORD_BITS; - let mut digits = Felt252VecImpl::new(); - digits.expand(length + 1).unwrap(); - let mut b = MPNat { digits }; - - b.digits.set(0, 1); - - let mut a = MPNat { digits: aa.digits.duplicate(), }; - a.digits.resize(length + 1); - - let mut neg: bool = false; - - let mut digits = Felt252VecImpl::new(); - digits.expand(length + 1).unwrap(); - let mut res = MPNat { digits }; - - let (mut wordpos, mut bitpos) = (0, 0); - - let mut i = 0; - loop { - if i == k { - break; - } - - let x = b.digits[0] & 1; - if x != 0 { - if !neg { - // b = a - b - //TODO: optimize with - //[#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) - let mut tmp = MPNat { digits: a.digits.duplicate(), }; - in_place_mul_sub(ref tmp.digits, ref b.digits, 1); - b = tmp; - neg = true; - } else { - // b = b - a - in_place_add(ref b.digits, ref a.digits); - } - } - - in_place_shr(ref b.digits, 1); - - res.digits.set(wordpos, res.digits[wordpos] | (x.shl(bitpos))); - - bitpos += 1; - if bitpos == WORD_BITS { - bitpos = 0; - wordpos += 1; - } - - i += 1; - }; - - res - } - - - /// Computes `self ^ exp mod modulus`. `exp` must be given as big-endian bytes. - fn modpow(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { - // exp must be stripped because it is iterated over in - // big_wrapping_pow and modpow_montgomery, and a large - // zero-padded exp leads to performance issues. - let (exp, exp_is_zero) = Self::strip_leading_zeroes(exp); - - // base^0 is always 1, regardless of base. - // Hence the result is 0 for (base^0) % 1, and 1 - // for every modulus larger than 1. - // - // The case of modulus being 0 should have already been - // handled in modexp(). - if exp_is_zero { - if modulus.digits.len() == 1 && modulus.digits[0] == 1 { - let mut digits = Felt252VecImpl::new(); - digits.expand(1).unwrap(); - - return MPNat { digits }; - } else { - let mut digits = Felt252VecImpl::new(); - digits.push(1); - - return MPNat { digits }; - } - } - - if exp.len() <= (ByteSize::::byte_size()) { - let exp_as_number: usize = exp.from_le_bytes_partial().expect('modpow_exp_as_number'); - - match self.digits.len().checked_mul(exp_as_number) { - Option::Some(max_output_digits) => { - if (modulus.digits.len() > max_output_digits) { - // Special case: modulus is larger than `base ^ exp`, so division is not - // relevant - let mut scratch_space: Felt252Vec = Felt252VecImpl::new(); - scratch_space.expand(max_output_digits).unwrap(); - - return big_wrapping_pow(ref self, exp, ref scratch_space); - } - }, - Option::None => {} - }; - } - - if modulus.is_power_of_two() { // return - return self.modpow_with_power_of_two(exp, ref modulus); - } else if modulus.is_odd() { - return self.modpow_montgomery(exp, ref modulus); - } - - // If the modulus is not a power of two and not an odd number then - // it is a product of some power of two with an odd number. In this - // case we will use the Chinese remainder theorem to get the result. - // See http://www.people.vcu.edu/~jwang3/CMSC691/j34monex.pdf - - let trailing_zeros = modulus.digits.count_leading_zeroes(); - let additional_zero_bits: usize = modulus - .digits[trailing_zeros] - .count_trailing_zeroes() - .into(); - - let mut power_of_two = { - let mut digits = Felt252VecImpl::new(); - digits.expand(trailing_zeros + 1).unwrap(); - let mut tmp = MPNat { digits }; - tmp.digits.set(trailing_zeros, 1_u64.shl(additional_zero_bits)); - tmp - }; - - let power_of_two_mask = power_of_two.digits[power_of_two.digits.len() - 1] - 1; - let mut odd = { - let num_digits = modulus.digits.len() - trailing_zeros; - let mut digits = Felt252VecImpl::new(); - digits.expand(num_digits).unwrap(); - let mut tmp = MPNat { digits }; - if additional_zero_bits > 0 { - tmp.digits.set(0, modulus.digits[trailing_zeros].shr(additional_zero_bits)); - let mut i = 1; - loop { - if i == num_digits { - break; - } - - let d = modulus.digits[trailing_zeros + i]; - tmp - .digits - .set( - i - 1, - tmp.digits[i - - 1] - + (d & power_of_two_mask).shl(WORD_BITS - additional_zero_bits) - ); - tmp.digits.set(i, d.shr(additional_zero_bits)); - - i += 1; - }; - } else { - // TODO: explore if we can avoid this clone and just use a copy to avoid deep - // cloning - let mut slice = modulus - .digits - .clone_slice(trailing_zeros, modulus.digits.len() - trailing_zeros); - tmp.digits.insert_vec(0, ref slice).unwrap(); - } - if tmp.digits.len() > 0 { - loop { - if tmp.digits[tmp.digits.len() - 1] != 0 { - break; - }; - - tmp.digits.pop().unwrap(); - }; - }; - tmp - }; - - let mut base_copy = MPNat { digits: self.digits.duplicate(), }; - let mut x1 = base_copy.modpow_montgomery(exp, ref odd); - let mut x2 = self.modpow_with_power_of_two(exp, ref power_of_two); - - let mut odd_inv = Self::koc_2017_inverse( - ref odd, trailing_zeros * WORD_BITS + additional_zero_bits - ); - - let s = power_of_two.digits.len(); - let mut scratch: Felt252Vec = Felt252VecImpl::new(); - scratch.expand(s).unwrap(); - - let mut diff = { - let mut b = false; - let mut i = 0; - loop { - if i == scratch.len() || i == s { - break; - } - - let (diff, borrow) = borrowing_sub( - x2.digits.get(i).unwrap_or(0), x1.digits.get(i).unwrap_or(0), b, - ); - - scratch.set(i, diff); - b = borrow; - - i += 1; - }; - - MPNat { digits: scratch } - }; - - let mut y = { - let mut out: Felt252Vec = Felt252VecImpl::new(); - out.expand(s).unwrap(); - big_wrapping_mul(ref diff, ref odd_inv, ref out); - - out.set(out.len() - 1, out[out.len() - 1] & power_of_two_mask); - MPNat { digits: out } - }; - - // Reuse allocation for efficiency - let mut digits = diff.digits; - let s = modulus.digits.len(); - digits.reset(); - digits.resize(s); - big_wrapping_mul(ref odd, ref y, ref digits); - let mut c = false; - - let mut i = 0; - loop { - if i == digits.len() { - break; - }; - - let out_digit = digits[i]; - - let (sum, carry) = carrying_add(x1.digits.get(i).unwrap_or(0), out_digit, c); - c = carry; - digits.set(i, sum); - - i += 1; - }; - - MPNat { digits } - } - - // Computes `self ^ exp mod modulus` using Montgomery multiplication. - // See https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf - fn modpow_montgomery(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { - // n_prime satisfies `r * (r^(-1)) - modulus * n' = 1`, where - // `r = 2^(WORD_BITS*modulus.digits.len())`. - let n_prime = WORD_MAX - mod_inv(modulus.digits[0]) + 1; - let s = modulus.digits.len; - - let mut digits = Felt252VecImpl::new(); - // safe unwrap, since initial length is 0; - digits.expand(s).unwrap(); - let mut x_bar = MPNat { digits }; - // Initialize result as `r mod modulus` (Montgomery form of 1) - compute_r_mod_n(ref modulus, ref x_bar.digits); - - // Reduce base mod modulus - self.sub_to_same_size(ref modulus); - - // Need to compute a_bar = base * r mod modulus; - // First directly multiply base * r to get a 2s-digit number, - // then reduce mod modulus. - let mut a_bar = { - let mut digits = Felt252VecImpl::new(); - digits.expand(2 * s).unwrap(); - let mut tmp = MPNat { digits }; - big_wrapping_mul(ref self, ref x_bar, ref tmp.digits); - - tmp.sub_to_same_size(ref modulus); - tmp - }; - - // scratch space for monpro algorithm - let mut scratch: Felt252Vec = Felt252VecImpl::new(); - scratch.expand(2 * s + 1).unwrap(); - let monpro_len = s + 2; - - let mut i = 0; - loop { - if i == exp.len() { - break; - } - - let b = *exp[i]; - - let mut mask: u8 = 128; - - loop { - if mask == 0 { - break; - }; - - monsq(ref x_bar, ref modulus, n_prime, ref scratch); - //TODO: optimize - let mut slice = scratch.clone_slice(0, s); - x_bar.digits.copy_from_vec_le(ref slice).unwrap(); - scratch.reset(); - - if b & mask != 0 { - let mut slice = scratch.clone_slice(0, monpro_len); - monpro(ref x_bar, ref a_bar, ref modulus, n_prime, ref slice); - scratch.insert_vec(0, ref slice).unwrap(); - - //TODO: optimize - let mut slice = scratch.clone_slice(0, s); - x_bar.digits.copy_from_vec_le(ref slice).unwrap(); - scratch.reset(); - } - mask = mask.shr(1); - }; - - i += 1; - }; - - // Convert out of Montgomery form by computing monpro with 1 - let mut one = { - // We'll reuse the memory space from a_bar for efficiency. - let mut digits = a_bar.digits; - digits.reset(); - digits.set(0, 1); - MPNat { digits } - }; - - let mut slice = scratch.clone_slice(0, monpro_len); - monpro(ref x_bar, ref one, ref modulus, n_prime, ref slice); - scratch.insert_vec(0, ref slice).unwrap(); - - scratch.resize(s); - MPNat { digits: scratch } - } - - fn modpow_with_power_of_two(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { - // We know `modulus` is a power of 2. So reducing is as easy as bit shifting. - // We also know the modulus is non-zero because 0 is not a power of 2. - - // First reduce self to be the same size as the modulus - self.force_same_size(ref modulus); - - // The modulus is a power of 2 but that power may not be a multiple of a whole word. - // We can clear out any higher order bits to fix this. - let modulus_mask = modulus.digits[modulus.digits.len() - 1] - 1; - self.digits.set(self.digits.len() - 1, self.digits[self.digits.len() - 1] & modulus_mask); - - // We know that `totient(2^k) = 2^(k-1)`, therefore by Euler's theorem - // we can also reduce the exponent mod `2^(k-1)`. Effectively this means - // throwing away bytes to make `exp` shorter. Note: Euler's theorem only applies - // if the base and modulus are coprime (which in this case means the base is odd). - let exp = if self.is_odd() && (exp.len() > WORD_BYTES * modulus.digits.len()) { - let i = exp.len() - WORD_BYTES * modulus.digits.len(); - exp.slice(i, exp.len() - i) - } else { - exp - }; - - let mut scratch_space = Felt252VecImpl::new(); - // safe unwrap, since the initial length is 0 - scratch_space.expand(modulus.digits.len()).unwrap(); - - let mut result = big_wrapping_pow(ref self, exp, ref scratch_space); - - // The modulus is a power of 2 but that power may not be a multiple of a whole word. - // We can clear out any higher order bits to fix this. - - result - .digits - .set(result.digits.len() - 1, result.digits[result.digits.len() - 1] & modulus_mask); - - result - } - - - /// Makes `self` have the same number of digits as `other` by - /// pushing 0s or dropping higher order digits as needed. - /// This is equivalent to reducing `self` modulo `2^(WORD_BITS*k)` where - /// `k` is the number of digits in `other`. - fn force_same_size(ref self: MPNat, ref other: MPNat) { - self.digits.resize(other.digits.len); - } - - /// stips leading zeroes from little endian bytes - /// # Arguments - /// * `input` a Span in little endian - /// # Returns - /// * (Span<8>, bool), where span is the resulting Span after removing leading zeroes, and the - /// boolean indicates if all bytes were zero - fn strip_leading_zeroes(mut v: Span) -> (Span, bool) { - loop { - let stripped_span = v; - match v.pop_front() { - Option::Some(v) => { if (*v != 0) { - break (stripped_span, false); - } }, - Option::None => { break (v, true); } - } - } - } -} - -pub fn mp_nat_to_u128(ref x: MPNat) -> u128 { - let result = x.digits.to_le_bytes(); - let mut i: usize = 0; - loop { - if i == result.len() { - break; - }; - - i += 1; - }; - result.from_le_bytes_partial().expect('mpnat_to_u128') -} - -#[cfg(test)] -mod tests { - use alexandria_data_structures::vec::Felt252VecImpl; - use alexandria_data_structures::vec::VecTrait; - use crate::crypto::modexp::mpnat::MPNatTrait; - use crate::math::{Bitshift, WrappingBitshift}; - use crate::traits::bytes::ToBytes; - use super::mp_nat_to_u128; - - // the tests are taken from - // [aurora-engine](https://github.com/aurora-is-near/aurora-engine/blob/1213f2c7c035aa523601fced8f75bef61b4728ab/engine-modexp/src/mpnat.rs#L825) - - fn check_modpow_even(base: u128, exp: u128, modulus: u128, expected: u128) { - let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); - let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); - let mut result = x.modpow(exp.to_be_bytes_padded(), ref m); - let result = mp_nat_to_u128(ref result); - assert_eq!(result, expected); - } - - fn check_modpow_with_power_of_two(base: u128, exp: u128, modulus: u128, expected: u128) { - let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); - let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); - let mut result = x.modpow_with_power_of_two(exp.to_be_bytes(), ref m); - let result = mp_nat_to_u128(ref result); - assert_eq!(result, expected); - } - - fn check_modpow_montgomery(base: u128, exp: u128, modulus: u128, expected: u128) { - let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); - let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); - let mut result = x.modpow_montgomery(exp.to_be_bytes(), ref m); - let result = mp_nat_to_u128(ref result); - assert_eq!(result, expected, "({base} ^ {exp}) % {modulus} failed check_modpow_montgomery"); - } - - fn check_sub_to_same_size(a: u128, n: u128) { - let mut x = MPNatTrait::from_big_endian(a.to_be_bytes()); - let mut y = MPNatTrait::from_big_endian(n.to_be_bytes()); - x.sub_to_same_size(ref y); - - assert!(x.digits.len() <= y.digits.len()); - let result = mp_nat_to_u128(ref x); - assert_eq!(result % n, a % n, "{a} % {n} failed sub_to_same_size check"); - } - - - fn check_is_odd(n: u128) { - let mut mp = MPNatTrait::from_big_endian(n.to_be_bytes()); - assert_eq!(mp.is_odd(), n % 2 == 1, "{n} failed is_odd test"); - } - - fn check_is_p2(n: u128, expected_result: bool) { - let mut mp = MPNatTrait::from_big_endian(n.to_be_bytes()); - assert_eq!(mp.is_power_of_two(), expected_result, "{n} failed is_power_of_two test"); - } - - #[test] - #[available_gas(100000000000000)] - fn test_modpow_even() { - check_modpow_even(3, 5, 500, 243); - check_modpow_even(3, 5, 20, 3); - check_modpow_even( - 0x2ff4f4df4c518867207c84b57a77aa50, - 0xca83c2925d17c577c9a03598b6f360, - 0xf863d4f17a5405d84814f54c92f803c8, - 0x8d216c9a1fb275ed18eb340ed43cacc0, - ); - check_modpow_even( - 0x13881e1614244c56d15ac01096b070e7, - 0x336df5b4567cbe4c093271dc151e6c72, - 0x7540f399a0b6c220f1fc60d2451a1ff0, - 0x1251d64c552e8f831f5b841d2811f9c1, - ); - check_modpow_even( - 0x774d5b2494a449d8f22b22ea542d4ddf, - 0xd2f602e1688f271853e7794503c2837e, - 0xa80d20ebf75f92192159197b60f36e8e, - 0x3fbbba42489b27fc271fb39f54aae2e1, - ); - check_modpow_even( - 0x756e409cc3583a6b68ae27ccd9eb3d50, - 0x16dafb38a334288954d038bedbddc970, - 0x1f9b2237f09413d1fc44edf9bd02b8bc, - 0x9347445ac61536a402723cd07a3f5a4, - ); - check_modpow_even( - 0x6dcb8405e2cc4dcebee3e2b14861b47d, - 0xe6c1e5251d6d5deb8dddd0198481d671, - 0xe34a31d814536e8b9ff6cc5300000000, - 0xaa86af638386880334694967564d0c3d, - ); - check_modpow_even( - 0x9c12fe4a1a97d17c1e4573247a43b0e5, - 0x466f3e0a2e8846b8c48ecbf612b96412, - 0x710d7b9d5718acff0000000000000000, - 0x569bf65929e71cd10a553a8623bdfc99, - ); - check_modpow_even( - 0x6d018fdeaa408222cb10ff2c36124dcf, - 0x8e35fc05d490bb138f73c2bc284a67a7, - 0x6c237160750d78400000000000000000, - 0x3fe14e11392c6c6be8efe956c965d5af, - ); - } - - #[test] - fn test_modpow_with_power_of_two() { - check_modpow_with_power_of_two(3, 2, 1.wrapping_shl(30), 9); - check_modpow_with_power_of_two(3, 5, 1.wrapping_shl(30), 243); - check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(30), 641836289); - check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(31), 1715578113); - check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(32), 3863061761); - check_modpow_with_power_of_two( - 0xabcd_ef01_2345_6789_1111, 0x1234_5678_90ab_cdef, 1.wrapping_shl(5), 17, - ); - check_modpow_with_power_of_two( - 0x3f47_9dc0_d5b9_6003, - 0xa180_e045_e314_8581, - 1.wrapping_shl(118), - 0x0028_3d19_e6cc_b8a0_e050_6abb_b9b1_1a03, - ); - } - - #[test] - #[available_gas(100000000000000)] - fn test_modpow_montgomery() { - check_modpow_montgomery(3, 5, 0x9346_9d50_1f74_d1c1, 243); - check_modpow_montgomery(3, 5, 19, 15); - check_modpow_montgomery( - 0x5c4b74ec760dfb021499f5c5e3c69222, - 0x62b2a34b21cf4cc036e880b3fb59fe09, - 0x7b799c4502cd69bde8bb12601ce3ff15, - 0x10c9d9071d0b86d6a59264d2f461200, - ); - check_modpow_montgomery( - 0xadb5ce8589030e3a9112123f4558f69c, - 0xb002827068f05b84a87431a70fb763ab, - 0xc4550871a1cfc67af3e77eceb2ecfce5, - 0x7cb78c0e1c1b43f6412e9d1155ea96d2, - ); - check_modpow_montgomery( - 0x26eb51a5d9bf15a536b6e3c67867b492, - 0xddf007944a79bf55806003220a58cc6, - 0xc96275a80c694a62330872b2690f8773, - 0x23b75090ead913def3a1e0bde863eda7, - ); - check_modpow_montgomery( - 0xb93fa81979e597f548c78f2ecb6800f3, - 0x5fad650044963a271898d644984cb9f0, - 0xbeb60d6bd0439ea39d447214a4f8d3ab, - 0x354e63e6a5e007014acd3e5ea88dc3ad, - ); - check_modpow_montgomery( - 0x1993163e4f578869d04949bc005c878f, - 0x8cb960f846475690259514af46868cf5, - 0x52e104dc72423b534d8e49d878f29e3b, - 0x2aa756846258d5cfa6a3f8b9b181a11c, - ); - } - - #[test] - fn test_sub_to_same_size() { - check_sub_to_same_size(0x10_00_00_00_00, 0xFF_00_00_00); - check_sub_to_same_size(0x10_00_00_00_00, 0x01_00_00_00); - check_sub_to_same_size(0x35_00_00_00_00, 0x01_00_00_00); - check_sub_to_same_size(0xEF_00_00_00_00_00_00, 0x02_FF_FF_FF); - - let n = 10; - let a = 57 + 2 * n + 0x1234_0000_0000 * n + 0x000b_0000_0000_0000_0000 * n; - check_sub_to_same_size(a, n); - - // Test that borrow equals self_most_sig at end of sub_to_same_size */ - { - let mut x = MPNatTrait::from_big_endian( - [ - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xae, - 0x5f, - 0xf0, - 0x8b, - 0xfc, - 0x02, - 0x71, - 0xa4, - 0xfe, - 0xe0, - 0x49, - 0x02, - 0xc9, - 0xd9, - 0x12, - 0x61, - 0x8e, - 0xf5, - 0x02, - 0x2c, - 0xa0, - 0x00, - 0x00, - 0x00, - ].span() - ); - let mut y = MPNatTrait::from_big_endian( - [ - 0xae, - 0x5f, - 0xf0, - 0x8b, - 0xfc, - 0x02, - 0x71, - 0xa4, - 0xfe, - 0xe0, - 0x49, - 0x0f, - 0x70, - 0x00, - 0x00, - 0x00, - ].span() - ); - x.sub_to_same_size(ref y); - } - - // Additional test for sub_to_same_size q_hat/r_hat adjustment logic */ - { - let mut x = MPNatTrait::from_big_endian( - [ - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - ].span() - ); - let mut y = MPNatTrait::from_big_endian( - [ - 0xff, - 0xff, - 0xff, - 0xff, - 0x00, - 0x00, - 0x00, - 0x00, - 0xff, - 0xff, - 0xff, - 0xff, - 0xff, - 0x00, - 0x00, - 0x00, - ].span() - ); - x.sub_to_same_size(ref y); - } - } - - #[test] - #[available_gas(100000000000000)] - fn test_mp_nat_is_odd() { - let mut n = 0; - loop { - if n == 1025 { - break; - }; - check_is_odd(n); - - n += 1; - }; - - let mut n = 0xFF_FF_FF_FF_00_00_00_00; - - loop { - if n == 0xFF_FF_FF_FF_00_00_04_01 { - break; - } - - check_is_odd(n); - n += 1; - }; - } - - #[test] - fn test_mp_nat_is_power_of_two() { - check_is_p2(0, false); - check_is_p2(1, true); - check_is_p2(1327, false); - check_is_p2((1.shl(1)) + (1.shl(35)), false); - check_is_p2(1.shl(1), true); - check_is_p2(1.shl(2), true); - check_is_p2(1.shl(3), true); - check_is_p2(1.shl(4), true); - check_is_p2(1.shl(5), true); - check_is_p2(1.shl(31), true); - check_is_p2(1.shl(32), true); - check_is_p2(1.shl(64), true); - check_is_p2(1.shl(65), true); - check_is_p2(1.shl(127), true); - } -} diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo index 177b60a79..6e51bd9e8 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo @@ -1,8 +1,9 @@ +use core::circuit::{u384, u96}; use core::cmp::min; use core::keccak::{cairo_keccak}; use core::num::traits::{Zero, One, Bounded, BitSize, SaturatingAdd}; use core::traits::{BitAnd}; -use crate::constants::{POW_2, POW_256_1, POW_256_REV}; +use crate::constants::POW_256_1; use crate::math::{Bitshift}; use crate::traits::integer::{BytesUsedTrait, ByteSize, U256Trait}; @@ -458,6 +459,39 @@ pub impl FromBytesImpl< } +/// An implementation of `FromBytes` specific to the `u384` circuit types. +/// Only `from_be_bytes` is used in the codebase; as such, other methods panic with `not +/// implemented` +impl U384FromBytes of FromBytes { + fn from_be_bytes(self: Span) -> Option { + if self.len() != 48 { + return Option::None; + } + let limb3_128: u128 = self.slice(0, 12).pad_left_with_zeroes(16).from_be_bytes().unwrap(); + let limb2_128: u128 = self.slice(12, 12).pad_left_with_zeroes(16).from_be_bytes().unwrap(); + let limb1_128: u128 = self.slice(24, 12).pad_left_with_zeroes(16).from_be_bytes().unwrap(); + let limb0_128: u128 = self.slice(36, 12).pad_left_with_zeroes(16).from_be_bytes().unwrap(); + let limb0: u96 = Into::<_, felt252>::into(limb0_128).try_into().unwrap(); + let limb1: u96 = Into::<_, felt252>::into(limb1_128).try_into().unwrap(); + let limb2: u96 = Into::<_, felt252>::into(limb2_128).try_into().unwrap(); + let limb3: u96 = Into::<_, felt252>::into(limb3_128).try_into().unwrap(); + Option::Some(u384 { limb0, limb1, limb2, limb3 }) + } + + fn from_be_bytes_partial(self: Span) -> Option { + panic!("not implemented") + } + + fn from_le_bytes(self: Span) -> Option { + panic!("not implemented") + } + + fn from_le_bytes_partial(self: Span) -> Option { + panic!("not implemented") + } +} + + #[generate_trait] pub impl ByteArrayExt of ByteArrayExTrait { /// Appends a span of bytes to the ByteArray @@ -766,4 +800,92 @@ mod tests { assert_eq!(result, expected); } } + + mod u384_test { + use core::circuit::{u384}; + use super::super::{FromBytes}; + #[test] + fn test_u384_from_be_bytes() { + let span = [ + 0x30, + 0x2f, + 0x2e, + 0x2d, + 0x2c, + 0x2b, + 0x2a, + 0x29, + 0x28, + 0x27, + 0x26, + 0x25, + 0x24, + 0x23, + 0x22, + 0x21, + 0x20, + 0x1f, + 0x1e, + 0x1d, + 0x1c, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x16, + 0x15, + 0x14, + 0x13, + 0x12, + 0x11, + 0x10, + 0x0f, + 0x0e, + 0x0d, + 0x0c, + 0x0b, + 0x0a, + 0x09, + 0x08, + 0x07, + 0x06, + 0x05, + 0x04, + 0x03, + 0x02, + 0x01 + ].span(); + let u384 = FromBytes::::from_be_bytes(span); + assert_eq!( + u384, + Option::Some( + u384 { + limb0: 0x0c0b0a090807060504030201, + limb1: 0x1817161514131211100f0e0d, + limb2: 0x24232221201f1e1d1c1b1a19, + limb3: 0x302f2e2d2c2b2a2928272625 + } + ) + ); + } + + #[test] + #[should_panic(expected: "not implemented")] + fn test_u384_from_be_bytes_partial() { + let u384 = FromBytes::::from_be_bytes_partial([].span()); + } + + #[test] + #[should_panic(expected: "not implemented")] + fn test_u384_from_le_bytes() { + let u384 = FromBytes::::from_le_bytes([].span()); + } + + #[test] + #[should_panic(expected: "not implemented")] + fn test_u384_from_le_bytes_partial() { + let u384 = FromBytes::::from_le_bytes_partial([].span()); + } + } } diff --git a/cairo_zero/tests/src/kakarot/precompiles/generate_modexp_data.py b/cairo_zero/tests/src/kakarot/precompiles/generate_modexp_data.py new file mode 100644 index 000000000..b27478a56 --- /dev/null +++ b/cairo_zero/tests/src/kakarot/precompiles/generate_modexp_data.py @@ -0,0 +1,219 @@ +from typing import Dict, List, Tuple + +from ethereum.base_types import U256, Bytes, Uint +from ethereum.cancun.vm.memory import buffer_read +from ethereum.cancun.vm.precompiled_contracts.modexp import gas_cost +from ethereum.crypto.hash import keccak256 +from hypothesis import given, settings +from hypothesis import strategies as st + +# Store test cases +test_cases: List[Dict] = [] + + +def modexp_384_bits(data: Bytes) -> Tuple[Uint, Bytes]: + """ + Calculate `(base**exp) % modulus` for arbitrary sized `base`, `exp` and. + `modulus`. The return value is the same length as the modulus. + + Modified version of EELS modexp implementation that only accepts up to 384-bit inputs. + Reference: https://github.com/ethereum/execution-specs/blob/master/src/ethereum/cancun/vm/precompiled_contracts/modexp.py#L23-L64 + """ + MAX_INPUT_BYTES = 48 + + # GAS + base_length = U256.from_be_bytes(buffer_read(data, U256(0), U256(32))) + exp_length = U256.from_be_bytes(buffer_read(data, U256(32), U256(32))) + modulus_length = U256.from_be_bytes(buffer_read(data, U256(64), U256(32))) + + if ( + base_length > MAX_INPUT_BYTES + or exp_length > MAX_INPUT_BYTES + or modulus_length > MAX_INPUT_BYTES + ): + raise ValueError("Input length exceeds maximum allowed length") + + exp_start = U256(96) + base_length + + exp_head = Uint.from_be_bytes( + buffer_read(data, exp_start, min(U256(32), exp_length)) + ) + + gas = gas_cost(base_length, modulus_length, exp_length, exp_head) + + # OPERATION + if base_length == 0 and modulus_length == 0: + output = Bytes() + return gas, output + + base = Uint.from_be_bytes(buffer_read(data, U256(96), base_length)) + exp = Uint.from_be_bytes(buffer_read(data, exp_start, exp_length)) + + modulus_start = exp_start + exp_length + modulus = Uint.from_be_bytes(buffer_read(data, modulus_start, modulus_length)) + + if modulus == 0: + output = Bytes(b"\x00") * modulus_length + else: + output = Uint(pow(base, exp, modulus)).to_bytes(modulus_length, "big") + + return gas, output + + +def create_input_data( + base_len: int, + exp_len: int, + modulus_len: int, + base: bytes, + exp: bytes, + modulus: bytes, +) -> Bytes: + encoded_base_len = U256(base_len).to_be_bytes32() + encoded_exp_len = U256(exp_len).to_be_bytes32() + encoded_modulus_len = U256(modulus_len).to_be_bytes32() + + return Bytes( + encoded_base_len + encoded_exp_len + encoded_modulus_len + base + exp + modulus + ) + + +def add_test_case(name: str, input_data: Bytes, is_err: bool = False) -> None: + """Add a test case to the global test cases list.""" + try: + result = modexp_384_bits(input_data) + gas, output = result + test_cases.append( + { + "name": name, + "input": input_data, + "output_gas": gas, + "output_data": output, + "is_err": is_err, + } + ) + except ValueError: + test_cases.append( + { + "name": name, + "input": input_data, + "output_gas": 0, + "output_data": Bytes(), + "is_err": True, + } + ) + + +@given( + data=st.data(), + base_len=st.integers(min_value=0, max_value=256), + exp_len=st.integers(min_value=0, max_value=256), + modulus_len=st.integers(min_value=0, max_value=256), + base_bytes=st.binary(min_size=0, max_size=256), + exp_bytes=st.binary(min_size=0, max_size=256), + modulus_bytes=st.binary(min_size=0, max_size=256), +) +@settings(max_examples=50) +def generate_test_modexp_384_bits_random_inputs( + data, base_len, exp_len, modulus_len, base_bytes, exp_bytes, modulus_bytes +): + # Ensure the actual data matches the specified length + base = base_bytes[:base_len].ljust(base_len, b"\x00") + exp = exp_bytes[:exp_len].ljust(exp_len, b"\x00") + modulus = modulus_bytes[:modulus_len].ljust(modulus_len, b"\x00") + + input_data = create_input_data(base_len, exp_len, modulus_len, base, exp, modulus) + test_id = keccak256(input_data)[0:20].hex() + + add_test_case( + f"modexp_random_inputs_{base_len}_{exp_len}_{modulus_len}__{test_id}", + input_data, + ) + + +@given( + data=st.data(), + base_len=st.integers(min_value=1, max_value=48), # At least 1 byte + exp_len=st.integers(min_value=1, max_value=48), # At least 1 byte + modulus_len=st.integers(min_value=1, max_value=48), # At least 1 byte +) +@settings(max_examples=50) +def generate_test_modexp_384_bits_non_empty_outputs( + data, base_len, exp_len, modulus_len +): + base = data.draw(st.binary(min_size=base_len, max_size=base_len)) + exp = data.draw(st.binary(min_size=exp_len, max_size=exp_len)) + # Ensure modulus is not zero by requiring at least one non-zero byte + modulus = data.draw( + st.binary(min_size=modulus_len, max_size=modulus_len).filter( + lambda x: any(b != 0 for b in x) + ) + ) + + input_data = create_input_data(base_len, exp_len, modulus_len, base, exp, modulus) + + add_test_case( + f"modexp_non_empty_outputs_{base_len}_{exp_len}_{modulus_len}", input_data + ) + + +def generate_cairo_tests() -> str: + """Generate Cairo test code from collected test cases.""" + cairo_tests = [] + + # Remove duplicate test cases based on the name + filtered_test_cases = [ + dict(t) for t in {case["name"]: case for case in test_cases}.values() + ] + + for case in filtered_test_cases: + # Convert bytes to hex array format + input_bytes = [f"0x{b:02x}" for b in case["input"]] + test_name = f"test_{case['name']}" + test_input = f"let input = array![{', '.join(input_bytes)}];" + + if not case["is_err"]: + output_bytes = [f"0x{b:02x}" for b in case["output_data"]] + + test = f""" + #[test] + fn {test_name}() {{ + #[cairofmt::skip] + {test_input} + #[cairofmt::skip] + let expected_result = array![{', '.join(output_bytes)}]; + let expected_gas = {case['output_gas']}; + + let (gas, result) = ModExp::exec(input.span()).unwrap(); + assert_eq!(result, expected_result.span()); + assert_eq!(gas, expected_gas); + }}""" + cairo_tests.append(test) + continue + + # In case the test errors, due to an input length too large + # just assert result.is_err() + test = f""" + #[test] + fn {test_name}() {{ + #[cairofmt::skip] + {test_input} + let result = ModExp::exec(input.span()); + assert!(result.is_err()); + }} + """ + cairo_tests.append(test) + + return "\n".join(cairo_tests) + + +if __name__ == "__main__": + # Run the Hypothesis test + generate_test_modexp_384_bits_random_inputs() + generate_test_modexp_384_bits_non_empty_outputs() + + # Generate and save the Cairo tests + print(f"Generated {len(test_cases)} test cases") + with open("generated_modexp_tests.cairo", "w") as f: + f.write(generate_cairo_tests()) + + print("Saved Cairo tests to generated_modexp_tests.cairo")