Implement Hash for "public" cryptographic types.

This adds a `Hash` implementation for public keys, commitments,
ciphertexts and signatures — types that might make sense to be included
in special transactions. The `DynamicHoneyBadger` implementation will
require some of them.
master
Andreas Fackler 7 years ago committed by Vladimir Komendantskiy
parent cf1782b2cf
commit db1de60237
  1. 29
      mod.rs
  2. 19
      poly.rs

@ -5,6 +5,7 @@ pub mod protobuf_impl;
mod serde_impl; mod serde_impl;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher};
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use init_with::InitWith; use init_with::InitWith;
@ -31,6 +32,12 @@ impl<E: Engine> PartialEq for PublicKey<E> {
} }
} }
impl<E: Engine> Hash for PublicKey<E> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.into_affine().into_compressed().as_ref().hash(state);
}
}
impl<E: Engine> PublicKey<E> { impl<E: Engine> PublicKey<E> {
/// Returns `true` if the signature matches the element of `E::G2`. /// Returns `true` if the signature matches the element of `E::G2`.
pub fn verify_g2<H: Into<E::G2Affine>>(&self, sig: &Signature<E>, hash: H) -> bool { pub fn verify_g2<H: Into<E::G2Affine>>(&self, sig: &Signature<E>, hash: H) -> bool {
@ -85,6 +92,12 @@ impl<E: Engine> PartialEq for Signature<E> {
} }
} }
impl<E: Engine> Hash for Signature<E> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.into_affine().into_compressed().as_ref().hash(state);
}
}
impl<E: Engine> Signature<E> { impl<E: Engine> Signature<E> {
pub fn parity(&self) -> bool { pub fn parity(&self) -> bool {
let uncomp = self.0.into_affine().into_uncompressed(); let uncomp = self.0.into_affine().into_uncompressed();
@ -160,6 +173,14 @@ impl<E: Engine> PartialEq for Ciphertext<E> {
} }
} }
impl<E: Engine> Hash for Ciphertext<E> {
fn hash<H: Hasher>(&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<E: Engine> Ciphertext<E> { impl<E: Engine> Ciphertext<E> {
/// Returns `true` if this is a valid ciphertext. This check is necessary to prevent /// Returns `true` if this is a valid ciphertext. This check is necessary to prevent
/// chosen-ciphertext attacks. /// chosen-ciphertext attacks.
@ -180,8 +201,14 @@ impl<E: Engine> PartialEq for DecryptionShare<E> {
} }
} }
impl<E: Engine> Hash for DecryptionShare<E> {
fn hash<H: Hasher>(&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. /// 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<E: Engine> { pub struct PublicKeySet<E: Engine> {
/// The coefficients of a polynomial whose value at `0` is the "master key", and value at /// The coefficients of a polynomial whose value at `0` is the "master key", and value at
/// `i + 1` is key share number `i`. /// `i + 1` is key share number `i`.

@ -20,6 +20,7 @@
// TODO: Expand this explanation and add examples, once the API is complete and stable. // TODO: Expand this explanation and add examples, once the API is complete and stable.
use std::borrow::Borrow; use std::borrow::Borrow;
use std::hash::{Hash, Hasher};
use std::{cmp, iter, ops}; use std::{cmp, iter, ops};
use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField}; use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField};
@ -261,6 +262,15 @@ impl<E: Engine> PartialEq for Commitment<E> {
} }
} }
impl<E: Engine> Hash for Commitment<E> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.coeff.len().hash(state);
for c in &self.coeff {
c.into_affine().into_compressed().as_ref().hash(state);
}
}
}
impl<B: Borrow<Commitment<E>>, E: Engine> ops::AddAssign<B> for Commitment<E> { impl<B: Borrow<Commitment<E>>, E: Engine> ops::AddAssign<B> for Commitment<E> {
fn add_assign(&mut self, rhs: B) { fn add_assign(&mut self, rhs: B) {
let len = cmp::max(self.coeff.len(), rhs.borrow().coeff.len()); let len = cmp::max(self.coeff.len(), rhs.borrow().coeff.len());
@ -403,6 +413,15 @@ pub struct BivarCommitment<E: Engine> {
coeff: Vec<E::G1>, coeff: Vec<E::G1>,
} }
impl<E: Engine> Hash for BivarCommitment<E> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.degree.hash(state);
for c in &self.coeff {
c.into_affine().into_compressed().as_ref().hash(state);
}
}
}
impl<E: Engine> BivarCommitment<E> { impl<E: Engine> BivarCommitment<E> {
/// Returns the polynomial's degree: It is the same in both variables. /// Returns the polynomial's degree: It is the same in both variables.
pub fn degree(&self) -> usize { pub fn degree(&self) -> usize {

Loading…
Cancel
Save