diff --git a/Cargo.lock b/Cargo.lock index 1bce1d1c..d1bf7315 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,7 +372,7 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" version = "0.13.6" -source = "git+https://github.com/ycscaly/traits?branch=batch_invert#b6061bd0433d357dc006f3b17c196f27d9d024f3" +source = "git+https://github.com/ycscaly/traits?branch=batch_invert#822a1ba8b67e8c4edef1c16506363243b3da061d" dependencies = [ "base16ct", "base64ct", diff --git a/k256/src/arithmetic/field.rs b/k256/src/arithmetic/field.rs index 78547ac9..6b8db0d2 100644 --- a/k256/src/arithmetic/field.rs +++ b/k256/src/arithmetic/field.rs @@ -702,7 +702,8 @@ mod tests { let l: FieldElement = FieldElement::random(&mut OsRng); let expected = proptest::std_facade::vec![k.invert().unwrap(), l.invert().unwrap()]; - let res: alloc::vec::Vec<_> = ::batch_invert(&[k, l]).unwrap(); + let res: alloc::vec::Vec<_> = + ::batch_invert_slice(&[k, l]).unwrap(); assert_eq!(res, expected); } diff --git a/k256/src/arithmetic/projective.rs b/k256/src/arithmetic/projective.rs index d4f3ecd3..f82b1f57 100644 --- a/k256/src/arithmetic/projective.rs +++ b/k256/src/arithmetic/projective.rs @@ -254,13 +254,7 @@ impl From for ProjectivePoint { } impl Normalize for ProjectivePoint { - type AffinePoint = AffinePoint; - - fn to_affine(&self) -> Self::AffinePoint { - ProjectivePoint::to_affine(self) - } - - fn batch_normalize_array(points: &[Self; N]) -> [Self::AffinePoint; N] { + fn batch_normalize_array(points: &[Self; N]) -> [Self::AffineRepr; N] { let mut zs = [FieldElement::ONE; N]; for i in 0..N { @@ -287,8 +281,13 @@ impl Normalize for ProjectivePoint { affine_points } + #[cfg(not(feature = "alloc"))] + fn batch_normalize_slice>(_points: &[Self]) -> B { + todo!() + } + #[cfg(feature = "alloc")] - fn batch_normalize>(points: &[Self]) -> B { + fn batch_normalize_slice>(points: &[Self]) -> B { let mut zs: alloc::vec::Vec<_> = (0..points.len()).map(|_| FieldElement::ONE).collect(); for i in 0..points.len() { @@ -302,7 +301,7 @@ impl Normalize for ProjectivePoint { // This is safe to unwrap since we assured that all elements are non-zero let zs_inverses: alloc::vec::Vec<_> = - ::batch_invert(zs.as_slice()).unwrap(); + ::batch_invert_slice(zs.as_slice()).unwrap(); let mut affine_points: alloc::vec::Vec<_> = (0..points.len()).map(|_| AffinePoint::IDENTITY).collect(); @@ -449,6 +448,7 @@ impl GroupEncoding for ProjectivePoint { impl PrimeGroup for ProjectivePoint {} +#[cfg(not(feature = "alloc"))] impl Curve for ProjectivePoint { type AffineRepr = AffinePoint; @@ -456,6 +456,23 @@ impl Curve for ProjectivePoint { ProjectivePoint::to_affine(self) } } +#[cfg(feature = "alloc")] +impl Curve for ProjectivePoint { + type AffineRepr = AffinePoint; + + fn to_affine(&self) -> AffinePoint { + ProjectivePoint::to_affine(self) + } + + fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) { + assert_eq!(p.len(), q.len()); + + let affine_points: alloc::vec::Vec<_> = ::batch_normalize_slice(p); + for i in 0..q.len() { + q[i] = affine_points[i]; + } + } +} impl PrimeCurve for ProjectivePoint { type Affine = AffinePoint; @@ -679,7 +696,7 @@ mod tests { use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine}; use elliptic_curve::ops::MulByGenerator; use elliptic_curve::Field; - use elliptic_curve::Normalize; + use elliptic_curve::{group, Normalize}; use rand_core::OsRng; #[test] @@ -700,42 +717,62 @@ mod tests { } #[test] - fn to_affine_batch_generic() { + fn batch_normalize_array() { let k: Scalar = Scalar::random(&mut OsRng); let l: Scalar = Scalar::random(&mut OsRng); let g = ProjectivePoint::mul_by_generator(&k); let h = ProjectivePoint::mul_by_generator(&l); + let mut res = [AffinePoint::IDENTITY; 2]; let expected = [g.to_affine(), h.to_affine()]; assert_eq!( ::batch_normalize_array(&[g, h]), expected ); + ::batch_normalize(&[g, h], &mut res); + assert_eq!(res, expected); + let expected = [g.to_affine(), AffinePoint::IDENTITY]; assert_eq!( ::batch_normalize_array(&[g, ProjectivePoint::IDENTITY]), expected ); + + ::batch_normalize( + &[g, ProjectivePoint::IDENTITY], + &mut res, + ); + assert_eq!(res, expected); } #[test] #[cfg(feature = "alloc")] - fn to_affine_batch() { + fn batch_normalize_slice() { let k: Scalar = Scalar::random(&mut OsRng); let l: Scalar = Scalar::random(&mut OsRng); let g = ProjectivePoint::mul_by_generator(&k); let h = ProjectivePoint::mul_by_generator(&l); let expected = proptest::std_facade::vec![g.to_affine(), h.to_affine()]; - let res: alloc::vec::Vec<_> = ::batch_normalize(&[g, h]); + let mut res: alloc::vec::Vec<_> = + ::batch_normalize_slice(&[g, h]); assert_eq!(res, expected); + ::batch_normalize(&[g, h], res.as_mut()); + assert_eq!(res.to_vec(), expected); + let expected = proptest::std_facade::vec![g.to_affine(), AffinePoint::IDENTITY]; - let res: alloc::vec::Vec<_> = - ::batch_normalize(&[g, ProjectivePoint::IDENTITY]); + res = + ::batch_normalize_slice(&[g, ProjectivePoint::IDENTITY]); assert_eq!(res, expected); + + ::batch_normalize( + &[g, ProjectivePoint::IDENTITY], + res.as_mut(), + ); + assert_eq!(res.to_vec(), expected); } #[test] diff --git a/k256/src/arithmetic/scalar.rs b/k256/src/arithmetic/scalar.rs index 4cd018df..6eb60a5d 100644 --- a/k256/src/arithmetic/scalar.rs +++ b/k256/src/arithmetic/scalar.rs @@ -969,7 +969,7 @@ mod tests { let l: Scalar = Scalar::random(&mut OsRng); let expected = proptest::std_facade::vec![k.invert().unwrap(), l.invert().unwrap()]; - let res: alloc::vec::Vec<_> = ::batch_invert(&[k, l]).unwrap(); + let res: alloc::vec::Vec<_> = ::batch_invert_slice(&[k, l]).unwrap(); assert_eq!(res, expected); }