Skip to main content

ed448_goldilocks/decaf/
ops.rs

1use crate::{DecafAffinePoint, DecafScalar, curve::scalar_mul::double_and_add};
2use core::{borrow::Borrow, iter::Sum};
3use elliptic_curve::{
4    CurveGroup,
5    ops::{Add, AddAssign, Mul, MulAssign, MulByGeneratorVartime, MulVartime, Neg, Sub, SubAssign},
6};
7
8use super::DecafPoint;
9
10/// Scalar Mul Operations
11impl Mul<&DecafScalar> for &DecafPoint {
12    type Output = DecafPoint;
13
14    fn mul(self, scalar: &DecafScalar) -> DecafPoint {
15        // XXX: We can do better than double and add
16        DecafPoint(double_and_add(&self.0, scalar.bits()).to_extended())
17    }
18}
19
20impl MulVartime<DecafScalar> for DecafPoint {
21    fn mul_vartime(self, scalar: DecafScalar) -> DecafPoint {
22        MulVartime::mul_vartime(&self, &scalar)
23    }
24}
25
26impl MulVartime<&DecafScalar> for DecafPoint {
27    fn mul_vartime(self, scalar: &DecafScalar) -> DecafPoint {
28        MulVartime::mul_vartime(&self, scalar)
29    }
30}
31
32impl MulVartime<&DecafScalar> for &DecafPoint {
33    fn mul_vartime(self, scalar: &DecafScalar) -> DecafPoint {
34        // TODO(tarcieri): optimized vartime implementation
35        self * scalar
36    }
37}
38
39impl MulByGeneratorVartime for DecafPoint {}
40
41define_mul_variants!(LHS = DecafPoint, RHS = DecafScalar, Output = DecafPoint);
42
43impl<'s> MulAssign<&'s DecafScalar> for DecafPoint {
44    fn mul_assign(&mut self, scalar: &'s DecafScalar) {
45        *self = *self * scalar;
46    }
47}
48impl MulAssign<DecafScalar> for DecafPoint {
49    fn mul_assign(&mut self, scalar: DecafScalar) {
50        *self = *self * scalar;
51    }
52}
53
54// Point addition
55
56impl Add<&DecafPoint> for &DecafPoint {
57    type Output = DecafPoint;
58
59    fn add(self, other: &DecafPoint) -> DecafPoint {
60        DecafPoint(self.0.add_extended(&other.0).to_extended())
61    }
62}
63
64impl Add<&DecafAffinePoint> for &DecafPoint {
65    type Output = DecafPoint;
66
67    fn add(self, rhs: &DecafAffinePoint) -> Self::Output {
68        self + DecafPoint(rhs.0.to_extended())
69    }
70}
71
72impl Add<&DecafPoint> for &DecafAffinePoint {
73    type Output = DecafPoint;
74
75    fn add(self, rhs: &DecafPoint) -> Self::Output {
76        DecafPoint(self.0.to_extended()) + rhs
77    }
78}
79
80define_add_variants!(LHS = DecafPoint, RHS = DecafPoint, Output = DecafPoint);
81define_add_variants!(
82    LHS = DecafPoint,
83    RHS = DecafAffinePoint,
84    Output = DecafPoint
85);
86define_add_variants!(
87    LHS = DecafAffinePoint,
88    RHS = DecafPoint,
89    Output = DecafPoint
90);
91
92impl AddAssign<&DecafPoint> for DecafPoint {
93    fn add_assign(&mut self, other: &DecafPoint) {
94        *self = *self + other;
95    }
96}
97impl AddAssign for DecafPoint {
98    fn add_assign(&mut self, other: DecafPoint) {
99        *self = *self + other;
100    }
101}
102
103impl AddAssign<&DecafAffinePoint> for DecafPoint {
104    fn add_assign(&mut self, other: &DecafAffinePoint) {
105        *self = *self + *other;
106    }
107}
108
109impl AddAssign<&DecafPoint> for DecafAffinePoint {
110    fn add_assign(&mut self, rhs: &DecafPoint) {
111        *self = (DecafPoint(self.0.to_extended()) + rhs).to_affine();
112    }
113}
114
115define_add_assign_variants!(LHS = DecafPoint, RHS = DecafAffinePoint);
116define_add_assign_variants!(LHS = DecafAffinePoint, RHS = DecafPoint);
117
118// Point Subtraction
119
120impl Sub<&DecafPoint> for &DecafPoint {
121    type Output = DecafPoint;
122
123    fn sub(self, other: &DecafPoint) -> DecafPoint {
124        DecafPoint(self.0.sub_extended(&other.0).to_extended())
125    }
126}
127
128impl Sub<&DecafAffinePoint> for &DecafPoint {
129    type Output = DecafPoint;
130
131    fn sub(self, rhs: &DecafAffinePoint) -> Self::Output {
132        self - DecafPoint(rhs.0.to_extended())
133    }
134}
135
136impl Sub<&DecafPoint> for &DecafAffinePoint {
137    type Output = DecafPoint;
138
139    fn sub(self, rhs: &DecafPoint) -> Self::Output {
140        DecafPoint(self.0.to_extended()) - rhs
141    }
142}
143
144define_sub_variants!(LHS = DecafPoint, RHS = DecafPoint, Output = DecafPoint);
145define_sub_variants!(
146    LHS = DecafPoint,
147    RHS = DecafAffinePoint,
148    Output = DecafPoint
149);
150define_sub_variants!(
151    LHS = DecafAffinePoint,
152    RHS = DecafPoint,
153    Output = DecafPoint
154);
155
156impl SubAssign<&DecafPoint> for DecafPoint {
157    fn sub_assign(&mut self, other: &DecafPoint) {
158        *self = *self - other;
159    }
160}
161impl SubAssign for DecafPoint {
162    fn sub_assign(&mut self, other: DecafPoint) {
163        *self = *self - other;
164    }
165}
166
167impl SubAssign<&DecafAffinePoint> for DecafPoint {
168    fn sub_assign(&mut self, other: &DecafAffinePoint) {
169        *self = *self - *other;
170    }
171}
172
173impl SubAssign<&DecafPoint> for DecafAffinePoint {
174    fn sub_assign(&mut self, rhs: &DecafPoint) {
175        *self = (DecafPoint(self.0.to_extended()) - rhs).to_affine();
176    }
177}
178
179define_sub_assign_variants!(LHS = DecafPoint, RHS = DecafAffinePoint);
180define_sub_assign_variants!(LHS = DecafAffinePoint, RHS = DecafPoint);
181
182// Point Negation
183
184impl Neg for &DecafPoint {
185    type Output = DecafPoint;
186
187    fn neg(self) -> DecafPoint {
188        DecafPoint(self.0.negate())
189    }
190}
191impl Neg for DecafPoint {
192    type Output = DecafPoint;
193
194    fn neg(self) -> DecafPoint {
195        (&self).neg()
196    }
197}
198
199impl<T> Sum<T> for DecafPoint
200where
201    T: Borrow<DecafPoint>,
202{
203    fn sum<I>(iter: I) -> Self
204    where
205        I: Iterator<Item = T>,
206    {
207        iter.fold(Self::IDENTITY, |acc, item| acc + item.borrow())
208    }
209}