11use super :: { EdwardsPoint , EdwardsScalar } ;
22use crate :: field:: FieldElement ;
3+ use core:: ops:: Add ;
34use subtle:: { Choice , ConditionallyNegatable , ConditionallySelectable , ConstantTimeEq } ;
45
56pub ( 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
96171impl 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
108183impl 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