use crate::serializers; use bls12_381::*; use serde::de::{Deserializer, Error}; use serde::ser::Serializer; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use base64; use serde_with::{SerializeAs,DeserializeAs}; use serde_with::serde_as; pub struct SerializeScalar; impl SerializeAs for SerializeScalar { fn serialize_as(g: &Scalar, serializer: S) -> Result where S: Serializer, { let base64 = base64::encode(g.to_bytes().to_vec()); String::serialize(&base64, serializer) } } impl<'de> DeserializeAs<'de, Scalar> for SerializeScalar { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let base64 = String::deserialize(deserializer)?; let s = base64::decode(base64.as_bytes()).map_err(|_x| Error::custom("Invalid Base64 string"))?; let a: &[u8; 32]; a = s .as_slice() .try_into() .map_err(|_x| Error::custom("Invalid Sized Array"))?; let result = Scalar::from_bytes(a); if result.is_none().into() { Err(Error::custom("Invalid Scalar")) } else { Ok(result.unwrap()) } } } pub struct SerializeGt; impl SerializeAs for SerializeGt { fn serialize_as(g: &Gt, serializer: S) -> Result where S: Serializer, { let base64 = base64::encode(g.to_uncompressed().to_vec()); String::serialize(&base64, serializer) } } impl<'de> DeserializeAs<'de, Gt> for SerializeGt { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let base64 = String::deserialize(deserializer)?; let s = base64::decode(base64.as_bytes()).map_err(|_x| Error::custom("Invalid Base64 string"))?; let a: &[u8; 576]; a = s.as_slice().try_into().map_err(|_x| Error::custom("Invalid Sized Array"))?; let result = Gt::from_uncompressed(a); if result.is_none().into() { Err(Error::custom("Invalid Gt")) } else { Ok(result.unwrap()) } } } pub struct SerializeG2; impl SerializeAs for SerializeG2 { fn serialize_as(g: &G2Projective, serializer: S) -> Result where S: Serializer, { let base64 = base64::encode(G2Affine::from(g).to_compressed().to_vec()); String::serialize(&base64, serializer) } } impl<'de> DeserializeAs<'de, G2Projective> for SerializeG2 { fn deserialize_as(deserializer: D) -> Result where D: Deserializer<'de>, { let base64 = String::deserialize(deserializer)?; let s = base64::decode(base64.as_bytes()).map_err(|_x| Error::custom("Invalid Base64 string"))?; let a: &[u8; 96]; a = s.as_slice().try_into().map_err(|_x| Error::custom("Invalid Sized Array"))?; let result = G2Affine::from_compressed(a); if result.is_none().into() { Err(Error::custom("Invalid G2 Element")) } else { Ok(result.unwrap().into()) } } } #[serde_as] #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] struct GtTest { #[serde_as(as = "serializers::SerializeGt")] g: Gt, } #[test] fn test_gt() { let point = GtTest { g: crate::utils::random_gt(), }; let serialized = serde_json::to_string(&point).unwrap(); println!("serialized = {}", serialized); // Convert the JSON string back to a Point. let deserialized: GtTest = serde_json::from_str(&serialized).unwrap(); println!("deserialized = {:?}", deserialized); assert_eq!(deserialized, point); }