use ark_serialize::{
CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
CanonicalSerializeWithFlags, Compress, SerializationError, Valid, Validate,
};
use ark_std::io::{Read, Write};
use crate::{scalar_mul::variable_base::VariableBaseMSM, AffineRepr};
use num_traits::Zero;
use ark_ff::{fields::Field, AdditiveGroup};
mod affine;
pub use affine::*;
mod group;
pub use group::*;
mod serialization_flags;
pub use serialization_flags::*;
pub trait TECurveConfig: super::CurveConfig {
const COEFF_A: Self::BaseField;
const COEFF_D: Self::BaseField;
const GENERATOR: Affine<Self>;
type MontCurveConfig: MontCurveConfig<BaseField = Self::BaseField>;
#[inline(always)]
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
elem * Self::COEFF_A
}
fn is_in_correct_subgroup_assuming_on_curve(item: &Affine<Self>) -> bool {
Self::mul_affine(item, Self::ScalarField::characteristic()).is_zero()
}
fn clear_cofactor(item: &Affine<Self>) -> Affine<Self> {
item.mul_by_cofactor()
}
fn mul_projective(base: &Projective<Self>, scalar: &[u64]) -> Projective<Self> {
let mut res = Projective::<Self>::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(scalar) {
res.double_in_place();
if b {
res += base;
}
}
res
}
fn mul_affine(base: &Affine<Self>, scalar: &[u64]) -> Projective<Self> {
let mut res = Projective::<Self>::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(scalar) {
res.double_in_place();
if b {
res += base
}
}
res
}
fn msm(
bases: &[Affine<Self>],
scalars: &[Self::ScalarField],
) -> Result<Projective<Self>, usize> {
(bases.len() == scalars.len())
.then(|| VariableBaseMSM::msm_unchecked(bases, scalars))
.ok_or(bases.len().min(scalars.len()))
}
#[inline]
fn serialize_with_mode<W: Write>(
item: &Affine<Self>,
mut writer: W,
compress: ark_serialize::Compress,
) -> Result<(), SerializationError> {
let flags = TEFlags::from_x_coordinate(item.x);
match compress {
Compress::Yes => item.y.serialize_with_flags(writer, flags),
Compress::No => {
item.x.serialize_uncompressed(&mut writer)?;
item.y.serialize_uncompressed(&mut writer)
},
}
}
fn deserialize_with_mode<R: Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Affine<Self>, SerializationError> {
let (x, y) = match compress {
Compress::Yes => {
let (y, flags): (_, TEFlags) =
CanonicalDeserializeWithFlags::deserialize_with_flags(reader)?;
let (x, neg_x) = Affine::<Self>::get_xs_from_y_unchecked(y)
.ok_or(SerializationError::InvalidData)?;
if flags.is_negative() {
(neg_x, y)
} else {
(x, y)
}
},
Compress::No => {
let x: Self::BaseField =
CanonicalDeserialize::deserialize_uncompressed(&mut reader)?;
let y: Self::BaseField =
CanonicalDeserialize::deserialize_uncompressed(&mut reader)?;
(x, y)
},
};
let point = Affine::<Self>::new_unchecked(x, y);
if let Validate::Yes = validate {
point.check()?;
}
Ok(point)
}
#[inline]
fn serialized_size(compress: Compress) -> usize {
let zero = Self::BaseField::zero();
match compress {
Compress::Yes => zero.serialized_size_with_flags::<TEFlags>(),
Compress::No => zero.uncompressed_size() + zero.uncompressed_size(),
}
}
}
pub trait MontCurveConfig: super::CurveConfig {
const COEFF_A: Self::BaseField;
const COEFF_B: Self::BaseField;
type TECurveConfig: TECurveConfig<BaseField = Self::BaseField>;
}