From d7e84fba18ab85f4c242b13e9d12ca45ec4d35af Mon Sep 17 00:00:00 2001 From: Jeff Burdges Date: Sun, 23 Jun 2019 17:00:30 +0200 Subject: [PATCH 1/4] Impl PartialEq, Eq, PartialOrd, Ord, Hash for EncodedPoint And consolodate Impl AsRef and AsMut as well --- group/src/lib.rs | 3 +- pairing/src/bls12_381/ec.rs | 88 ++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/group/src/lib.rs b/group/src/lib.rs index fc924c3743..4cb9c60c88 100644 --- a/group/src/lib.rs +++ b/group/src/lib.rs @@ -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..14316acc0a 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -624,6 +624,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 +686,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 +786,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 +1313,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 +1429,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> { From c02a4cc89dc14d6f8613fd47f774a54eee695133 Mon Sep 17 00:00:00 2001 From: Jeff Burdges Date: Sun, 23 Jun 2019 17:06:19 +0200 Subject: [PATCH 2/4] Make batch_normalization more flexible with BorrowMut --- group/src/lib.rs | 2 +- pairing/src/bls12_381/ec.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/group/src/lib.rs b/group/src/lib.rs index 4cb9c60c88..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. diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index 14316acc0a..6bcd59d802 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -247,7 +247,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 +256,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 +268,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 +285,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 From 781a48482f05c492852bf0f5b174070227310380 Mon Sep 17 00:00:00 2001 From: Jeff Burdges Date: Sun, 23 Jun 2019 17:10:03 +0200 Subject: [PATCH 3/4] Make Eq return faster in more cases. In fact is_normalized() and From<$projective>: $affine cover the is_zero() special case because they handle the is_zero() special case themselves. I kept the is_zero() special case here for robustness against future modifications, but you may wish to remove it. --- pairing/src/bls12_381/ec.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index 6bcd59d802..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). From bb638b220e515efc244499aef9f0ae5a71079809 Mon Sep 17 00:00:00 2001 From: Jeff Burdges Date: Sun, 23 Jun 2019 17:42:02 +0200 Subject: [PATCH 4/4] oops, looks like bellman makes a point type --- bellman/src/groth16/tests/dummy_engine.rs | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) 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;