diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index d5f37a971f..7b0eb820ee 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -312,7 +312,7 @@ impl CurveProjective for Fr { ::is_zero(self) } - fn batch_normalization(_: &mut [Self]) { + fn batch_normalization>(_: &mut [S]) { } @@ -371,6 +371,29 @@ impl AsRef<[u8]> for FakePoint { } } +impl PartialEq for FakePoint { + fn eq(&self, other: &FakePoint) -> bool { + unimplemented!() + } +} +impl Eq for FakePoint { } +impl PartialOrd for FakePoint { + fn partial_cmp(&self, other: &FakePoint) -> Option<::std::cmp::Ordering> { + unimplemented!() + } +} +impl Ord for FakePoint { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + unimplemented!() + } +} + +impl ::std::hash::Hash for FakePoint { + fn hash(&self, state: &mut H) { + unimplemented!() + } +} + impl EncodedPoint for FakePoint { type Affine = Fr; diff --git a/group/src/lib.rs b/group/src/lib.rs index fc924c3743..54a9820c73 100644 --- a/group/src/lib.rs +++ b/group/src/lib.rs @@ -41,7 +41,7 @@ pub trait CurveProjective: /// Normalizes a slice of projective elements so that /// conversion to affine is cheap. - fn batch_normalization(v: &mut [Self]); + fn batch_normalization>(v: &mut [S]); /// Checks if the point is already "normalized" so that /// cheap affine conversion is possible. @@ -127,7 +127,8 @@ pub trait CurveAffine: /// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`. pub trait EncodedPoint: - Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static + Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + + PartialOrd + Ord + PartialEq + Eq + ::std::hash::Hash + 'static { type Affine: CurveAffine; diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index f5a6d8f4bc..2a86ef3d13 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -52,6 +52,12 @@ macro_rules! curve_impl { return false; } + if self.is_normalized() { + if other.is_normalized() { + return self.into_affine() == other.into_affine() + } + } + // The points (X, Y, Z) and (X', Y', Z') // are equal when (X * Z^2) = (X' * Z'^2) // and (Y * Z^3) = (Y' * Z'^3). @@ -247,7 +253,7 @@ macro_rules! curve_impl { self.is_zero() || self.z == $basefield::one() } - fn batch_normalization(v: &mut [Self]) + fn batch_normalization>(v: &mut [S]) { // Montgomery’s Trick and Fast Implementation of Masked AES // Genelle, Prouff and Quisquater @@ -256,7 +262,7 @@ macro_rules! curve_impl { // First pass: compute [a, ab, abc, ...] let mut prod = Vec::with_capacity(v.len()); let mut tmp = $basefield::one(); - for g in v.iter_mut() + for g in v.iter_mut().map(|g| g.borrow_mut()) // Ignore normalized elements .filter(|g| !g.is_normalized()) { @@ -268,7 +274,7 @@ macro_rules! curve_impl { tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. // Second pass: iterate backwards to compute inverses - for (g, s) in v.iter_mut() + for (g, s) in v.iter_mut().map(|g| g.borrow_mut()) // Backwards .rev() // Ignore normalized elements @@ -285,7 +291,7 @@ macro_rules! curve_impl { } // Perform affine transformations - for g in v.iter_mut() + for g in v.iter_mut().map(|g| g.borrow_mut()) .filter(|g| !g.is_normalized()) { let mut z = g.z; // 1/z @@ -624,6 +630,44 @@ macro_rules! curve_impl { } } +macro_rules! encoded_point_delegations { + ($t:ident) => { + impl AsRef<[u8]> for $t { + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + impl AsMut<[u8]> for $t { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0 + } + } + + impl PartialEq for $t { + fn eq(&self, other: &$t) -> bool { + PartialEq::eq(&self.0[..], &other.0[..]) + } + } + impl Eq for $t { } + impl PartialOrd for $t { + fn partial_cmp(&self, other: &$t) -> Option<::std::cmp::Ordering> { + PartialOrd::partial_cmp(&self.0[..], &other.0[..]) + } + } + impl Ord for $t { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + Ord::cmp(&self.0[..], &other.0[..]) + } + } + + impl ::std::hash::Hash for $t { + fn hash(&self, state: &mut H) { + self.0[..].hash(state); + } + } + } +} // encoded_point_delegations + pub mod g1 { use super::super::{Bls12, Fq, Fq12, FqRepr, Fr, FrRepr}; use super::g2::G2Affine; @@ -648,18 +692,8 @@ pub mod g1 { #[derive(Copy, Clone)] pub struct G1Uncompressed([u8; 96]); - impl AsRef<[u8]> for G1Uncompressed { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl AsMut<[u8]> for G1Uncompressed { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - } - + encoded_point_delegations!(G1Uncompressed); + impl fmt::Debug for G1Uncompressed { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.0[..].fmt(formatter) @@ -758,17 +792,7 @@ pub mod g1 { #[derive(Copy, Clone)] pub struct G1Compressed([u8; 48]); - impl AsRef<[u8]> for G1Compressed { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl AsMut<[u8]> for G1Compressed { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - } + encoded_point_delegations!(G1Compressed); impl fmt::Debug for G1Compressed { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { @@ -1295,17 +1319,7 @@ pub mod g2 { #[derive(Copy, Clone)] pub struct G2Uncompressed([u8; 192]); - impl AsRef<[u8]> for G2Uncompressed { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl AsMut<[u8]> for G2Uncompressed { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - } + encoded_point_delegations!(G2Uncompressed); impl fmt::Debug for G2Uncompressed { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { @@ -1421,17 +1435,7 @@ pub mod g2 { #[derive(Copy, Clone)] pub struct G2Compressed([u8; 96]); - impl AsRef<[u8]> for G2Compressed { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - impl AsMut<[u8]> for G2Compressed { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - } + encoded_point_delegations!(G2Compressed); impl fmt::Debug for G2Compressed { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {