#[cfg(feature = "simd")]
mod tests {
use clock_curve_math::simd::*;
#[test]
fn test_simd_limbs_creation_and_conversion() {
let zero_limbs = [0u64; 4];
let zero_simd = SimdLimbs::from_limbs(&zero_limbs);
assert_eq!(zero_simd.to_limbs(), zero_limbs);
let test_limbs = [1u64, 2u64, 3u64, 4u64];
let test_simd = SimdLimbs::from_limbs(&test_limbs);
assert_eq!(test_simd.to_limbs(), test_limbs);
let max_limbs = [u64::MAX; 4];
let max_simd = SimdLimbs::from_limbs(&max_limbs);
assert_eq!(max_simd.to_limbs(), max_limbs);
}
#[test]
fn test_simd_limbs_debug_and_clone() {
let limbs = [42u64, 123u64, 999u64, 0u64];
let original = SimdLimbs::from_limbs(&limbs);
let cloned = original.clone();
assert_eq!(original, cloned);
assert_eq!(original.to_limbs(), cloned.to_limbs());
let debug_str = format!("{:?}", original);
assert!(debug_str.contains("SimdLimbs"));
assert!(debug_str.contains("limbs"));
}
#[test]
fn test_simd_limbs_equality() {
let limbs1 = [1u64, 2, 3, 4];
let limbs2 = [1u64, 2, 3, 4];
let limbs3 = [1u64, 2, 3, 5];
let simd1 = SimdLimbs::from_limbs(&limbs1);
let simd2 = SimdLimbs::from_limbs(&limbs2);
let simd3 = SimdLimbs::from_limbs(&limbs3);
assert_eq!(simd1, simd2);
assert_eq!(simd1.to_limbs(), simd2.to_limbs());
assert_ne!(simd1, simd3);
assert_ne!(simd1.to_limbs(), simd3.to_limbs());
}
#[test]
fn test_simd_support_enum_variants() {
assert_eq!(SimdSupport::None, SimdSupport::None);
assert_eq!(SimdSupport::Sse41, SimdSupport::Sse41);
assert_eq!(SimdSupport::Avx256, SimdSupport::Avx256);
assert_eq!(SimdSupport::Avx512, SimdSupport::Avx512);
assert_eq!(SimdSupport::Neon, SimdSupport::Neon);
assert!(format!("{:?}", SimdSupport::None).contains("None"));
assert!(format!("{:?}", SimdSupport::Avx256).contains("Avx256"));
}
#[test]
fn test_simd_support_detection_safety() {
let support = SimdLimbs::detect_simd_support();
match support {
SimdSupport::None
| SimdSupport::Sse41
| SimdSupport::Avx256
| SimdSupport::Avx512
| SimdSupport::Neon => {
}
}
let support2 = SimdLimbs::detect_simd_support();
assert_eq!(support, support2);
}
#[test]
fn test_simd_support_clone_and_copy() {
let support = SimdSupport::Avx256;
let cloned = support.clone();
let copied = support;
assert_eq!(support, cloned);
assert_eq!(support, copied);
assert_eq!(cloned, copied);
}
#[cfg(feature = "alloc")]
mod alloc_tests {
use super::*;
use clock_curve_math::FieldElement;
#[test]
fn test_simd_batch_creation() {
let batch = SimdBatch::<u64>::new();
assert_eq!(batch.as_slice().len(), 0);
assert!(matches!(
batch.simd_support(),
SimdSupport::None
| SimdSupport::Sse41
| SimdSupport::Avx256
| SimdSupport::Avx512
| SimdSupport::Neon
));
}
#[test]
fn test_simd_batch_with_capacity() {
let capacity = 100;
let batch = SimdBatch::<u64>::with_capacity(capacity);
assert_eq!(batch.as_slice().len(), 0);
}
#[test]
fn test_simd_batch_push_and_access() {
let mut batch = SimdBatch::new();
batch.push(42u64);
batch.push(123u64);
batch.push(999u64);
let slice = batch.as_slice();
assert_eq!(slice.len(), 3);
assert_eq!(slice[0], 42u64);
assert_eq!(slice[1], 123u64);
assert_eq!(slice[2], 999u64);
}
#[test]
fn test_simd_batch_with_field_elements() {
let mut batch = SimdBatch::new();
let elem1 = FieldElement::from_u64(1);
let elem2 = FieldElement::from_u64(2);
let elem3 = FieldElement::from_u64(3);
batch.push(elem1.clone());
batch.push(elem2.clone());
batch.push(elem3.clone());
let slice = batch.as_slice();
assert_eq!(slice.len(), 3);
assert_eq!(slice[0], elem1);
assert_eq!(slice[1], elem2);
assert_eq!(slice[2], elem3);
}
#[test]
fn test_simd_batch_clone() {
let mut original = SimdBatch::new();
original.push(42u64);
original.push(24u64);
let cloned = original.clone();
assert_eq!(original.as_slice(), cloned.as_slice());
assert_eq!(original.simd_support(), cloned.simd_support());
original.push(100u64);
assert_ne!(original.as_slice().len(), cloned.as_slice().len());
}
#[test]
fn test_simd_batch_debug_formatting() {
let mut batch = SimdBatch::new();
batch.push(1u64);
batch.push(2u64);
let debug_str = format!("{:?}", batch);
assert!(debug_str.contains("SimdBatch"));
}
}
#[test]
fn test_prepare_montgomery_mul_simd() {
use clock_curve_math::{BigInt, montgomery};
let a = BigInt::from_u64(12345);
let b = BigInt::from_u64(67890);
let modulus = BigInt::from_u64(7919); let n_prime = montgomery::compute_n_prime(&modulus);
let result = prepare_montgomery_mul_simd(&a, &b, &modulus, &n_prime);
assert!(result >= BigInt::from_u64(0));
assert!(result < modulus);
let expected = montgomery::montgomery_mul(&a, &b, &modulus, &n_prime);
assert_eq!(result, expected);
}
#[cfg(feature = "alloc")]
#[test]
fn test_prepare_batch_inverse_simd() {
use clock_curve_math::FieldElement;
let elements = vec![
FieldElement::from_u64(1),
FieldElement::from_u64(2),
FieldElement::from_u64(3),
];
let result = prepare_batch_inverse_simd(&elements);
assert!(result.is_some());
let inverses = result.unwrap();
assert_eq!(inverses.inverses.len(), 3);
for (i, inv) in inverses.inverses.iter().enumerate() {
assert_eq!(elements[i].mul(inv), FieldElement::from_u64(1));
}
let expected = clock_curve_math::field::batch_inverse(&elements);
assert!(expected.is_some());
let expected_inverses = expected.unwrap();
assert_eq!(inverses.inverses, expected_inverses.inverses);
}
#[cfg(feature = "alloc")]
mod perf_tests {
use super::*;
#[test]
fn test_perf_result_creation() {
use core::time::Duration;
let duration = Duration::from_nanos(1000);
let operation = "test_operation";
let result = perf::PerfResult::new(duration, operation);
assert_eq!(result.duration, duration);
assert_eq!(result.operation, operation);
assert!(matches!(
result.simd_level,
SimdSupport::None
| SimdSupport::Sse41
| SimdSupport::Avx256
| SimdSupport::Avx512
| SimdSupport::Neon
));
}
#[test]
fn test_perf_result_debug() {
use core::time::Duration;
let result = perf::PerfResult::new(Duration::from_micros(500), "test");
let debug_str = format!("{:?}", result);
assert!(debug_str.contains("PerfResult"));
assert!(debug_str.contains("test"));
}
#[test]
fn test_simd_benchmark_creation() {
let benchmark = perf::SimdBenchmark::new();
}
#[test]
fn test_simd_benchmark_operations() {
use core::time::Duration;
let mut benchmark = perf::SimdBenchmark::new();
let result1 = perf::PerfResult::new(Duration::from_nanos(1000), "scalar");
let result2 = perf::PerfResult::new(Duration::from_nanos(500), "simd");
benchmark.record(result1);
benchmark.record(result2);
let ratio = benchmark.improvement_ratio("scalar", "simd");
assert!(ratio.is_some());
assert_eq!(ratio.unwrap(), 2.0); }
#[test]
fn test_simd_benchmark_missing_operations() {
use core::time::Duration;
let mut benchmark = perf::SimdBenchmark::new();
benchmark.record(perf::PerfResult::new(Duration::from_nanos(1000), "scalar"));
let ratio = benchmark.improvement_ratio("scalar", "missing_simd");
assert!(ratio.is_none());
let ratio2 = benchmark.improvement_ratio("missing_scalar", "simd");
assert!(ratio2.is_none());
}
#[test]
fn test_simd_benchmark_clone() {
use core::time::Duration;
let mut original = perf::SimdBenchmark::new();
original.record(perf::PerfResult::new(Duration::from_nanos(1000), "test"));
let cloned = original.clone();
}
}
#[test]
fn test_simd_alignment() {
let limbs = [1u64, 2, 3, 4];
let simd = SimdLimbs::from_limbs(&limbs);
let converted_back = simd.to_limbs();
assert_eq!(limbs, converted_back);
}
#[cfg(feature = "alloc")]
#[test]
fn test_simd_batch_empty_operations() {
let batch = SimdBatch::<u64>::new();
assert_eq!(batch.as_slice().len(), 0);
let empty_slice = batch.as_slice();
assert_eq!(empty_slice, &[]);
}
#[test]
fn test_simd_constant_time_considerations() {
let support1 = SimdLimbs::detect_simd_support();
let support2 = SimdLimbs::detect_simd_support();
let support3 = SimdLimbs::detect_simd_support();
assert_eq!(support1, support2);
assert_eq!(support2, support3);
}
}