use ff::PrimeField;
use group::GroupEncoding;
use serde_crate::{
de::Error as DeserializeError, Deserialize, Deserializer, Serialize, Serializer,
};
use crate::{
curves::{Ep, EpAffine, Eq, EqAffine},
fields::{Fp, Fq},
group::Curve,
};
fn serialize_bytes<S: Serializer>(bytes: [u8; 32], s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
hex::serde::serialize(bytes, s)
} else {
bytes.serialize(s)
}
}
fn deserialize_bytes<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 32], D::Error> {
if d.is_human_readable() {
hex::serde::deserialize(d)
} else {
<[u8; 32]>::deserialize(d)
}
}
impl Serialize for Fp {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_bytes(self.to_repr(), s)
}
}
impl<'de> Deserialize<'de> for Fp {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let bytes = deserialize_bytes(d)?;
match Fp::from_repr(bytes).into() {
Some(fq) => Ok(fq),
None => Err(D::Error::custom(
"deserialized bytes don't encode a Pallas field element",
)),
}
}
}
impl Serialize for Fq {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_bytes(self.to_repr(), s)
}
}
impl<'de> Deserialize<'de> for Fq {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let bytes = deserialize_bytes(d)?;
match Fq::from_repr(bytes).into() {
Some(fq) => Ok(fq),
None => Err(D::Error::custom(
"deserialized bytes don't encode a Vesta field element",
)),
}
}
}
impl Serialize for EpAffine {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_bytes(self.to_bytes(), s)
}
}
impl<'de> Deserialize<'de> for EpAffine {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let bytes = deserialize_bytes(d)?;
match EpAffine::from_bytes(&bytes).into() {
Some(ep_affine) => Ok(ep_affine),
None => Err(D::Error::custom(
"deserialized bytes don't encode a Pallas curve point",
)),
}
}
}
impl Serialize for EqAffine {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_bytes(self.to_bytes(), s)
}
}
impl<'de> Deserialize<'de> for EqAffine {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let bytes = deserialize_bytes(d)?;
match EqAffine::from_bytes(&bytes).into() {
Some(eq_affine) => Ok(eq_affine),
None => Err(D::Error::custom(
"deserialized bytes don't encode a Vesta curve point",
)),
}
}
}
impl Serialize for Ep {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
EpAffine::serialize(&self.to_affine(), s)
}
}
impl<'de> Deserialize<'de> for Ep {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(Self::from(EpAffine::deserialize(d)?))
}
}
impl Serialize for Eq {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
EqAffine::serialize(&self.to_affine(), s)
}
}
impl<'de> Deserialize<'de> for Eq {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(Self::from(EqAffine::deserialize(d)?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::fmt::Debug;
use ff::Field;
use group::{prime::PrimeCurveAffine, Curve, Group};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use crate::curves::{Ep, Eq};
fn test_roundtrip<T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq>(t: &T) {
let serialized_json = serde_json::to_vec(t).unwrap();
assert_eq!(*t, serde_json::from_slice(&serialized_json).unwrap());
let serialized_bincode = bincode::serialize(t).unwrap();
assert_eq!(*t, bincode::deserialize(&serialized_bincode).unwrap());
}
#[test]
fn serde_fp() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
for _ in 0..100 {
let f = Fp::random(&mut rng);
test_roundtrip(&f);
}
let f = Fp::zero();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Fp>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Fp>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = Fp::one();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Fp>(
br#""0100000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Fp>(&[
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
}
#[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,
]);
for _ in 0..100 {
let f = Fq::random(&mut rng);
test_roundtrip(&f);
}
let f = Fq::zero();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Fq>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Fq>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = Fq::one();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Fq>(
br#""0100000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Fq>(&[
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
}
#[test]
fn serde_ep_affine() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
for _ in 0..100 {
let f = Ep::random(&mut rng);
test_roundtrip(&f.to_affine());
}
let f = EpAffine::identity();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<EpAffine>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<EpAffine>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = EpAffine::generator();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<EpAffine>(
br#""00000000ed302d991bf94c09fc98462200000000000000000000000000000040""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<EpAffine>(&[
0, 0, 0, 0, 237, 48, 45, 153, 27, 249, 76, 9, 252, 152, 70, 34, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 64
])
.unwrap(),
f
);
}
#[test]
fn serde_eq_affine() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
for _ in 0..100 {
let f = Eq::random(&mut rng);
test_roundtrip(&f.to_affine());
}
let f = EqAffine::identity();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<EqAffine>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<EqAffine>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = EqAffine::generator();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<EqAffine>(
br#""0000000021eb468cdda89409fc98462200000000000000000000000000000040""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<EqAffine>(&[
0, 0, 0, 0, 33, 235, 70, 140, 221, 168, 148, 9, 252, 152, 70, 34, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 64
])
.unwrap(),
f
);
}
#[test]
fn serde_ep() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
for _ in 0..100 {
let f = Ep::random(&mut rng);
test_roundtrip(&f);
}
let f = Ep::identity();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Ep>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Ep>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = Ep::generator();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Ep>(
br#""00000000ed302d991bf94c09fc98462200000000000000000000000000000040""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Ep>(&[
0, 0, 0, 0, 237, 48, 45, 153, 27, 249, 76, 9, 252, 152, 70, 34, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 64
])
.unwrap(),
f
);
}
#[test]
fn serde_eq() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);
for _ in 0..100 {
let f = Eq::random(&mut rng);
test_roundtrip(&f);
}
let f = Eq::identity();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Eq>(
br#""0000000000000000000000000000000000000000000000000000000000000000""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Eq>(&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
])
.unwrap(),
f
);
let f = Eq::generator();
test_roundtrip(&f);
assert_eq!(
serde_json::from_slice::<Eq>(
br#""0000000021eb468cdda89409fc98462200000000000000000000000000000040""#
)
.unwrap(),
f
);
assert_eq!(
bincode::deserialize::<Eq>(&[
0, 0, 0, 0, 33, 235, 70, 140, 221, 168, 148, 9, 252, 152, 70, 34, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 64
])
.unwrap(),
f
);
}
}