Skip to content

Commit d1de36f

Browse files
committed
Add MixedAdditionPoint
1 parent f291a56 commit d1de36f

File tree

1 file changed

+81
-6
lines changed
  • ed448-goldilocks/src/edwards

1 file changed

+81
-6
lines changed

ed448-goldilocks/src/edwards/mul.rs

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{EdwardsPoint, EdwardsScalar};
22
use crate::field::FieldElement;
3+
use core::ops::Add;
34
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};
45

56
pub(super) fn scalar_mul(point: &EdwardsPoint, scalar: &EdwardsScalar) -> EdwardsPoint {
@@ -25,7 +26,7 @@ pub(super) fn scalar_mul(point: &EdwardsPoint, scalar: &EdwardsScalar) -> Edward
2526
let mut neg_P = lookup.select(abs_value);
2627
neg_P.conditional_negate(Choice::from((sign) as u8));
2728

28-
result = (EdwardsPoint::from(result) + neg_P).into();
29+
result = &EdwardsPoint::from(result) + &neg_P;
2930
}
3031

3132
result.into()
@@ -90,15 +91,89 @@ impl From<EdwardsPoint> for ExtensiblePoint {
9091
}
9192
}
9293

93-
pub struct LookupTable([EdwardsPoint; 8]);
94+
#[derive(Clone, Copy)]
95+
struct MixedAdditionPoint {
96+
X: FieldElement,
97+
Y: FieldElement,
98+
Z: FieldElement,
99+
Td: FieldElement,
100+
}
101+
102+
impl MixedAdditionPoint {
103+
const IDENTITY: Self = Self {
104+
X: FieldElement::ZERO,
105+
Y: FieldElement::ONE,
106+
Z: FieldElement::ONE,
107+
Td: FieldElement::ZERO,
108+
};
109+
}
110+
111+
impl From<&EdwardsPoint> for MixedAdditionPoint {
112+
fn from(value: &EdwardsPoint) -> Self {
113+
Self {
114+
X: value.X,
115+
Y: value.Y,
116+
Z: value.Z,
117+
Td: value.T * FieldElement::EDWARDS_D,
118+
}
119+
}
120+
}
121+
122+
impl From<EdwardsPoint> for MixedAdditionPoint {
123+
fn from(value: EdwardsPoint) -> Self {
124+
(&value).into()
125+
}
126+
}
127+
128+
impl Add<&MixedAdditionPoint> for &EdwardsPoint {
129+
type Output = ExtensiblePoint;
130+
131+
fn add(self, rhs: &MixedAdditionPoint) -> Self::Output {
132+
let A = self.X * rhs.X;
133+
let B = self.Y * rhs.Y;
134+
let C = self.T * rhs.Td;
135+
let D = self.Z * rhs.Z;
136+
let E = (self.X + self.Y) * (rhs.X + rhs.Y) - A - B;
137+
let F = D - C;
138+
let G = D + C;
139+
let H = B - A;
140+
ExtensiblePoint {
141+
X: E * F,
142+
Y: G * H,
143+
Z: F * G,
144+
T1: E,
145+
T2: H,
146+
}
147+
}
148+
}
149+
150+
impl ConditionallySelectable for MixedAdditionPoint {
151+
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
152+
Self {
153+
X: FieldElement::conditional_select(&a.X, &b.X, choice),
154+
Y: FieldElement::conditional_select(&a.Y, &b.Y, choice),
155+
Z: FieldElement::conditional_select(&a.Z, &b.Z, choice),
156+
Td: FieldElement::conditional_select(&a.Td, &b.Td, choice),
157+
}
158+
}
159+
}
160+
161+
impl ConditionallyNegatable for MixedAdditionPoint {
162+
fn conditional_negate(&mut self, choice: Choice) {
163+
self.X.conditional_negate(choice);
164+
self.Td.conditional_negate(choice);
165+
}
166+
}
167+
168+
struct LookupTable([MixedAdditionPoint; 8]);
94169

95170
/// Precomputes odd multiples of the point passed in
96171
impl From<&EdwardsPoint> for LookupTable {
97172
fn from(P: &EdwardsPoint) -> LookupTable {
98-
let mut table = [*P; 8];
173+
let mut table = [MixedAdditionPoint::from(P); 8];
99174

100175
for i in 1..8 {
101-
table[i] = P + table[i - 1];
176+
table[i] = EdwardsPoint::from(P + &table[i - 1]).into();
102177
}
103178

104179
LookupTable(table)
@@ -107,8 +182,8 @@ impl From<&EdwardsPoint> for LookupTable {
107182

108183
impl LookupTable {
109184
/// Selects a projective niels point from a lookup table in constant time
110-
pub fn select(&self, index: u32) -> EdwardsPoint {
111-
let mut result = EdwardsPoint::IDENTITY;
185+
fn select(&self, index: u32) -> MixedAdditionPoint {
186+
let mut result = MixedAdditionPoint::IDENTITY;
112187

113188
for i in 1..9 {
114189
let swap = index.ct_eq(&(i as u32));

0 commit comments

Comments
 (0)