use miden_core::{
Felt,
field::{BasedVectorSpace, Field, PrimeCharacteristicRing, QuadFelt, TwoAdicField},
program::StackInputs,
};
use proptest::prelude::*;
use super::{
super::stack_ops::op_push, EIGHT, TAU_INV, TAU2_INV, TAU3_INV, TWO_INV,
compute_evaluation_points, fold4 as fri_fold4, get_domain_segment_flags, get_tau_factor,
op_fri_ext2fold4,
};
use crate::{
fast::FastProcessor,
processor::{Processor, SystemInterface},
};
#[test]
fn test_constants() {
let tau = Felt::two_adic_generator(2);
assert_eq!(TAU_INV, tau.inverse());
assert_eq!(TAU2_INV, tau.square().inverse());
assert_eq!(TAU3_INV, tau.cube().inverse());
assert_eq!(Felt::new(2).inverse(), TWO_INV);
}
proptest! {
#[test]
fn test_op_fri_ext2fold4(
v0_0 in any::<u64>(),
v0_1 in any::<u64>(),
v1_0 in any::<u64>(),
v1_1 in any::<u64>(),
v2_0 in any::<u64>(),
v2_1 in any::<u64>(),
v3_0 in any::<u64>(),
v3_1 in any::<u64>(),
f_pos in any::<u64>(),
d_seg in 0u64..4,
poe in 1u64..=u64::MAX,
alpha_0 in any::<u64>(),
alpha_1 in any::<u64>(),
layer_ptr in any::<u64>(),
end_ptr in any::<u64>(),
) {
let query_values = [
QuadFelt::new([Felt::new(v0_0), Felt::new(v0_1)]),
QuadFelt::new([Felt::new(v1_0), Felt::new(v1_1)]),
QuadFelt::new([Felt::new(v2_0), Felt::new(v2_1)]),
QuadFelt::new([Felt::new(v3_0), Felt::new(v3_1)]),
];
let prev_value = query_values[d_seg as usize];
let prev_value_base = prev_value.as_basis_coefficients_slice();
let alpha = QuadFelt::new([Felt::new(alpha_0), Felt::new(alpha_1)]);
let poe = Felt::new(poe);
let f_pos = Felt::new(f_pos);
let d_seg_felt = Felt::new(d_seg);
let layer_ptr = Felt::new(layer_ptr);
let end_ptr = Felt::new(end_ptr);
let stack_inputs = [
query_values[0].as_basis_coefficients_slice()[1], query_values[1].as_basis_coefficients_slice()[0], query_values[1].as_basis_coefficients_slice()[1], query_values[2].as_basis_coefficients_slice()[0], query_values[2].as_basis_coefficients_slice()[1], query_values[3].as_basis_coefficients_slice()[0], query_values[3].as_basis_coefficients_slice()[1], f_pos, d_seg_felt, poe, prev_value_base[1], prev_value_base[0], Felt::new(alpha_1), Felt::new(alpha_0), layer_ptr, end_ptr, ];
let mut processor = FastProcessor::new(StackInputs::new(&stack_inputs).unwrap());
let v0 = query_values[0].as_basis_coefficients_slice()[0];
op_push(&mut processor, v0).unwrap();
processor.system_mut().increment_clock();
let result = op_fri_ext2fold4(&mut processor);
prop_assert!(result.is_ok(), "op_fri_ext2fold4 failed: {:?}", result.err());
processor.system_mut().increment_clock();
let f_tau = get_tau_factor(d_seg as usize);
let x = poe * f_tau;
let x_inv = x.inverse();
let (ev, es) = compute_evaluation_points(alpha, x_inv);
let (folded_value, tmp0, tmp1) = fri_fold4(query_values, ev, es);
let tmp0_base: &[Felt] = tmp0.as_basis_coefficients_slice();
let tmp1_base: &[Felt] = tmp1.as_basis_coefficients_slice();
let ds = get_domain_segment_flags(d_seg as usize);
let folded_value_base: &[Felt] = folded_value.as_basis_coefficients_slice();
let poe2 = poe.square();
let poe4 = poe2.square();
let stack = processor.stack_top();
prop_assert_eq!(stack[15], tmp0_base[1], "tmp0[1] at position 0");
prop_assert_eq!(stack[14], tmp0_base[0], "tmp0[0] at position 1");
prop_assert_eq!(stack[13], tmp1_base[1], "tmp1[1] at position 2");
prop_assert_eq!(stack[12], tmp1_base[0], "tmp1[0] at position 3");
prop_assert_eq!(stack[11], ds[0], "ds[0] at position 4");
prop_assert_eq!(stack[10], ds[1], "ds[1] at position 5");
prop_assert_eq!(stack[9], ds[2], "ds[2] at position 6");
prop_assert_eq!(stack[8], ds[3], "ds[3] at position 7");
prop_assert_eq!(stack[7], poe2, "poe^2 at position 8");
prop_assert_eq!(stack[6], f_tau, "f_tau at position 9");
prop_assert_eq!(stack[5], layer_ptr + EIGHT, "layer_ptr+8 at position 10");
prop_assert_eq!(stack[4], poe4, "poe^4 at position 11");
prop_assert_eq!(stack[3], f_pos, "f_pos at position 12");
prop_assert_eq!(stack[2], folded_value_base[1], "folded_value[1] at position 13");
prop_assert_eq!(stack[1], folded_value_base[0], "folded_value[0] at position 14");
prop_assert_eq!(stack[0], end_ptr, "end_ptr at position 15");
}
}