From abff26a15340578333c6431a0a2bb4223dc437c5 Mon Sep 17 00:00:00 2001 From: Andreas Fackler Date: Wed, 30 May 2018 10:08:43 +0200 Subject: [PATCH] Make public keys and signatures serializable. --- mod.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 7 deletions(-) diff --git a/mod.rs b/mod.rs index 1fa782e..1829598 100644 --- a/mod.rs +++ b/mod.rs @@ -2,7 +2,6 @@ mod error; use byteorder::{BigEndian, ByteOrder}; use init_with::InitWith; - use pairing::{CurveAffine, CurveProjective, Engine, Field, PrimeField}; use rand::{ChaChaRng, Rand, Rng, SeedableRng}; use ring::digest; @@ -101,10 +100,11 @@ impl SecretKey { } /// A public key and an associated set of public key shares. +#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))] 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`. - coeff: Vec, + coeff: Vec>, } impl PublicKeySet { @@ -115,8 +115,8 @@ impl PublicKeySet { } /// Returns the public key. - pub fn public_key(&self) -> PublicKey { - PublicKey(self.coeff[0]) + pub fn public_key(&self) -> &PublicKey { + &self.coeff[0] } /// Returns the `i`-th public key share. @@ -126,10 +126,10 @@ impl PublicKeySet { { let mut x = E::Fr::one(); x.add_assign(&E::Fr::from_repr(i.into()).expect("invalid index")); - let mut pk = *self.coeff.last().expect("at least one coefficient"); + let mut pk = self.coeff.last().expect("at least one coefficient").0; for c in self.coeff.iter().rev().skip(1) { pk.mul_assign(x); - pk.add_assign(c); + pk.add_assign(&c.0); } PublicKey(pk) } @@ -215,7 +215,7 @@ impl SecretKeySet { /// Returns the corresponding public key set. That information can be shared publicly. pub fn public_keys(&self) -> PublicKeySet { - let to_pub = |c: &E::Fr| E::G1Affine::one().mul(*c); + let to_pub = |c: &E::Fr| PublicKey(E::G1Affine::one().mul(*c)); PublicKeySet { coeff: self.coeff.iter().map(to_pub).collect(), } @@ -288,4 +288,82 @@ mod tests { assert_ne!(hash(&msg), hash(&msg_end0)); assert_ne!(hash(&msg_end0), hash(&msg_end1)); } + + #[cfg(feature = "serialization-serde")] + #[test] + fn test_serde() { + use bincode; + + let mut rng = rand::thread_rng(); + let sk = SecretKey::::new(&mut rng); + let sig = sk.sign("Please sign here: ______"); + let pk = sk.public_key(); + let ser_pk = bincode::serialize(&pk).expect("serialize public key"); + let deser_pk = bincode::deserialize(&ser_pk).expect("deserialize public key"); + assert_eq!(pk, deser_pk); + let ser_sig = bincode::serialize(&sig).expect("serialize signature"); + let deser_sig = bincode::deserialize(&ser_sig).expect("deserialize signature"); + assert_eq!(sig, deser_sig); + } +} + +#[cfg(feature = "serialization-serde")] +mod serde { + use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine}; + + use super::{PublicKey, Signature}; + use serde::de::Error as DeserializeError; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + const ERR_LEN: &str = "wrong length of deserialized group element"; + const ERR_CODE: &str = "deserialized bytes don't encode a group element"; + + impl Serialize for PublicKey { + fn serialize(&self, s: S) -> Result { + serialize_projective(&self.0, s) + } + } + + impl<'de, E: Engine> Deserialize<'de> for PublicKey { + fn deserialize>(d: D) -> Result { + Ok(PublicKey(deserialize_projective(d)?)) + } + } + + impl Serialize for Signature { + fn serialize(&self, s: S) -> Result { + serialize_projective(&self.0, s) + } + } + + impl<'de, E: Engine> Deserialize<'de> for Signature { + fn deserialize>(d: D) -> Result { + Ok(Signature(deserialize_projective(d)?)) + } + } + + /// Serializes the compressed representation of a group element. + fn serialize_projective(c: &C, s: S) -> Result + where + S: Serializer, + C: CurveProjective, + { + c.into_affine().into_compressed().as_ref().serialize(s) + } + + /// Deserializes the compressed representation of a group element. + fn deserialize_projective<'de, D, C>(d: D) -> Result + where + D: Deserializer<'de>, + C: CurveProjective, + { + let bytes = >::deserialize(d)?; + if bytes.len() != ::Compressed::size() { + return Err(D::Error::custom(ERR_LEN)); + } + let mut compressed = ::Compressed::empty(); + compressed.as_mut().copy_from_slice(&bytes); + let to_err = |_| D::Error::custom(ERR_CODE); + Ok(compressed.into_affine().map_err(to_err)?.into_projective()) + } }