11#![ allow( non_snake_case) ]
22#![ allow( dead_code) ]
33
4- use crate :: curve:: twedwards:: affine:: AffinePoint ;
4+ use crate :: curve:: twedwards:: affine:: AffineNielsPoint ;
55use crate :: curve:: twedwards:: extensible:: ExtensiblePoint ;
6- use crate :: edwards :: EdwardsPoint as EdwardsExtendedPoint ;
6+ use crate :: curve :: twedwards :: projective :: ProjectiveNielsPoint ;
77use crate :: field:: FieldElement ;
88use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
99
@@ -43,6 +43,11 @@ impl PartialEq for ExtendedPoint {
4343 self . ct_eq ( other) . into ( )
4444 }
4545}
46+ impl PartialEq < ExtensiblePoint > for ExtendedPoint {
47+ fn eq ( & self , other : & ExtensiblePoint ) -> bool {
48+ self . to_extensible ( ) . ct_eq ( other) . into ( )
49+ }
50+ }
4651impl Eq for ExtendedPoint { }
4752
4853impl Default for ExtendedPoint {
@@ -69,14 +74,90 @@ impl ExtendedPoint {
6974 T : FieldElement :: ZERO ,
7075 } ;
7176
72- /// Doubles an extended point
73- pub ( crate ) fn double ( & self ) -> ExtendedPoint {
74- self . to_extensible ( ) . double ( ) . to_extended ( )
77+ /// Adds an extensible point to an extended point
78+ /// Returns an extensible point
79+ /// (3.1) https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
80+ pub fn add_extended ( & self , other : & ExtendedPoint ) -> ExtensiblePoint {
81+ let A = self . X * other. X ;
82+ let B = self . Y * other. Y ;
83+ let C = self . T * other. T * FieldElement :: TWISTED_D ;
84+ let D = self . Z * other. Z ;
85+ let E = ( self . X + self . Y ) * ( other. X + other. Y ) - A - B ;
86+ let F = D - C ;
87+ let G = D + C ;
88+ let H = B + A ;
89+ ExtensiblePoint {
90+ X : E * F ,
91+ Y : G * H ,
92+ T1 : E ,
93+ T2 : H ,
94+ Z : F * G ,
95+ }
96+ }
97+
98+ /// Subtracts an extensible point from an extended point
99+ /// Returns an extensible point
100+ /// This is a direct modification of the addition formula to the negation of `other`
101+ pub fn sub_extended ( & self , other : & ExtendedPoint ) -> ExtensiblePoint {
102+ let A = self . X * other. X ;
103+ let B = self . Y * other. Y ;
104+ let C = self . T * other. T * FieldElement :: TWISTED_D ;
105+ let D = self . Z * other. Z ;
106+ let E = ( self . X + self . Y ) * ( other. Y - other. X ) + A - B ;
107+ let F = D + C ;
108+ let G = D - C ;
109+ let H = B - A ;
110+ ExtensiblePoint {
111+ X : E * F ,
112+ Y : G * H ,
113+ T1 : E ,
114+ T2 : H ,
115+ Z : F * G ,
116+ }
117+ }
118+
119+ /// Adds an extensible point to an AffineNiels point
120+ /// Returns an Extensible point
121+ pub fn add_affine_niels ( & self , other : AffineNielsPoint ) -> ExtensiblePoint {
122+ let A = other. y_minus_x * ( self . Y - self . X ) ;
123+ let B = other. y_plus_x * ( self . X + self . Y ) ;
124+ let C = other. td * self . T ;
125+ let D = B + A ;
126+ let E = B - A ;
127+ let F = self . Z - C ;
128+ let G = self . Z + C ;
129+ ExtensiblePoint {
130+ X : E * F ,
131+ Y : G * D ,
132+ Z : F * G ,
133+ T1 : E ,
134+ T2 : D ,
135+ }
75136 }
76137
77- /// Adds an extended point to itself
78- pub ( crate ) fn add ( & self , other : & ExtendedPoint ) -> ExtendedPoint {
79- self . to_extensible ( ) . add_extended ( other) . to_extended ( )
138+ /// Adds an extensible point to a ProjectiveNiels point
139+ /// Returns an extensible point
140+ /// (3.1)[Last set of formulas] https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
141+ /// This differs from the formula above by a factor of 2. Saving 1 Double
142+ /// Cost 8M
143+ pub fn add_projective_niels ( & self , other : & ProjectiveNielsPoint ) -> ExtensiblePoint {
144+ // This is the only step which makes it different than adding an AffineNielsPoint
145+ let Z = self . Z * other. Z ;
146+
147+ let A = ( self . Y - self . X ) * other. Y_minus_X ;
148+ let B = ( self . Y + self . X ) * other. Y_plus_X ;
149+ let C = other. Td * self . T ;
150+ let D = B + A ;
151+ let E = B - A ;
152+ let F = Z - C ;
153+ let G = Z + C ;
154+ ExtensiblePoint {
155+ X : E * F ,
156+ Y : G * D ,
157+ Z : F * G ,
158+ T1 : E ,
159+ T2 : D ,
160+ }
80161 }
81162
82163 /// Converts an ExtendedPoint to an ExtensiblePoint
@@ -90,53 +171,16 @@ impl ExtendedPoint {
90171 }
91172 }
92173
93- /// Converts an extended point to Affine co-ordinates
94- pub ( crate ) fn to_affine ( self ) -> AffinePoint {
95- // Points to consider:
96- // - All points where Z=0, translate to (0,0)
97- // - The identity point has z=1, so it is not a problem
98-
99- let INV_Z = self . Z . invert ( ) ;
100-
101- let x = self . X * INV_Z ;
102- let y = self . Y * INV_Z ;
103-
104- AffinePoint { x, y }
105- }
106-
107- /// Edwards_Isogeny is derived from the doubling formula
108- /// XXX: There is a duplicate method in the twisted edwards module to compute the dual isogeny
109- /// XXX: Not much point trying to make it generic I think. So what we can do is optimise each respective isogeny method for a=1 or a = -1 (currently, I just made it really slow and simple)
110- fn edwards_isogeny ( & self , a : FieldElement ) -> EdwardsExtendedPoint {
111- // Convert to affine now, then derive extended version later
112- let affine = self . to_affine ( ) ;
113- let x = affine. x ;
114- let y = affine. y ;
115-
116- // Compute x
117- let xy = x * y;
118- let x_numerator = xy. double ( ) ;
119- let x_denom = y. square ( ) - ( a * x. square ( ) ) ;
120- let new_x = x_numerator * x_denom. invert ( ) ;
121-
122- // Compute y
123- let y_numerator = y. square ( ) + ( a * x. square ( ) ) ;
124- let y_denom = ( FieldElement :: ONE + FieldElement :: ONE ) - y. square ( ) - ( a * x. square ( ) ) ;
125- let new_y = y_numerator * y_denom. invert ( ) ;
126-
127- EdwardsExtendedPoint {
128- X : new_x,
129- Y : new_y,
130- Z : FieldElement :: ONE ,
131- T : new_x * new_y,
174+ /// Converts an Extensible point to a ProjectiveNiels Point
175+ pub fn to_projective_niels ( self ) -> ProjectiveNielsPoint {
176+ ProjectiveNielsPoint {
177+ Y_plus_X : self . X + self . Y ,
178+ Y_minus_X : self . Y - self . X ,
179+ Z : self . Z . double ( ) ,
180+ Td : self . T * FieldElement :: TWO_TIMES_TWISTED_D ,
132181 }
133182 }
134183
135- /// Uses a 2-isogeny to map the point to the Ed448-Goldilocks
136- pub fn to_untwisted ( self ) -> EdwardsExtendedPoint {
137- self . edwards_isogeny ( FieldElement :: MINUS_ONE )
138- }
139-
140184 /// Checks if the point is on the curve
141185 pub ( crate ) fn is_on_curve ( & self ) -> Choice {
142186 let XY = self . X * self . Y ;
@@ -178,6 +222,7 @@ impl ExtendedPoint {
178222#[ cfg( test) ]
179223mod tests {
180224 use super :: * ;
225+ use crate :: curve:: twedwards:: affine:: AffinePoint ;
181226 use crate :: { GOLDILOCKS_BASE_POINT , TWISTED_EDWARDS_BASE_POINT } ;
182227
183228 fn hex_to_field ( hex : & ' static str ) -> FieldElement {
@@ -196,7 +241,7 @@ mod tests {
196241 let y = hex_to_field (
197242 "ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed" ,
198243 ) ;
199- let a = AffinePoint { x, y } . to_extended ( ) ;
244+ let a = AffinePoint { x, y } . to_extensible ( ) ;
200245 let twist_a = a. to_untwisted ( ) . to_twisted ( ) ;
201246 assert_eq ! ( twist_a, a. double( ) . double( ) )
202247 }
@@ -220,28 +265,28 @@ mod tests {
220265 #[ test]
221266 fn test_point_add ( ) {
222267 let a = TWISTED_EDWARDS_BASE_POINT ;
223- let b = a. double ( ) ;
268+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
224269
225270 // A + B = B + A = C
226- let c_1 = a. to_extensible ( ) . add_extended ( & b) . to_extended ( ) ;
227- let c_2 = b. to_extensible ( ) . add_extended ( & a) . to_extended ( ) ;
271+ let c_1 = a. add_extended ( & b) . to_extended ( ) ;
272+ let c_2 = b. add_extended ( & a) . to_extended ( ) ;
228273 assert ! ( c_1 == c_2) ;
229274
230275 // Adding identity point should not change result
231- let c = c_1. to_extensible ( ) . add_extended ( & ExtendedPoint :: IDENTITY ) ;
232- assert ! ( c. to_extended ( ) == c_1) ;
276+ let c = c_1. add_extended ( & ExtendedPoint :: IDENTITY ) ;
277+ assert ! ( c == c_1) ;
233278 }
234279
235280 #[ test]
236281 fn test_point_sub ( ) {
237282 let a = TWISTED_EDWARDS_BASE_POINT ;
238- let b = a. double ( ) ;
283+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
239284
240285 // A - B = C
241- let c_1 = a. to_extensible ( ) . sub_extended ( & b) . to_extended ( ) ;
286+ let c_1 = a. sub_extended ( & b) . to_extended ( ) ;
242287
243288 // -B + A = C
244- let c_2 = b. negate ( ) . to_extensible ( ) . add_extended ( & a) . to_extended ( ) ;
289+ let c_2 = b. negate ( ) . add_extended ( & a) . to_extended ( ) ;
245290 assert ! ( c_1 == c_2) ;
246291 }
247292
@@ -250,6 +295,6 @@ mod tests {
250295 let a = TWISTED_EDWARDS_BASE_POINT ;
251296 let neg_a = a. negate ( ) ;
252297
253- assert ! ( a. to_extensible ( ) . add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
298+ assert ! ( a. add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
254299 }
255300}
0 commit comments