From 6484242afc3a55c16c2bab146f4b1876a1cbf1c4 Mon Sep 17 00:00:00 2001 From: Andreas Fackler Date: Wed, 20 Jun 2018 10:43:59 +0200 Subject: [PATCH] Simplify serde implementations, add Ciphertext. --- src/crypto/mod.rs | 23 ++++--- src/crypto/serde_impl.rs | 139 ++++++++++++++------------------------- 2 files changed, 64 insertions(+), 98 deletions(-) diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 4986af6..1dd0bfe 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -4,8 +4,6 @@ pub mod poly; pub mod protobuf_impl; mod serde_impl; -use self::poly::{Commitment, Poly}; - use std::fmt; use byteorder::{BigEndian, ByteOrder}; @@ -15,6 +13,7 @@ use rand::{ChaChaRng, OsRng, Rng, SeedableRng}; use ring::digest; use self::error::{ErrorKind, Result}; +use self::poly::{Commitment, Poly}; use fmt::HexBytes; /// The number of words (`u32`) in a ChaCha RNG seed. @@ -23,8 +22,8 @@ const CHACHA_RNG_SEED_SIZE: usize = 8; const ERR_OS_RNG: &str = "could not initialize the OS random number generator"; /// A public key, or a public key share. -#[derive(Clone, Debug)] -pub struct PublicKey(E::G1); +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct PublicKey(#[serde(with = "serde_impl::projective")] E::G1); impl PartialEq for PublicKey { fn eq(&self, other: &PublicKey) -> bool { @@ -69,8 +68,8 @@ impl PublicKey { } /// A signature, or a signature share. -#[derive(Clone)] -pub struct Signature(E::G2); +#[derive(Deserialize, Serialize, Clone)] +pub struct Signature(#[serde(with = "serde_impl::projective")] E::G2); impl fmt::Debug for Signature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -148,8 +147,12 @@ impl SecretKey { } /// An encrypted message. -#[derive(Debug)] -pub struct Ciphertext(E::G1, Vec, E::G2); +#[derive(Deserialize, Serialize, Debug)] +pub struct Ciphertext( + #[serde(with = "serde_impl::projective")] E::G1, + Vec, + #[serde(with = "serde_impl::projective")] E::G2, +); impl PartialEq for Ciphertext { fn eq(&self, other: &Ciphertext) -> bool { @@ -168,8 +171,8 @@ impl Ciphertext { } /// A decryption share. A threshold of decryption shares can be used to decrypt a message. -#[derive(Debug)] -pub struct DecryptionShare(E::G1); +#[derive(Deserialize, Serialize, Debug)] +pub struct DecryptionShare(#[serde(with = "serde_impl::projective")] E::G1); impl PartialEq for DecryptionShare { fn eq(&self, other: &DecryptionShare) -> bool { diff --git a/src/crypto/serde_impl.rs b/src/crypto/serde_impl.rs index 5e98a4d..d6caccd 100644 --- a/src/crypto/serde_impl.rs +++ b/src/crypto/serde_impl.rs @@ -1,104 +1,67 @@ -use std::borrow::Borrow; -use std::marker::PhantomData; +/// Serialization and deserialization of a group element's compressed representation. +pub mod projective { + use pairing::{CurveAffine, CurveProjective, EncodedPoint}; + use serde::de::Error as DeserializeError; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine}; + const ERR_LEN: &str = "wrong length of deserialized group element"; + const ERR_CODE: &str = "deserialized bytes don't encode a group element"; -use super::{DecryptionShare, 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"; - -/// A wrapper type to facilitate serialization and deserialization of group elements. -struct CurveWrap(B, PhantomData); - -impl CurveWrap { - fn new(c: B) -> Self { - CurveWrap(c, PhantomData) + pub fn serialize(c: &C, s: S) -> Result + where + S: Serializer, + C: CurveProjective, + { + c.into_affine().into_compressed().as_ref().serialize(s) } -} -impl> Serialize for CurveWrap { - fn serialize(&self, s: S) -> Result { - serialize_projective(self.0.borrow(), s) + pub fn deserialize<'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()) } } -impl<'de, C: CurveProjective> Deserialize<'de> for CurveWrap { - fn deserialize>(d: D) -> Result { - Ok(CurveWrap::new(deserialize_projective(d)?)) - } -} - -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)?)) - } -} - -impl Serialize for DecryptionShare { - fn serialize(&self, s: S) -> Result { - serialize_projective(&self.0, s) - } -} - -impl<'de, E: Engine> Deserialize<'de> for DecryptionShare { - fn deserialize>(d: D) -> Result { - Ok(DecryptionShare(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()) -} - /// Serialization and deserialization of vectors of projective curve elements. pub mod projective_vec { - use super::CurveWrap; + use std::borrow::Borrow; + use std::marker::PhantomData; use pairing::CurveProjective; use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use super::projective; + + /// A wrapper type to facilitate serialization and deserialization of group elements. + struct CurveWrap(B, PhantomData); + + impl CurveWrap { + fn new(c: B) -> Self { + CurveWrap(c, PhantomData) + } + } + + impl> Serialize for CurveWrap { + fn serialize(&self, s: S) -> Result { + projective::serialize(self.0.borrow(), s) + } + } + + impl<'de, C: CurveProjective> Deserialize<'de> for CurveWrap { + fn deserialize>(d: D) -> Result { + Ok(CurveWrap::new(projective::deserialize(d)?)) + } + } + pub fn serialize(vec: &[C], s: S) -> Result where S: Serializer,