decaf377/ark_curve/element/
projective.rsuse core::borrow::Borrow;
use core::hash::Hash;
use ark_ff::Zero;
use ark_std::fmt::{Display, Formatter, Result as FmtResult};
use zeroize::Zeroize;
use crate::{ark_curve::EdwardsProjective, Fq, Fr};
use super::super::constants::{B_T, B_X, B_Y, B_Z};
#[derive(Copy, Clone)]
pub struct Element {
pub(crate) inner: EdwardsProjective,
}
impl Element {
pub const GENERATOR: Self = Self {
inner: EdwardsProjective::new_unchecked(B_X, B_Y, B_T, B_Z),
};
pub const IDENTITY: Self = Self {
inner: EdwardsProjective::new_unchecked(Fq::ZERO, Fq::ONE, Fq::ZERO, Fq::ONE),
};
}
impl Hash for Element {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.inner.hash(state);
}
}
impl core::fmt::Debug for Element {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!(
"decaf377::Element({})",
hex::encode(&self.vartime_compress().0[..])
))
}
}
impl Display for Element {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(
f,
"decaf377::Element({})",
hex::encode(&self.vartime_compress().0[..])
)
}
}
impl Default for Element {
fn default() -> Self {
Element {
inner: EdwardsProjective::zero(),
}
}
}
impl PartialEq for Element {
fn eq(&self, other: &Element) -> bool {
self.inner.x * other.inner.y == self.inner.y * other.inner.x
}
}
impl Eq for Element {}
impl Zeroize for Element {
fn zeroize(&mut self) {
self.inner.zeroize()
}
}
impl Element {
pub fn is_identity(&self) -> bool {
self.inner.x == Fq::zero()
}
pub fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Element
where
I: IntoIterator,
I::Item: Borrow<Fr>,
J: IntoIterator,
J::Item: Borrow<Element>,
{
let scalars = scalars.into_iter();
let points = points.into_iter();
scalars
.zip(points)
.fold(Element::default(), |acc, (scalar, point)| {
acc + (scalar.borrow() * point.borrow())
})
}
}
impl Zero for Element {
fn zero() -> Self {
Self::default()
}
fn is_zero(&self) -> bool {
self.inner.is_zero()
}
}
impl core::iter::Sum<Self> for Element {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Self::zero(), core::ops::Add::add)
}
}
impl<'a> core::iter::Sum<&'a Element> for Element {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Self::zero(), core::ops::Add::add)
}
}