Skip to content

Instantly share code, notes, and snippets.

@huitseeker
Created December 25, 2025 21:43
Show Gist options
  • Select an option

  • Save huitseeker/3a13cc3c34c0073e9bfc4ed96b75ce19 to your computer and use it in GitHub Desktop.

Select an option

Save huitseeker/3a13cc3c34c0073e9bfc4ed96b75ce19 to your computer and use it in GitHub Desktop.
//! Verify QuadFelt::new_complex matches the old QuadFelt::from([a, b]) behavior.
//!
//! Both APIs call BinomialExtensionField::new with the same array, so they should be identical.
use miden_core::{Felt, QuadFelt};
use proptest::prelude::*;
/// Create QuadFelt from array like the old API did.
///
/// BinomialExtensionField is #[repr(transparent)] over [A; D], and PhantomData is zero-sized,
/// so transmute is safe.
fn quadfelt_from_array_old_api(arr: [Felt; 2]) -> QuadFelt {
unsafe { std::mem::transmute::<[Felt; 2], QuadFelt>(arr) }
}
proptest! {
#[test]
fn test_quadfelt_construction_equivalence(a in 0u64..u64::MAX, b in 0u64..u64::MAX) {
let felt_a = Felt::new(a);
let felt_b = Felt::new(b);
let qf_new = QuadFelt::new_complex(felt_a, felt_b);
let qf_old = quadfelt_from_array_old_api([felt_a, felt_b]);
prop_assert_eq!(qf_new, qf_old,
"new_complex({}, {}) != from([{}, {}])", a, b, a, b);
}
#[test]
fn test_quadfelt_arithmetic_equivalence(
a1 in 0u64..u64::MAX, b1 in 0u64..u64::MAX,
a2 in 0u64..u64::MAX, b2 in 0u64..u64::MAX
) {
let f1a = Felt::new(a1);
let f1b = Felt::new(b1);
let f2a = Felt::new(a2);
let f2b = Felt::new(b2);
let qf1_new = QuadFelt::new_complex(f1a, f1b);
let qf1_old = quadfelt_from_array_old_api([f1a, f1b]);
let qf2_new = QuadFelt::new_complex(f2a, f2b);
let qf2_old = quadfelt_from_array_old_api([f2a, f2b]);
prop_assert_eq!(qf1_new + qf2_new, qf1_old + qf2_old, "Addition differs");
prop_assert_eq!(qf1_new * qf2_new, qf1_old * qf2_old, "Multiplication differs");
prop_assert_eq!(qf1_new - qf2_new, qf1_old - qf2_old, "Subtraction differs");
}
#[test]
fn test_quadfelt_basis_coefficients_equivalence(a in 0u64..u64::MAX, b in 0u64..u64::MAX) {
use miden_core::BasedVectorSpace;
let felt_a = Felt::new(a);
let felt_b = Felt::new(b);
let qf_new = QuadFelt::new_complex(felt_a, felt_b);
let qf_old = quadfelt_from_array_old_api([felt_a, felt_b]);
let coeffs_new: &[Felt] = qf_new.as_basis_coefficients_slice();
let coeffs_old: &[Felt] = qf_old.as_basis_coefficients_slice();
prop_assert_eq!(coeffs_new[0], coeffs_old[0], "Coeff[0] differs");
prop_assert_eq!(coeffs_new[1], coeffs_old[1], "Coeff[1] differs");
prop_assert_eq!(coeffs_new[0], felt_a, "Coeff[0] != input a");
prop_assert_eq!(coeffs_new[1], felt_b, "Coeff[1] != input b");
}
#[test]
fn test_quadfelt_special_values_equivalence(x in 0u64..u64::MAX) {
use miden_core::{ZERO, ONE};
let felt_x = Felt::new(x);
let zero_new = QuadFelt::new_complex(ZERO, ZERO);
let zero_old = quadfelt_from_array_old_api([ZERO, ZERO]);
prop_assert_eq!(zero_new, zero_old, "ZERO differs");
let one_new = QuadFelt::new_complex(ONE, ZERO);
let one_old = quadfelt_from_array_old_api([ONE, ZERO]);
prop_assert_eq!(one_new, one_old, "ONE differs");
let real_new = QuadFelt::new_complex(felt_x, ZERO);
let real_old = quadfelt_from_array_old_api([felt_x, ZERO]);
prop_assert_eq!(real_new, real_old, "Real-only differs");
let imag_new = QuadFelt::new_complex(ZERO, felt_x);
let imag_old = quadfelt_from_array_old_api([ZERO, felt_x]);
prop_assert_eq!(imag_new, imag_old, "Imag-only differs");
}
}
#[test]
fn test_quadfelt_transmute_safety() {
assert_eq!(
std::mem::size_of::<QuadFelt>(),
std::mem::size_of::<[Felt; 2]>(),
"Size mismatch"
);
assert_eq!(
std::mem::align_of::<QuadFelt>(),
std::mem::align_of::<[Felt; 2]>(),
"Alignment mismatch"
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment