diff --git a/mod.rs b/mod.rs index 1dd0bfe..2827de0 100644 --- a/mod.rs +++ b/mod.rs @@ -5,6 +5,7 @@ pub mod protobuf_impl; mod serde_impl; use std::fmt; +use std::hash::{Hash, Hasher}; use byteorder::{BigEndian, ByteOrder}; use init_with::InitWith; @@ -31,6 +32,12 @@ impl PartialEq for PublicKey { } } +impl Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.0.into_affine().into_compressed().as_ref().hash(state); + } +} + impl PublicKey { /// Returns `true` if the signature matches the element of `E::G2`. pub fn verify_g2>(&self, sig: &Signature, hash: H) -> bool { @@ -85,6 +92,12 @@ impl PartialEq for Signature { } } +impl Hash for Signature { + fn hash(&self, state: &mut H) { + self.0.into_affine().into_compressed().as_ref().hash(state); + } +} + impl Signature { pub fn parity(&self) -> bool { let uncomp = self.0.into_affine().into_uncompressed(); @@ -160,6 +173,14 @@ impl PartialEq for Ciphertext { } } +impl Hash for Ciphertext { + fn hash(&self, state: &mut H) { + self.0.into_affine().into_compressed().as_ref().hash(state); + self.1.hash(state); + self.2.into_affine().into_compressed().as_ref().hash(state); + } +} + impl Ciphertext { /// Returns `true` if this is a valid ciphertext. This check is necessary to prevent /// chosen-ciphertext attacks. @@ -180,8 +201,14 @@ impl PartialEq for DecryptionShare { } } +impl Hash for DecryptionShare { + fn hash(&self, state: &mut H) { + self.0.into_affine().into_compressed().as_ref().hash(state); + } +} + /// A public key and an associated set of public key shares. -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Hash)] pub struct PublicKeySet { /// The coefficients of a polynomial whose value at `0` is the "master key", and value at /// `i + 1` is key share number `i`. diff --git a/poly.rs b/poly.rs index 989a875..7479f25 100644 --- a/poly.rs +++ b/poly.rs @@ -20,6 +20,7 @@ // TODO: Expand this explanation and add examples, once the API is complete and stable. use std::borrow::Borrow; +use std::hash::{Hash, Hasher}; use std::{cmp, iter, ops}; use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField}; @@ -261,6 +262,15 @@ impl PartialEq for Commitment { } } +impl Hash for Commitment { + fn hash(&self, state: &mut H) { + self.coeff.len().hash(state); + for c in &self.coeff { + c.into_affine().into_compressed().as_ref().hash(state); + } + } +} + impl>, E: Engine> ops::AddAssign for Commitment { fn add_assign(&mut self, rhs: B) { let len = cmp::max(self.coeff.len(), rhs.borrow().coeff.len()); @@ -403,6 +413,15 @@ pub struct BivarCommitment { coeff: Vec, } +impl Hash for BivarCommitment { + fn hash(&self, state: &mut H) { + self.degree.hash(state); + for c in &self.coeff { + c.into_affine().into_compressed().as_ref().hash(state); + } + } +} + impl BivarCommitment { /// Returns the polynomial's degree: It is the same in both variables. pub fn degree(&self) -> usize {