From 2faf2afa46b6f85fd8afb22fc7e37b061ce66b6a Mon Sep 17 00:00:00 2001 From: Vladimir Komendantskiy Date: Sat, 9 Jun 2018 21:50:36 +0100 Subject: [PATCH] protobuf serialization --- mod.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/mod.rs b/mod.rs index 2d2e344..7b82d33 100644 --- a/mod.rs +++ b/mod.rs @@ -517,3 +517,99 @@ mod tests { assert_eq!(sig, deser_sig); } } + +#[cfg(feature = "serialization-serde")] +mod serde { + use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine}; + + 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"; + + 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()) + } +} + +#[cfg(feature = "serialization-protobuf")] +pub mod proto { + use super::Signature; + use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine}; + + impl Signature { + pub fn to_vec(&self) -> Vec { + let comp = self.0.into_affine().into_compressed(); + comp.as_ref().to_vec() + } + + pub fn from_bytes(bytes: &[u8]) -> Option { + let mut comp = ::Compressed::empty(); + comp.as_mut().copy_from_slice(bytes); + if let Ok(affine) = comp.into_affine() { + Some(Signature(affine.into_projective())) + } else { + None + } + } + } +}