use super::super::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
use rand_core::OsRng;
use subtle::{Choice, ConditionallySelectable};
#[test]
fn test_g1_identity_operations() {
let identity = G1Projective::identity();
let g = G1Projective::generator();
let point = g * Scalar::from(42u64);
assert_eq!(G1Affine::from(identity + point), G1Affine::from(point));
assert_eq!(G1Affine::from(point + identity), G1Affine::from(point));
let scalar = Scalar::from(42u64);
assert_eq!(identity * scalar, identity);
assert_eq!(identity.double(), identity);
assert_eq!(-identity, identity);
}
#[test]
fn test_g1_associativity() {
let g = G1Projective::generator();
let p = g * Scalar::from(2u64);
let q = g * Scalar::from(3u64);
let r = g * Scalar::from(5u64);
let sum1 = (p + q) + r;
let sum2 = p + (q + r);
assert_eq!(G1Affine::from(sum1), G1Affine::from(sum2));
}
#[test]
fn test_g1_commutativity() {
let g = G1Projective::generator();
let p = g * Scalar::from(7u64);
let q = g * Scalar::from(11u64);
assert_eq!(G1Affine::from(p + q), G1Affine::from(q + p));
}
#[test]
fn test_g1_scalar_multiplication_distributivity() {
let p = G1Projective::generator();
let a = Scalar::from(42u64);
let b = Scalar::from(69u64);
let left = p * (a + b);
let right = (p * a) + (p * b);
assert_eq!(G1Affine::from(left), G1Affine::from(right));
let left = p * (a * b);
let right = (p * b) * a;
assert_eq!(G1Affine::from(left), G1Affine::from(right));
}
#[test]
fn test_g1_double_vs_add() {
let g1 = G1Projective::generator();
let p = g1 * Scalar::from(42u64);
assert_eq!(G1Affine::from(p.double()), G1Affine::from(p + p));
}
#[test]
fn test_g1_mixed_addition_consistency() {
let g = G1Projective::generator();
let p_proj = g * Scalar::from(13u64);
let q_proj = g * Scalar::from(17u64);
let p_aff = G1Affine::from(p_proj);
let q_aff = G1Affine::from(q_proj);
let result1 = p_proj + q_proj;
let result2 = p_proj + q_aff;
let result3 = p_aff + q_proj;
let result4 = G1Projective::from(p_aff) + G1Projective::from(q_aff);
let aff1 = G1Affine::from(result1);
let aff2 = G1Affine::from(result2);
let aff3 = G1Affine::from(result3);
let aff4 = G1Affine::from(result4);
assert_eq!(aff1, aff2);
assert_eq!(aff1, aff3);
assert_eq!(aff1, aff4);
}
#[test]
fn test_g1_batch_normalize() {
let g = G1Projective::generator();
let points: Vec<G1Projective> = (1..=10).map(|i| g * Scalar::from(i as u64)).collect();
let mut batch_result = vec![G1Affine::identity(); points.len()];
G1Projective::batch_normalize(&points, &mut batch_result);
for (proj, batch_aff) in points.iter().zip(batch_result.iter()) {
let individual_aff = G1Affine::from(proj);
assert_eq!(individual_aff, *batch_aff);
}
}
#[test]
fn test_g1_batch_normalize_with_identity() {
let points = vec![
G1Projective::generator(),
G1Projective::identity(),
G1Projective::generator().double(),
G1Projective::identity(),
];
let mut batch_result = vec![G1Affine::identity(); points.len()];
G1Projective::batch_normalize(&points, &mut batch_result);
assert_eq!(batch_result[0], G1Affine::generator());
assert_eq!(batch_result[1], G1Affine::identity());
assert_eq!(
batch_result[2],
G1Affine::from(G1Projective::generator().double())
);
assert_eq!(batch_result[3], G1Affine::identity());
}
#[test]
fn test_g1_conditional_select() {
let p = G1Projective::random(&mut OsRng);
let q = G1Projective::random(&mut OsRng);
let selected =
<G1Projective as ConditionallySelectable>::conditional_select(&p, &q, Choice::from(0u8));
assert_eq!(selected, p);
let selected =
<G1Projective as ConditionallySelectable>::conditional_select(&p, &q, Choice::from(1u8));
assert_eq!(selected, q);
}
#[test]
fn test_g1_sum() {
let g = G1Projective::generator();
let points: Vec<G1Projective> = (1..=5).map(|i| g * Scalar::from(i as u64)).collect();
let mut manual_sum = G1Projective::identity();
for p in &points {
manual_sum += p;
}
let trait_sum: G1Projective = points.iter().map(|p| p.clone()).sum();
assert_eq!(G1Affine::from(manual_sum), G1Affine::from(trait_sum));
}
#[test]
fn test_g2_identity_operations() {
let identity = G2Projective::identity();
let g = G2Projective::generator();
let point = g * Scalar::from(42u64);
assert_eq!(G2Affine::from(identity + point), G2Affine::from(point));
assert_eq!(G2Affine::from(point + identity), G2Affine::from(point));
let scalar = Scalar::from(42u64);
assert_eq!(identity * scalar, identity);
assert_eq!(identity.double(), identity);
assert_eq!(-identity, identity);
}
#[test]
fn test_g2_associativity() {
let g = G2Projective::generator();
let p = g * Scalar::from(2u64);
let q = g * Scalar::from(3u64);
let r = g * Scalar::from(5u64);
let sum1 = (p + q) + r;
let sum2 = p + (q + r);
assert_eq!(G2Affine::from(sum1), G2Affine::from(sum2));
}
#[test]
fn test_g2_commutativity() {
let g = G2Projective::generator();
let p = g * Scalar::from(7u64);
let q = g * Scalar::from(11u64);
assert_eq!(G2Affine::from(p + q), G2Affine::from(q + p));
}
#[test]
fn test_g2_scalar_multiplication_distributivity() {
let p = G2Projective::generator();
let a = Scalar::from(42u64);
let b = Scalar::from(69u64);
let left = p * (a + b);
let right = (p * a) + (p * b);
assert_eq!(G2Affine::from(left), G2Affine::from(right));
let left = p * (a * b);
let right = (p * b) * a;
assert_eq!(G2Affine::from(left), G2Affine::from(right));
}
#[test]
fn test_g2_double_vs_add() {
let g2 = G2Projective::generator();
let q = g2 * Scalar::from(42u64);
assert_eq!(G2Affine::from(q.double()), G2Affine::from(q + q));
}
#[test]
fn test_g2_batch_normalize() {
let g = G2Projective::generator();
let points: Vec<G2Projective> = (1..=10).map(|i| g * Scalar::from(i as u64)).collect();
let mut batch_result = vec![G2Affine::identity(); points.len()];
G2Projective::batch_normalize(&points, &mut batch_result);
for (proj, batch_aff) in points.iter().zip(batch_result.iter()) {
let individual_aff = G2Affine::from(proj);
assert_eq!(individual_aff, *batch_aff);
}
}
#[test]
fn test_g2_conditional_select() {
let p = G2Projective::random(&mut OsRng);
let q = G2Projective::random(&mut OsRng);
let selected =
<G2Projective as ConditionallySelectable>::conditional_select(&p, &q, Choice::from(0u8));
assert_eq!(selected, p);
let selected =
<G2Projective as ConditionallySelectable>::conditional_select(&p, &q, Choice::from(1u8));
assert_eq!(selected, q);
}
#[test]
fn test_g2_sum() {
let g = G2Projective::generator();
let points: Vec<G2Projective> = (1..=5).map(|i| g * Scalar::from(i as u64)).collect();
let mut manual_sum = G2Projective::identity();
for p in &points {
manual_sum += p;
}
let trait_sum: G2Projective = points.iter().map(|p| p.clone()).sum();
assert_eq!(G2Affine::from(manual_sum), G2Affine::from(trait_sum));
}
#[test]
fn test_scalar_edge_cases() {
let p = G1Projective::generator();
assert_eq!(p * Scalar::zero(), G1Projective::identity());
assert_eq!(p * Scalar::one(), p);
let minus_one = Scalar::zero() - Scalar::one();
let p_times_minus_one = p * minus_one;
let minus_p = -p;
assert_eq!(G1Affine::from(p_times_minus_one), G1Affine::from(minus_p));
let q = G2Projective::generator();
assert_eq!(q * Scalar::zero(), G2Projective::identity());
assert_eq!(q * Scalar::one(), q);
let q_times_minus_one = q * minus_one;
let minus_q = -q;
assert_eq!(G2Affine::from(q_times_minus_one), G2Affine::from(minus_q));
}
#[test]
fn test_scalar_sum_and_product() {
let scalars: Vec<Scalar> = (0..5).map(|i| Scalar::from((i + 1) as u64)).collect();
let expected_sum = Scalar::from(15u64); let actual_sum: Scalar = scalars.iter().map(|s| *s).sum();
assert_eq!(expected_sum, actual_sum);
let expected_product = Scalar::from(120u64); let actual_product: Scalar = scalars.iter().map(|s| *s).product();
assert_eq!(expected_product, actual_product);
}
#[test]
fn test_g1_torsion_free() {
assert!(bool::from(G1Affine::generator().is_torsion_free()));
assert!(bool::from(G1Affine::identity().is_torsion_free()));
let g = G1Projective::generator();
for i in 1..=10 {
let point = g * Scalar::from(i as u64);
let cleared = point.clear_cofactor();
assert!(bool::from(G1Affine::from(cleared).is_torsion_free()));
}
}
#[test]
fn test_g2_torsion_free() {
assert!(bool::from(G2Affine::generator().is_torsion_free()));
assert!(bool::from(G2Affine::identity().is_torsion_free()));
let g = G2Projective::generator();
for i in 1..=10 {
let point = g * Scalar::from(i as u64);
let cleared = point.clear_cofactor();
assert!(bool::from(G2Affine::from(cleared).is_torsion_free()));
}
}
#[test]
fn test_cofactor_clearing() {
let g1 = G1Projective::generator();
for i in 1..=5 {
let p1 = g1 * Scalar::from(i as u64);
let p1_cleared = p1.clear_cofactor();
assert!(bool::from(G1Affine::from(p1_cleared).is_torsion_free()));
}
let g2 = G2Projective::generator();
for i in 1..=5 {
let p2 = g2 * Scalar::from(i as u64);
let p2_cleared = p2.clear_cofactor();
assert!(bool::from(G2Affine::from(p2_cleared).is_torsion_free()));
}
}
#[test]
fn test_g1_endomorphism() {
let g = G1Projective::generator();
let p = g * Scalar::from(42u64);
let cleared = p.clear_cofactor();
let cleared_affine = G1Affine::from(cleared);
assert!(bool::from(cleared_affine.is_on_curve()));
assert!(bool::from(cleared_affine.is_torsion_free()));
}