blob: 95ad0a623d2bd27f7e575390e614284ec400824d [file] [log] [blame] [edit]
//! 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);
}
}