use clock_curve_math::BigInt;
use clock_curve_math::extensible::*;
#[test]
fn test_multiplication_algorithm_enum() {
assert_eq!(
MultiplicationAlgorithm::Standard,
MultiplicationAlgorithm::Standard
);
assert_eq!(
MultiplicationAlgorithm::Schoolbook,
MultiplicationAlgorithm::Schoolbook
);
assert_eq!(
MultiplicationAlgorithm::Karatsuba,
MultiplicationAlgorithm::Karatsuba
);
assert_eq!(
MultiplicationAlgorithm::ToomCook,
MultiplicationAlgorithm::ToomCook
);
assert_eq!(MultiplicationAlgorithm::FFT, MultiplicationAlgorithm::FFT);
assert_ne!(
MultiplicationAlgorithm::Standard,
MultiplicationAlgorithm::Schoolbook
);
assert!(format!("{:?}", MultiplicationAlgorithm::Karatsuba).contains("Karatsuba"));
}
#[test]
fn test_mul_karatsuba_standalone_basic() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let result = mul_karatsuba_standalone(&a, &b);
let expected = a.mul(&b);
assert_eq!(result, expected);
}
#[test]
fn test_mul_karatsuba_standalone_edge_cases() {
let zero = BigInt::from_u64(0);
let num = BigInt::from_u64(42);
assert_eq!(mul_karatsuba_standalone(&zero, &num), BigInt::from_u64(0));
assert_eq!(mul_karatsuba_standalone(&num, &zero), BigInt::from_u64(0));
assert_eq!(mul_karatsuba_standalone(&zero, &zero), BigInt::from_u64(0));
let one = BigInt::from_u64(1);
assert_eq!(mul_karatsuba_standalone(&num, &one), num);
assert_eq!(mul_karatsuba_standalone(&one, &num), num);
}
#[test]
fn test_mul_karatsuba_standalone_large_numbers() {
let a = BigInt::from_limbs(&[u64::MAX, u64::MAX, 0, 0]);
let b = BigInt::from_limbs(&[u64::MAX, u64::MAX, 0, 0]);
let result = mul_karatsuba_standalone(&a, &b);
let expected = a.mul(&b);
assert_eq!(result, expected);
}
#[test]
fn test_mul_toom_cook_standalone_basic() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let result = mul_toom_cook_standalone(&a, &b);
let expected = a.mul(&b);
assert_eq!(result, expected);
}
#[test]
fn test_mul_toom_cook_standalone_edge_cases() {
let zero = BigInt::from_u64(0);
let one = BigInt::from_u64(1);
let num = BigInt::from_u64(42);
assert_eq!(mul_toom_cook_standalone(&zero, &num), BigInt::from_u64(0));
assert_eq!(mul_toom_cook_standalone(&num, &zero), BigInt::from_u64(0));
assert_eq!(mul_toom_cook_standalone(&zero, &zero), BigInt::from_u64(0));
assert_eq!(mul_toom_cook_standalone(&num, &one), num);
assert_eq!(mul_toom_cook_standalone(&one, &num), num);
}
#[test]
fn test_mul_fft_standalone_basic() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let result = mul_fft_standalone(&a, &b);
let expected = a.mul(&b);
assert_eq!(result, expected);
}
#[test]
fn test_mul_fft_standalone_edge_cases() {
let zero = BigInt::from_u64(0);
let one = BigInt::from_u64(1);
let num = BigInt::from_u64(42);
assert_eq!(mul_fft_standalone(&zero, &num), BigInt::from_u64(0));
assert_eq!(mul_fft_standalone(&num, &zero), BigInt::from_u64(0));
assert_eq!(mul_fft_standalone(&zero, &zero), BigInt::from_u64(0));
assert_eq!(mul_fft_standalone(&num, &one), num);
assert_eq!(mul_fft_standalone(&one, &num), num);
}
#[test]
fn test_multiplication_algorithms_consistency() {
let test_cases = vec![
(BigInt::from_u64(123), BigInt::from_u64(456)),
(BigInt::from_u64(789), BigInt::from_u64(123)),
(
BigInt::from_limbs(&[1, 2, 3, 0]),
BigInt::from_limbs(&[4, 5, 6, 0]),
),
];
for (a, b) in test_cases {
let standard = a.mul(&b);
let karatsuba = mul_karatsuba_standalone(&a, &b);
let toom_cook = mul_toom_cook_standalone(&a, &b);
let fft = mul_fft_standalone(&a, &b);
assert_eq!(
karatsuba, standard,
"Karatsuba failed for {:?} * {:?}",
a, b
);
assert_eq!(
toom_cook, standard,
"Toom-Cook failed for {:?} * {:?}",
a, b
);
assert_eq!(fft, standard, "FFT failed for {:?} * {:?}", a, b);
}
}
#[test]
fn test_multiplication_algorithms_commutativity() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let karatsuba_ab = mul_karatsuba_standalone(&a, &b);
let karatsuba_ba = mul_karatsuba_standalone(&b, &a);
assert_eq!(karatsuba_ab, karatsuba_ba);
let toom_ab = mul_toom_cook_standalone(&a, &b);
let toom_ba = mul_toom_cook_standalone(&b, &a);
assert_eq!(toom_ab, toom_ba);
let fft_ab = mul_fft_standalone(&a, &b);
let fft_ba = mul_fft_standalone(&b, &a);
assert_eq!(fft_ab, fft_ba);
}
#[test]
fn test_multiplication_algorithms_distributivity() {
let a = BigInt::from_u64(100);
let b = BigInt::from_u64(200);
let c = BigInt::from_u64(50);
let left = (a.add(&b)).mul(&c);
let right = a.mul(&c).add(&b.mul(&c));
assert_eq!(left, right);
let left_k = mul_karatsuba_standalone(&(a.add(&b)), &c);
let right_k = mul_karatsuba_standalone(&a, &c).add(&mul_karatsuba_standalone(&b, &c));
assert_eq!(left_k, right_k);
}
#[test]
fn test_mul_karatsuba_impl_consistency() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let standalone = mul_karatsuba_standalone(&a, &b);
let standard = a.mul(&b);
assert_eq!(standalone, standard);
}
#[test]
fn test_mul_toom_cook_impl_consistency() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let standalone = mul_toom_cook_standalone(&a, &b);
let standard = a.mul(&b);
assert_eq!(standalone, standard);
}
#[test]
fn test_mul_fft_impl_consistency() {
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let standalone = mul_fft_standalone(&a, &b);
let standard = a.mul(&b);
assert_eq!(standalone, standard);
}
#[test]
fn test_utils_modular_inverse() {
use clock_curve_math::extensible::utils;
let modulus = BigInt::from_u64(17); let value = BigInt::from_u64(3);
let inverse = utils::mod_inverse(&value, &modulus);
assert!(inverse.is_some());
assert_eq!(inverse.unwrap(), BigInt::from_u64(6));
let product = value.mul(&inverse.unwrap());
let remainder = product.div_rem(&modulus).1;
assert_eq!(remainder, BigInt::from_u64(1));
}
#[test]
fn test_utils_modular_inverse_edge_cases() {
use clock_curve_math::extensible::utils;
let modulus = BigInt::from_u64(17);
let inverse_1 = utils::mod_inverse(&BigInt::from_u64(1), &modulus);
assert!(inverse_1.is_some());
assert_eq!(inverse_1.unwrap(), BigInt::from_u64(1));
let inverse_neg1 = utils::mod_inverse(&BigInt::from_u64(16), &modulus);
assert!(inverse_neg1.is_some());
assert_eq!(inverse_neg1.unwrap(), BigInt::from_u64(16));
let no_inverse = utils::mod_inverse(&BigInt::from_u64(4), &BigInt::from_u64(6));
assert!(no_inverse.is_none());
}
#[test]
fn test_utils_modular_exponentiation() {
use clock_curve_math::extensible::utils;
let base = BigInt::from_u64(2);
let exp = BigInt::from_u64(10);
let modulus = BigInt::from_u64(1000);
let result = utils::mod_pow(&base, &exp, &modulus);
assert_eq!(result, BigInt::from_u64(24)); }
#[test]
fn test_utils_modular_exponentiation_edge_cases() {
use clock_curve_math::extensible::utils;
let modulus = BigInt::from_u64(17);
let result = utils::mod_pow(&BigInt::from_u64(5), &BigInt::from_u64(0), &modulus);
assert_eq!(result, BigInt::from_u64(1));
let result = utils::mod_pow(&BigInt::from_u64(1), &BigInt::from_u64(42), &modulus);
assert_eq!(result, BigInt::from_u64(1));
let result = utils::mod_pow(&BigInt::from_u64(5), &BigInt::from_u64(1), &modulus);
assert_eq!(result, BigInt::from_u64(5));
}
#[test]
fn test_algorithms_performance_characteristics() {
let small_a = BigInt::from_u64(123);
let small_b = BigInt::from_u64(456);
let medium_a = BigInt::from_limbs(&[u64::MAX, u64::MAX, 0, 0]);
let medium_b = BigInt::from_limbs(&[u64::MAX, u64::MAX, 0, 0]);
let _ = mul_karatsuba_standalone(&small_a, &small_b);
let _ = mul_toom_cook_standalone(&small_a, &small_b);
let _ = mul_fft_standalone(&small_a, &small_b);
let _ = mul_karatsuba_standalone(&medium_a, &medium_b);
let _ = mul_toom_cook_standalone(&medium_a, &medium_b);
let _ = mul_fft_standalone(&medium_a, &medium_b);
}
#[test]
fn test_multiplication_algorithm_debug_formatting() {
let algo = MultiplicationAlgorithm::Karatsuba;
let debug_str = format!("{:?}", algo);
assert!(debug_str.contains("Karatsuba"));
let algo2 = MultiplicationAlgorithm::ToomCook;
let debug_str2 = format!("{:?}", algo2);
assert!(debug_str2.contains("ToomCook"));
}
#[test]
fn test_multiplication_algorithm_equality() {
assert_eq!(
MultiplicationAlgorithm::Standard,
MultiplicationAlgorithm::Standard
);
assert_ne!(
MultiplicationAlgorithm::Standard,
MultiplicationAlgorithm::Schoolbook
);
assert_ne!(
MultiplicationAlgorithm::Karatsuba,
MultiplicationAlgorithm::ToomCook
);
assert_ne!(
MultiplicationAlgorithm::FFT,
MultiplicationAlgorithm::Standard
);
}
#[test]
fn test_multiplication_algorithm_clone() {
let algo = MultiplicationAlgorithm::Karatsuba;
let cloned = algo.clone();
assert_eq!(algo, cloned);
}
#[test]
fn test_multiplication_algorithm_copy() {
let algo = MultiplicationAlgorithm::FFT;
let copied = algo;
assert_eq!(algo, copied);
}