clock-curve-math 1.1.3

High-performance, constant-time, cryptography-grade number theory library for ClockCurve ecosystem
Documentation
//! Integration tests for cross-module functionality.
//!
//! These tests verify that different modules work correctly together,
//! providing end-to-end validation of the cryptographic operations.

use clock_curve_math::*;

/// Test that FieldElement operations are consistent
#[test]
fn test_field_element_consistency() {
    // Create FieldElements
    let fe1 = FieldElement::from_u64(42);
    let fe2 = FieldElement::from_u64(58);

    // Test arithmetic operations
    let sum = fe1.add(&fe2);
    assert!(sum.is_valid());

    // Test commutativity
    let sum2 = fe2.add(&fe1);
    assert_eq!(sum, sum2);

    // Test multiplication
    let product = fe1.mul(&fe2);
    assert!(product.is_valid());
}

/// Test that Scalar operations work correctly
#[test]
fn test_scalar_bigint_integration() {
    // Create Scalars
    let scalar1 = Scalar::from_u64(12345);
    let scalar2 = Scalar::from_u64(67890);

    // Test arithmetic operations
    let sum = scalar1.add(&scalar2);
    let expected_sum = Scalar::from_u64(12345 + 67890);
    assert_eq!(sum, expected_sum);

    // Test multiplication
    let product = scalar1.mul(&scalar2);
    // Just verify it's a valid scalar
    assert!(product.is_valid());
}

/// Test basic FieldElement operations
#[test]
fn test_basic_field_operations() {
    let fe1 = FieldElement::from_u64(1000);
    let fe2 = FieldElement::from_u64(2000);

    // Test addition
    let sum = fe1.add(&fe2);
    assert!(sum.is_valid());

    // Test that operations are consistent
    let sum2 = fe2.add(&fe1);
    assert_eq!(sum, sum2); // Commutativity

    // Test multiplication
    let product = fe1.mul(&fe2);
    assert!(product.is_valid());
}

/// Test field and scalar arithmetic properties
#[test]
fn test_field_scalar_arithmetic_properties() {
    // Test that scalar arithmetic works
    let x = Scalar::from_u64(5);
    let y = Scalar::from_u64(7);
    let z = Scalar::from_u64(11);

    // Test associativity for scalars
    let s_left = x.add(&y).add(&z);
    let s_right = x.add(&y.add(&z));
    assert_eq!(s_left, s_right);

    // Test that results are valid
    assert!(s_left.is_valid());
    assert!(s_right.is_valid());
}

/// Test error handling integration
#[test]
fn test_error_handling_integration() {
    // Test invalid byte values for FieldElement (too large)
    let mut large_bytes = [0xFFu8; 32];
    large_bytes[31] = 0xFF; // Make it larger than p
    assert!(FieldElement::from_bytes(&large_bytes).is_err());

    // Test invalid byte values for Scalar (too large)
    assert!(Scalar::from_bytes(&large_bytes).is_err());

    // Test valid values
    let valid_bytes = [0u8; 32];
    assert!(FieldElement::from_bytes(&valid_bytes).is_ok());
    assert!(Scalar::from_bytes(&valid_bytes).is_ok());
}

/// Test mixed operations between field elements and scalars
#[test]
fn test_mixed_operations() {
    // While field elements and scalars are different types,
    // they should both support similar operations
    let fe = FieldElement::from_u64(42);
    let scalar = Scalar::from_u64(42);

    // Both should be able to perform addition
    let fe_result = fe.add(&FieldElement::from_u64(8));
    let scalar_result = scalar.add(&Scalar::from_u64(8));

    // Results should be different due to different moduli
    // We can't directly compare the internal representations, but we can verify both are valid
    assert!(fe_result.is_valid());
    assert!(scalar_result.is_valid());
}

/// Test clock-bigint backend specific operations
#[cfg(feature = "bigint-backend")]
#[test]
fn test_bigint_backend_integration() {
    use clock_curve_math::bigint::BigInt;
    use clock_curve_math::{ONE, ZERO};

    // Test basic BigInt creation and operations
    let a = BigInt::from_u64(12345);
    let b = BigInt::from_u64(67890);

    // Test addition
    let sum = a.add(&b);
    let expected_sum = BigInt::from_u64(12345 + 67890);
    assert_eq!(sum, expected_sum);

    // Test multiplication
    let product = a.mul(&b);
    // BigInt doesn't have is_valid, but we can verify it's not zero for this test
    assert!(!product.is_zero());

    // Test comparison with known values
    assert!(ZERO().is_zero());
    // Check that one is not zero
    assert!(!ONE().is_zero());
    assert!(!a.is_zero());
    // Verify one equals BigInt::from_u64(1)
    assert_eq!(ONE(), BigInt::from_u64(1));
}

/// Test custom-limbs backend specific operations
#[cfg(feature = "custom-limbs")]
#[test]
fn test_custom_limbs_backend_integration() {
    use clock_curve_math::bigint::{BigInt, BigIntOps};
    use clock_curve_math::{ONE, ZERO};

    // Test basic BigInt creation and operations
    let a = BigInt::from_u64(12345);
    let b = BigInt::from_u64(67890);

    // Test addition
    let sum = a.add(&b);
    let expected_sum = BigInt::from_u64(12345 + 67890);
    assert_eq!(sum, expected_sum);

    // Test multiplication
    let product = a.mul(&b);
    // BigInt doesn't have is_valid, but we can verify it's not zero for this test
    assert!(!product.is_zero());

    // Test comparison with known values
    assert!(ZERO().is_zero());
    // Check that one is not zero
    assert!(!ONE().is_zero());
    assert!(!a.is_zero());
    // Verify one equals BigInt::from_u64(1)
    assert_eq!(ONE(), BigInt::from_u64(1));
}

/// Test that both backends produce identical results for basic operations
#[test]
fn test_backend_consistency_basic_ops() {
    // This test will only compile when both backends are available
    // In practice, this would require conditional compilation or separate test binaries
    // For now, we test the active backend thoroughly

    // Test field element operations across different backends
    let fe1 = FieldElement::from_u64(42);
    let fe2 = FieldElement::from_u64(58);

    // Test commutativity (should work regardless of backend)
    let sum1 = fe1.add(&fe2);
    let sum2 = fe2.add(&fe1);
    assert_eq!(sum1, sum2);
    assert!(sum1.is_valid());

    // Test scalar operations
    let s1 = Scalar::from_u64(123);
    let s2 = Scalar::from_u64(456);

    let s_sum1 = s1.add(&s2);
    let s_sum2 = s2.add(&s1);
    assert_eq!(s_sum1, s_sum2);
    assert!(s_sum1.is_valid());
}

/// Test that field and scalar operations work correctly with current backend
#[test]
fn test_field_scalar_backend_integration() {
    // Create test values
    let field_vals = [1u64, 42, 12345, 999999];
    let scalar_vals = [2u64, 58, 67890, 111111];

    for &f_val in &field_vals {
        for &s_val in &scalar_vals {
            let fe = FieldElement::from_u64(f_val);
            let scalar = Scalar::from_u64(s_val);

            // Test that operations complete successfully
            let fe_sum = fe.add(&FieldElement::from_u64(s_val));
            let scalar_sum = scalar.add(&Scalar::from_u64(f_val));

            // Verify results are valid
            assert!(fe_sum.is_valid());
            assert!(scalar_sum.is_valid());

            // Test multiplication
            let fe_prod = fe.mul(&FieldElement::from_u64(s_val));
            let scalar_prod = scalar.mul(&Scalar::from_u64(f_val));

            assert!(fe_prod.is_valid());
            assert!(scalar_prod.is_valid());
        }
    }
}