use primitives::{
algebra::{
elliptic_curve::{Curve, Point},
field::{FieldExtension, SubfieldElement},
},
utils::InPlaceCodec,
};
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
pub trait LegacyBytes: Sized {
fn legacy_serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
fn legacy_deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>;
}
impl<F: FieldExtension> LegacyBytes for SubfieldElement<F> {
fn legacy_serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serde_bytes::serialize(AsRef::<[u8]>::as_ref(&self.to_le_bytes()), serializer)
}
fn legacy_deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
Self::from_le_bytes(bytes).map_err(D::Error::custom)
}
}
impl<C: Curve> LegacyBytes for Point<C> {
fn legacy_serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut bytes = self.to_inplace_bytes();
if C::POINT_BIG_ENDIAN {
bytes.reverse();
}
serde_bytes::serialize(bytes.as_slice(), serializer)
}
fn legacy_deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
let mut bytes = bytes.to_vec();
if C::POINT_BIG_ENDIAN {
bytes.reverse();
}
Self::read_le_bytes(&bytes).map_err(D::Error::custom)
}
}
impl<T: LegacyBytes> LegacyBytes for Vec<T> {
fn legacy_serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.collect_seq(self.iter().map(Legacy))
}
fn legacy_deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Vec::<Legacy<T>>::deserialize(deserializer)?
.into_iter()
.map(|w| w.0)
.collect())
}
}
struct Legacy<T>(T);
impl<T: LegacyBytes> Serialize for Legacy<&T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.legacy_serialize(serializer)
}
}
impl<'de, T: LegacyBytes> Deserialize<'de> for Legacy<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
T::legacy_deserialize(deserializer).map(Legacy)
}
}
pub mod legacy {
use super::*;
pub fn serialize<T: LegacyBytes, S: Serializer>(
value: &T,
serializer: S,
) -> Result<S::Ok, S::Error> {
value.legacy_serialize(serializer)
}
pub fn deserialize<'de, T: LegacyBytes, D: Deserializer<'de>>(
deserializer: D,
) -> Result<T, D::Error> {
T::legacy_deserialize(deserializer)
}
}