use std::fmt;
use std::marker::PhantomData;
use super::{G1Affine, G2Affine, G1, G2};
use groupy::{CurveAffine, CurveProjective, EncodedPoint};
use serde::de::{Error as DeserializeError, SeqAccess, Visitor};
use serde::ser::SerializeTuple;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
const ERR_CODE: &str = "deserialized bytes don't encode a group element";
impl Serialize for G1 {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
self.into_affine().serialize(s)
}
}
impl<'de> Deserialize<'de> for G1 {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(G1Affine::deserialize(d)?.into_projective())
}
}
impl Serialize for G1Affine {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_affine(self, s)
}
}
impl<'de> Deserialize<'de> for G1Affine {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(deserialize_affine(d)?)
}
}
impl Serialize for G2 {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
self.into_affine().serialize(s)
}
}
impl<'de> Deserialize<'de> for G2 {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(G2Affine::deserialize(d)?.into_projective())
}
}
impl Serialize for G2Affine {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_affine(self, s)
}
}
impl<'de> Deserialize<'de> for G2Affine {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(deserialize_affine(d)?)
}
}
fn serialize_affine<S: Serializer, C: CurveAffine>(c: &C, s: S) -> Result<S::Ok, S::Error> {
let len = C::Compressed::size();
let mut tup = s.serialize_tuple(len)?;
for byte in c.into_compressed().as_ref() {
tup.serialize_element(byte)?;
}
tup.end()
}
fn deserialize_affine<'de, D: Deserializer<'de>, C: CurveAffine>(d: D) -> Result<C, D::Error> {
struct TupleVisitor<C> {
_ph: PhantomData<C>,
}
impl<'de, C: CurveAffine> Visitor<'de> for TupleVisitor<C> {
type Value = C;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
let len = C::Compressed::size();
write!(f, "a tuple of size {}", len)
}
#[inline]
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<C, A::Error> {
let mut compressed = C::Compressed::empty();
for (i, byte) in compressed.as_mut().iter_mut().enumerate() {
let len_err = || DeserializeError::invalid_length(i, &self);
*byte = seq.next_element()?.ok_or_else(len_err)?;
}
let to_err = |_| DeserializeError::custom(ERR_CODE);
compressed.into_affine().map_err(to_err)
}
}
let len = C::Compressed::size();
d.deserialize_tuple(len, TupleVisitor { _ph: PhantomData })
}
#[cfg(test)]
mod tests {
extern crate serde_json;
use super::*;
use crate::bls12_381::{Fq, Fq12, Fr};
use std::fmt::Debug;
use fff::{Field, PrimeField};
use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng;
fn test_roundtrip<T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq>(t: &T) {
let ser = serde_json::to_vec(t).unwrap();
assert_eq!(*t, serde_json::from_slice(&ser).unwrap());
}
#[test]
fn serde_g1() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
let g = G1::random(&mut rng);
test_roundtrip(&g);
test_roundtrip(&g.into_affine());
}
#[test]
fn serde_g2() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
let g = G2::random(&mut rng);
test_roundtrip(&g);
test_roundtrip(&g.into_affine());
}
#[test]
fn serde_fr() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
let f = Fr::random(&mut rng);
test_roundtrip(&f);
test_roundtrip(&f.into_repr());
}
#[test]
fn serde_fq() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
let f = Fq::random(&mut rng);
test_roundtrip(&f);
test_roundtrip(&f.into_repr());
}
#[test]
fn serde_fq12() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
let f = Fq12::random(&mut rng);
test_roundtrip(&f);
}
}