| //! Projective arithmetic tests. |
| |
| #![cfg(all(feature = "arithmetic", feature = "test-vectors"))] |
| |
| use elliptic_curve::{ |
| sec1::{self, ToEncodedPoint}, |
| PrimeField, |
| }; |
| use p384::{ |
| test_vectors::group::{ADD_TEST_VECTORS, MUL_TEST_VECTORS}, |
| AffinePoint, ProjectivePoint, Scalar, |
| }; |
| use primeorder::Double; |
| |
| /// Assert that the provided projective point matches the given test vector. |
| // TODO(tarcieri): use coordinate APIs. See zkcrypto/group#30 |
| macro_rules! assert_point_eq { |
| ($actual:expr, $expected:expr) => { |
| let (expected_x, expected_y) = $expected; |
| |
| let point = $actual.to_affine().to_encoded_point(false); |
| let (actual_x, actual_y) = match point.coordinates() { |
| sec1::Coordinates::Uncompressed { x, y } => (x, y), |
| _ => unreachable!(), |
| }; |
| |
| assert_eq!(&expected_x, actual_x.as_slice()); |
| assert_eq!(&expected_y, actual_y.as_slice()); |
| }; |
| } |
| |
| #[test] |
| fn affine_to_projective() { |
| let basepoint_affine = AffinePoint::GENERATOR; |
| let basepoint_projective = ProjectivePoint::GENERATOR; |
| |
| assert_eq!( |
| ProjectivePoint::from(basepoint_affine), |
| basepoint_projective, |
| ); |
| assert_eq!(basepoint_projective.to_affine(), basepoint_affine); |
| assert!(!bool::from(basepoint_projective.to_affine().is_identity())); |
| assert!(bool::from( |
| ProjectivePoint::IDENTITY.to_affine().is_identity() |
| )); |
| } |
| |
| #[test] |
| fn projective_identity_addition() { |
| let identity = ProjectivePoint::IDENTITY; |
| let generator = ProjectivePoint::GENERATOR; |
| |
| assert_eq!(identity + &generator, generator); |
| assert_eq!(generator + &identity, generator); |
| } |
| |
| #[test] |
| fn test_vector_repeated_add() { |
| let generator = ProjectivePoint::GENERATOR; |
| let mut p = generator; |
| |
| for i in 0..ADD_TEST_VECTORS.len() { |
| assert_point_eq!(p, ADD_TEST_VECTORS[i]); |
| p += &generator; |
| } |
| } |
| |
| #[test] |
| fn test_vector_repeated_add_mixed() { |
| let generator = AffinePoint::GENERATOR; |
| let mut p = ProjectivePoint::GENERATOR; |
| |
| for i in 0..ADD_TEST_VECTORS.len() { |
| assert_point_eq!(p, ADD_TEST_VECTORS[i]); |
| p += &generator; |
| } |
| } |
| |
| #[test] |
| fn test_vector_add_mixed_identity() { |
| let generator = ProjectivePoint::GENERATOR; |
| let p0 = generator + ProjectivePoint::IDENTITY; |
| let p1 = generator + AffinePoint::IDENTITY; |
| assert_eq!(p0, p1); |
| } |
| |
| #[test] |
| fn test_vector_double_generator() { |
| let generator = ProjectivePoint::GENERATOR; |
| let mut p = generator; |
| |
| for i in 0..2 { |
| assert_point_eq!(p, ADD_TEST_VECTORS[i]); |
| p = p.double(); |
| } |
| } |
| |
| #[test] |
| fn projective_add_vs_double() { |
| let generator = ProjectivePoint::GENERATOR; |
| assert_eq!(generator + &generator, generator.double()); |
| } |
| |
| #[test] |
| fn projective_add_and_sub() { |
| let basepoint_affine = AffinePoint::GENERATOR; |
| let basepoint_projective = ProjectivePoint::GENERATOR; |
| |
| assert_eq!( |
| (basepoint_projective + &basepoint_projective) - &basepoint_projective, |
| basepoint_projective |
| ); |
| assert_eq!( |
| (basepoint_projective + &basepoint_affine) - &basepoint_affine, |
| basepoint_projective |
| ); |
| } |
| |
| #[test] |
| fn projective_double_and_sub() { |
| let generator = ProjectivePoint::GENERATOR; |
| assert_eq!(generator.double() - &generator, generator); |
| } |
| |
| #[test] |
| fn test_vector_scalar_mult() { |
| let generator = ProjectivePoint::GENERATOR; |
| |
| for (k, coords) in ADD_TEST_VECTORS |
| .iter() |
| .enumerate() |
| .map(|(k, coords)| (Scalar::from(k as u64 + 1), *coords)) |
| .chain( |
| MUL_TEST_VECTORS |
| .iter() |
| .cloned() |
| .map(|(k, x, y)| (Scalar::from_repr(k.into()).unwrap(), (x, y))), |
| ) |
| { |
| let p = generator * &k; |
| assert_point_eq!(p, coords); |
| } |
| } |