decaf377/ark_curve/element/
projective.rs1use core::borrow::Borrow;
2use core::hash::Hash;
3
4use ark_ff::Zero;
5use ark_std::fmt::{Display, Formatter, Result as FmtResult};
6
7use zeroize::Zeroize;
8
9use crate::{ark_curve::EdwardsProjective, Fq, Fr};
10
11use super::super::constants::{B_T, B_X, B_Y, B_Z};
12
13#[derive(Copy, Clone)]
14pub struct Element {
15 pub(crate) inner: EdwardsProjective,
16}
17
18impl Element {
19 pub const GENERATOR: Self = Self {
21 inner: EdwardsProjective::new_unchecked(B_X, B_Y, B_T, B_Z),
22 };
23
24 pub const IDENTITY: Self = Self {
25 inner: EdwardsProjective::new_unchecked(Fq::ZERO, Fq::ONE, Fq::ZERO, Fq::ONE),
26 };
27}
28
29impl Hash for Element {
30 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
31 self.inner.hash(state);
32 }
33}
34
35impl core::fmt::Debug for Element {
36 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
37 f.write_fmt(format_args!(
41 "decaf377::Element({})",
42 hex::encode(&self.vartime_compress().0[..])
43 ))
44 }
45}
46
47impl Display for Element {
48 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
49 write!(
50 f,
51 "decaf377::Element({})",
52 hex::encode(&self.vartime_compress().0[..])
53 )
54 }
55}
56
57impl Default for Element {
58 fn default() -> Self {
59 Element {
60 inner: EdwardsProjective::zero(),
61 }
62 }
63}
64
65impl PartialEq for Element {
66 fn eq(&self, other: &Element) -> bool {
67 self.inner.x * other.inner.y == self.inner.y * other.inner.x
69 }
70}
71
72impl Eq for Element {}
73
74impl Zeroize for Element {
75 fn zeroize(&mut self) {
76 self.inner.zeroize()
77 }
78}
79
80impl Element {
81 pub fn is_identity(&self) -> bool {
83 self.inner.x == Fq::zero()
86 }
87
88 pub fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Element
100 where
101 I: IntoIterator,
102 I::Item: Borrow<Fr>,
103 J: IntoIterator,
104 J::Item: Borrow<Element>,
105 {
106 let scalars = scalars.into_iter();
108 let points = points.into_iter();
109
110 scalars
113 .zip(points)
114 .fold(Element::default(), |acc, (scalar, point)| {
115 acc + (scalar.borrow() * point.borrow())
116 })
117 }
118}
119
120impl Zero for Element {
121 fn zero() -> Self {
122 Self::default()
123 }
124
125 fn is_zero(&self) -> bool {
126 self.inner.is_zero()
127 }
128}
129
130impl core::iter::Sum<Self> for Element {
131 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
132 iter.fold(Self::zero(), core::ops::Add::add)
133 }
134}
135
136impl<'a> core::iter::Sum<&'a Element> for Element {
137 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
138 iter.fold(Self::zero(), core::ops::Add::add)
139 }
140}