130 lines
3.7 KiB
Rust
130 lines
3.7 KiB
Rust
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<Scalar> for SerializeScalar {
|
|
fn serialize_as<S>(g: &Scalar, serializer: S) -> Result<S::Ok, S::Error>
|
|
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<D>(deserializer: D) -> Result<Scalar, D::Error>
|
|
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<Gt> for SerializeGt {
|
|
fn serialize_as<S>(g: &Gt, serializer: S) -> Result<S::Ok, S::Error>
|
|
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<D>(deserializer: D) -> Result<Gt, D::Error>
|
|
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<G2Projective> for SerializeG2 {
|
|
fn serialize_as<S>(g: &G2Projective, serializer: S) -> Result<S::Ok, S::Error>
|
|
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<D>(deserializer: D) -> Result<G2Projective, D::Error>
|
|
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);
|
|
}
|