#[macro_export]
macro_rules! impl_sw_curve_serializer {
($params: ident) => {
impl<P: $params> CanonicalSerialize for Projective<P> {
#[allow(unused_qualifications)]
#[inline]
fn serialize_with_mode<W: std::io::Write>(
&self,
writer: W,
compress: Compress,
) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
CanonicalSerialize::serialize_with_mode(&Affine::<P>::from(*self), writer, compress)
}
#[inline]
fn serialized_size(&self, compress: Compress) -> usize {
Affine::<P>::from(*self).serialized_size(compress)
}
#[inline]
fn uncompressed_size(&self) -> usize {
Affine::<P>::from(*self).uncompressed_size()
}
}
impl<P: $params> Valid for Projective<P> {
fn check(&self) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
let point = Affine::<P>::from(*self);
if point.is_on_curve() & point.is_in_correct_subgroup_assuming_on_curve() {
Ok(())
} else {
Err(snarkvm_utilities::serialize::SerializationError::InvalidData)
}
}
}
impl<P: $params> CanonicalDeserialize for Projective<P> {
#[allow(unused_qualifications)]
fn deserialize_with_mode<R: std::io::Read>(
reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, snarkvm_utilities::serialize::SerializationError> {
Affine::<P>::deserialize_with_mode(reader, compress, validate).map(Into::into)
}
}
impl<P: $params> CanonicalSerialize for Affine<P> {
#[allow(unused_qualifications)]
#[inline]
fn serialize_with_mode<W: std::io::Write>(
&self,
mut writer: W,
compress: Compress,
) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
match compress {
Compress::Yes => {
if self.is_zero() {
let flags = snarkvm_utilities::serialize::SWFlags::infinity();
P::BaseField::zero().serialize_with_flags(writer, flags)
} else {
let flags = snarkvm_utilities::serialize::SWFlags::from_y_sign(self.y > -self.y);
self.x.serialize_with_flags(writer, flags)
}
}
Compress::No => {
let flags = if self.is_zero() {
snarkvm_utilities::serialize::SWFlags::infinity()
} else {
snarkvm_utilities::serialize::SWFlags::default()
};
self.x.serialize_uncompressed(&mut writer)?;
self.y.serialize_with_flags(&mut writer, flags)?;
Ok(())
}
}
}
#[inline]
fn serialized_size(&self, compress: Compress) -> usize {
match compress {
Compress::Yes => self.x.serialized_size_with_flags::<SWFlags>(),
Compress::No => self.x.serialized_size(compress) + self.y.serialized_size_with_flags::<SWFlags>(),
}
}
}
impl<P: $params> Valid for Affine<P> {
fn check(&self) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
if self.is_on_curve() & self.is_in_correct_subgroup_assuming_on_curve() {
Ok(())
} else {
Err(snarkvm_utilities::serialize::SerializationError::InvalidData)
}
}
}
impl<P: $params> CanonicalDeserialize for Affine<P> {
#[allow(unused_qualifications)]
fn deserialize_with_mode<R: std::io::Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, snarkvm_utilities::serialize::SerializationError> {
use snarkvm_utilities::serialize::SWFlags;
let point = if let Compress::Yes = compress {
let (x, flags) = P::BaseField::deserialize_with_flags::<_, SWFlags>(&mut reader)?;
if flags.is_infinity() {
Self::zero()
} else {
Affine::<P>::from_x_coordinate(x, flags.is_positive().unwrap())
.ok_or(snarkvm_utilities::serialize::SerializationError::InvalidData)?
}
} else {
let x = P::BaseField::deserialize_uncompressed(&mut reader)?;
let (y, flags) = P::BaseField::deserialize_with_flags::<_, SWFlags>(&mut reader)?;
Affine::<P>::new(x, y, flags.is_infinity())
};
if validate == Validate::Yes {
point.check()?;
}
Ok(point)
}
}
};
}
#[macro_export]
macro_rules! impl_edwards_curve_serializer {
($params: ident) => {
impl<P: $params> CanonicalSerialize for Projective<P> {
#[allow(unused_qualifications)]
#[inline]
fn serialize_with_mode<W: std::io::Write>(
&self,
writer: W,
compress: Compress,
) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
Affine::<P>::from(*self).serialize_with_mode(writer, compress)
}
#[inline]
fn serialized_size(&self, compress: Compress) -> usize {
Affine::<P>::from(*self).serialized_size(compress)
}
}
impl<P: $params> Valid for Projective<P> {
fn check(&self) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
let point = Affine::<P>::from(*self);
if point.is_on_curve() & point.is_in_correct_subgroup_assuming_on_curve() {
Ok(())
} else {
Err(snarkvm_utilities::serialize::SerializationError::InvalidData)
}
}
}
impl<P: $params> CanonicalDeserialize for Projective<P> {
#[allow(unused_qualifications)]
fn deserialize_with_mode<R: std::io::Read>(
reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, snarkvm_utilities::serialize::SerializationError> {
Affine::<P>::deserialize_with_mode(reader, compress, validate).map(Into::into)
}
}
impl<P: $params> CanonicalSerialize for Affine<P> {
#[allow(unused_qualifications)]
#[inline]
fn serialize_with_mode<W: std::io::Write>(
&self,
mut writer: W,
compress: Compress,
) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
if let Compress::Yes = compress {
if self.is_zero() {
let flags = snarkvm_utilities::serialize::EdwardsFlags::default();
P::BaseField::zero().serialize_with_flags(&mut writer, flags)
} else {
let flags = snarkvm_utilities::serialize::EdwardsFlags::from_y_sign(self.y > -self.y);
self.x.serialize_with_flags(writer, flags)
}
} else {
self.x.serialize_uncompressed(&mut writer)?;
self.y.serialize_uncompressed(&mut writer)?;
Ok(())
}
}
#[inline]
fn serialized_size(&self, compress: Compress) -> usize {
if let Compress::Yes = compress {
use snarkvm_utilities::serialize::EdwardsFlags;
self.x.serialized_size_with_flags::<EdwardsFlags>()
} else {
self.x.uncompressed_size() + self.y.uncompressed_size()
}
}
}
impl<P: $params> Valid for Affine<P> {
#[allow(unused_qualifications)]
fn check(&self) -> Result<(), snarkvm_utilities::serialize::SerializationError> {
if self.is_on_curve() & self.is_in_correct_subgroup_assuming_on_curve() {
Ok(())
} else {
Err(snarkvm_utilities::serialize::SerializationError::InvalidData)
}
}
}
impl<P: $params> CanonicalDeserialize for Affine<P> {
#[allow(unused_qualifications)]
fn deserialize_with_mode<R: std::io::Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, snarkvm_utilities::serialize::SerializationError> {
use snarkvm_utilities::serialize::{EdwardsFlags, SerializationError};
let point = if let Compress::Yes = compress {
let (x, flags): (P::BaseField, EdwardsFlags) = P::BaseField::deserialize_with_flags(&mut reader)?;
if x == P::BaseField::zero() {
Self::zero()
} else {
Affine::<P>::from_x_coordinate(x, flags.is_positive()).ok_or(SerializationError::InvalidData)?
}
} else {
let x = P::BaseField::deserialize_uncompressed(&mut reader)?;
let y = P::BaseField::deserialize_uncompressed(&mut reader)?;
Affine::<P>::new(x, y, x * y)
};
if let Validate::Yes = validate {
Valid::check(&point)?;
}
Ok(point)
}
}
};
}