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.
This commit is contained in:
Andreas Fackler 2018-06-19 12:22:10 +02:00 committed by Vladimir Komendantskiy
parent cf1782b2cf
commit db1de60237
2 changed files with 47 additions and 1 deletions

29
mod.rs
View File

@ -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<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> {
/// 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 {
@ -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> {
pub fn parity(&self) -> bool {
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> {
/// Returns `true` if this is a valid ciphertext. This check is necessary to prevent
/// 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.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, Hash)]
pub struct PublicKeySet<E: Engine> {
/// The coefficients of a polynomial whose value at `0` is the "master key", and value at
/// `i + 1` is key share number `i`.

19
poly.rs
View File

@ -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<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> {
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<E: Engine> {
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> {
/// Returns the polynomial's degree: It is the same in both variables.
pub fn degree(&self) -> usize {