diff --git a/Cargo.lock b/Cargo.lock index 39f29d385..5d9a348f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -403,8 +403,7 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" version = "0.14.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541598dba361b5ba0321caad955ba99ae82a604f4047c4f2743724996abf62f4" +source = "git+https://github.com/RustCrypto/traits#f24c2ae0b6ab6e897fab9645274d5c1d815e671e" dependencies = [ "base16ct", "base64ct", diff --git a/Cargo.toml b/Cargo.toml index 2d57d49d4..071db2023 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,6 @@ opt-level = 2 [patch.crates-io] primefield = { path = "primefield" } primeorder = { path = "primeorder" } + +# https://github.com/RustCrypto/traits/pull/1896 +elliptic-curve = { git = "https://github.com/RustCrypto/traits" } diff --git a/k256/src/arithmetic/projective.rs b/k256/src/arithmetic/projective.rs index 0e1cad2d9..04d8b059b 100644 --- a/k256/src/arithmetic/projective.rs +++ b/k256/src/arithmetic/projective.rs @@ -257,10 +257,10 @@ impl From for ProjectivePoint { } impl BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint { - type Output = [Self::AffineRepr; N]; + type Output = [::AffineRepr; N]; #[inline] - fn batch_normalize(points: &[Self; N]) -> [Self::AffineRepr; N] { + fn batch_normalize(points: &[Self; N]) -> [::AffineRepr; N] { let zs = [FieldElement::ONE; N]; let mut affine_points = [AffinePoint::IDENTITY; N]; batch_normalize_generic(points, zs, &mut affine_points); @@ -270,10 +270,10 @@ impl BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint { #[cfg(feature = "alloc")] impl BatchNormalize<[ProjectivePoint]> for ProjectivePoint { - type Output = Vec; + type Output = Vec<::AffineRepr>; #[inline] - fn batch_normalize(points: &[Self]) -> Vec { + fn batch_normalize(points: &[Self]) -> Vec<::AffineRepr> { let zs = vec![FieldElement::ONE; points.len()]; let mut affine_points = vec![AffinePoint::IDENTITY; points.len()]; batch_normalize_generic(points, zs, &mut affine_points); diff --git a/p256/tests/projective.rs b/p256/tests/projective.rs index e57808cbd..0044a3e8f 100644 --- a/p256/tests/projective.rs +++ b/p256/tests/projective.rs @@ -3,14 +3,18 @@ #![cfg(all(feature = "arithmetic", feature = "test-vectors"))] use elliptic_curve::{ + BatchNormalize, group::{GroupEncoding, ff::PrimeField}, + ops::ReduceNonZero, + point::NonIdentity, sec1::{self, ToEncodedPoint}, }; use p256::{ - AffinePoint, ProjectivePoint, Scalar, + AffinePoint, NonZeroScalar, ProjectivePoint, Scalar, test_vectors::group::{ADD_TEST_VECTORS, MUL_TEST_VECTORS}, }; use primeorder::{Double, test_projective_arithmetic}; +use proptest::{prelude::any, prop_compose, proptest}; test_projective_arithmetic!( AffinePoint, @@ -25,3 +29,41 @@ fn projective_identity_to_bytes() { // This is technically an invalid SEC1 encoding, but is preferable to panicking. assert_eq!([0; 33], ProjectivePoint::IDENTITY.to_bytes().as_slice()); } + +prop_compose! { + fn non_identity()(bytes in any::<[u8; 32]>()) -> NonIdentity { + NonIdentity::mul_by_generator(&NonZeroScalar::reduce_nonzero_bytes(&bytes.into())) + } +} + +// TODO: move to `primeorder::test_projective_arithmetic`. +proptest! { + #[test] + fn batch_normalize( + a in non_identity(), + b in non_identity(), + ) { + let points: [NonIdentity; 2] = [a, b]; + + let affine_points = NonIdentity::batch_normalize(&points); + + for (point, affine_point) in points.into_iter().zip(affine_points) { + assert_eq!(affine_point, point.to_affine()); + } + } + + #[test] + #[cfg(feature = "alloc")] + fn batch_normalize_alloc( + a in non_identity(), + b in non_identity(), + ) { + let points = vec![a, b]; + + let affine_points = NonIdentity::batch_normalize(points.as_slice()); + + for (point, affine_point) in points.into_iter().zip(affine_points) { + assert_eq!(affine_point, point.to_affine()); + } + } +} diff --git a/primeorder/src/projective.rs b/primeorder/src/projective.rs index b4419a0c6..46d179477 100644 --- a/primeorder/src/projective.rs +++ b/primeorder/src/projective.rs @@ -13,7 +13,7 @@ use elliptic_curve::{ array::ArraySize, bigint::ArrayEncoding, group::{ - self, Group, GroupEncoding, + Curve, Group, GroupEncoding, prime::{PrimeCurve, PrimeGroup}, }, ops::{BatchInvert, LinearCombination}, @@ -308,7 +308,7 @@ where } } -impl group::Curve for ProjectivePoint +impl Curve for ProjectivePoint where Self: Double, C: PrimeCurveParams, @@ -333,10 +333,10 @@ where Self: Double, C: PrimeCurveParams, { - type Output = [Self::AffineRepr; N]; + type Output = [::AffineRepr; N]; #[inline] - fn batch_normalize(points: &[Self; N]) -> [Self::AffineRepr; N] { + fn batch_normalize(points: &[Self; N]) -> [::AffineRepr; N] { let zs = [C::FieldElement::ONE; N]; let mut affine_points = [C::AffinePoint::IDENTITY; N]; batch_normalize_generic(points, zs, &mut affine_points); @@ -350,10 +350,10 @@ where Self: Double, C: PrimeCurveParams, { - type Output = Vec; + type Output = Vec<::AffineRepr>; #[inline] - fn batch_normalize(points: &[Self]) -> Vec { + fn batch_normalize(points: &[Self]) -> Vec<::AffineRepr> { let mut zs = vec![C::FieldElement::ONE; points.len()]; let mut affine_points = vec![AffinePoint::IDENTITY; points.len()]; batch_normalize_generic(points, zs.as_mut_slice(), &mut affine_points);