22#![ allow( dead_code) ]
33
44use super :: IsogenyMap ;
5- use super :: affine:: AffinePoint ;
65use super :: extensible:: ExtensiblePoint ;
6+ use super :: projective:: ProjectiveNielsPoint ;
7+ use super :: { IsogenyMapResult , affine:: AffineNielsPoint } ;
78use crate :: edwards:: EdwardsPoint as EdwardsExtendedPoint ;
89use crate :: field:: FieldElement ;
910use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
@@ -44,6 +45,11 @@ impl PartialEq for ExtendedPoint {
4445 self . ct_eq ( other) . into ( )
4546 }
4647}
48+ impl PartialEq < ExtensiblePoint > for ExtendedPoint {
49+ fn eq ( & self , other : & ExtensiblePoint ) -> bool {
50+ self . to_extensible ( ) . ct_eq ( other) . into ( )
51+ }
52+ }
4753impl Eq for ExtendedPoint { }
4854
4955impl Default for ExtendedPoint {
@@ -70,14 +76,90 @@ impl ExtendedPoint {
7076 T : FieldElement :: ZERO ,
7177 } ;
7278
73- /// Doubles an extended point
74- pub ( crate ) fn double ( & self ) -> ExtendedPoint {
75- self . to_extensible ( ) . double ( ) . to_extended ( )
79+ /// Adds an extensible point to an extended point
80+ /// Returns an extensible point
81+ /// (3.1) https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
82+ pub fn add_extended ( & self , other : & ExtendedPoint ) -> ExtensiblePoint {
83+ let A = self . X * other. X ;
84+ let B = self . Y * other. Y ;
85+ let C = self . T * other. T * FieldElement :: TWISTED_D ;
86+ let D = self . Z * other. Z ;
87+ let E = ( self . X + self . Y ) * ( other. X + other. Y ) - A - B ;
88+ let F = D - C ;
89+ let G = D + C ;
90+ let H = B + A ;
91+ ExtensiblePoint {
92+ X : E * F ,
93+ Y : G * H ,
94+ T1 : E ,
95+ T2 : H ,
96+ Z : F * G ,
97+ }
7698 }
7799
78- /// Adds an extended point to itself
79- pub ( crate ) fn add ( & self , other : & ExtendedPoint ) -> ExtendedPoint {
80- self . to_extensible ( ) . add_extended ( other) . to_extended ( )
100+ /// Subtracts an extensible point from an extended point
101+ /// Returns an extensible point
102+ /// This is a direct modification of the addition formula to the negation of `other`
103+ pub fn sub_extended ( & self , other : & ExtendedPoint ) -> ExtensiblePoint {
104+ let A = self . X * other. X ;
105+ let B = self . Y * other. Y ;
106+ let C = self . T * other. T * FieldElement :: TWISTED_D ;
107+ let D = self . Z * other. Z ;
108+ let E = ( self . X + self . Y ) * ( other. Y - other. X ) + A - B ;
109+ let F = D + C ;
110+ let G = D - C ;
111+ let H = B - A ;
112+ ExtensiblePoint {
113+ X : E * F ,
114+ Y : G * H ,
115+ T1 : E ,
116+ T2 : H ,
117+ Z : F * G ,
118+ }
119+ }
120+
121+ /// Adds an extensible point to an AffineNiels point
122+ /// Returns an Extensible point
123+ pub fn add_affine_niels ( & self , other : AffineNielsPoint ) -> ExtensiblePoint {
124+ let A = other. y_minus_x * ( self . Y - self . X ) ;
125+ let B = other. y_plus_x * ( self . X + self . Y ) ;
126+ let C = other. td * self . T ;
127+ let D = B + A ;
128+ let E = B - A ;
129+ let F = self . Z - C ;
130+ let G = self . Z + C ;
131+ ExtensiblePoint {
132+ X : E * F ,
133+ Y : G * D ,
134+ Z : F * G ,
135+ T1 : E ,
136+ T2 : D ,
137+ }
138+ }
139+
140+ /// Adds an extensible point to a ProjectiveNiels point
141+ /// Returns an extensible point
142+ /// (3.1)[Last set of formulas] https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf
143+ /// This differs from the formula above by a factor of 2. Saving 1 Double
144+ /// Cost 8M
145+ pub fn add_projective_niels ( & self , other : & ProjectiveNielsPoint ) -> ExtensiblePoint {
146+ // This is the only step which makes it different than adding an AffineNielsPoint
147+ let Z = self . Z * other. Z ;
148+
149+ let A = ( self . Y - self . X ) * other. Y_minus_X ;
150+ let B = ( self . Y + self . X ) * other. Y_plus_X ;
151+ let C = other. Td * self . T ;
152+ let D = B + A ;
153+ let E = B - A ;
154+ let F = Z - C ;
155+ let G = Z + C ;
156+ ExtensiblePoint {
157+ X : E * F ,
158+ Y : G * D ,
159+ Z : F * G ,
160+ T1 : E ,
161+ T2 : D ,
162+ }
81163 }
82164
83165 /// Converts an ExtendedPoint to an ExtensiblePoint
@@ -91,31 +173,32 @@ impl ExtendedPoint {
91173 }
92174 }
93175
94- /// Converts an extended point to Affine co-ordinates
95- pub ( crate ) fn to_affine ( self ) -> AffinePoint {
96- // Points to consider:
97- // - All points where Z=0, translate to (0,0)
98- // - The identity point has z=1, so it is not a problem
99-
100- let INV_Z = self . Z . invert ( ) ;
101-
102- let x = self . X * INV_Z ;
103- let y = self . Y * INV_Z ;
104-
105- AffinePoint { x, y }
106- }
107-
108176 /// Uses a 2-isogeny to map the point to the Ed448-Goldilocks
109177 pub fn to_untwisted ( self ) -> EdwardsExtendedPoint {
110- let IsogenyMap { X, Y, T , Z } = IsogenyMap {
178+ let IsogenyMapResult { X, Y, Z , T1 , T2 } = IsogenyMap {
111179 X : self . X ,
112180 Y : self . Y ,
113- T : self . T ,
114181 Z : self . Z ,
182+ T : self . T ,
115183 }
116184 . map ( |f| -f) ;
117185
118- EdwardsExtendedPoint { X , Y , Z , T }
186+ EdwardsExtendedPoint {
187+ X ,
188+ Y ,
189+ Z ,
190+ T : T1 * T2 ,
191+ }
192+ }
193+
194+ /// Converts an Extensible point to a ProjectiveNiels Point
195+ pub fn to_projective_niels ( self ) -> ProjectiveNielsPoint {
196+ ProjectiveNielsPoint {
197+ Y_plus_X : self . X + self . Y ,
198+ Y_minus_X : self . Y - self . X ,
199+ Z : self . Z . double ( ) ,
200+ Td : self . T * FieldElement :: TWO_TIMES_TWISTED_D ,
201+ }
119202 }
120203
121204 /// Checks if the point is on the curve
@@ -159,6 +242,7 @@ impl ExtendedPoint {
159242#[ cfg( test) ]
160243mod tests {
161244 use super :: * ;
245+ use crate :: curve:: twedwards:: affine:: AffinePoint ;
162246 use crate :: { GOLDILOCKS_BASE_POINT , TWISTED_EDWARDS_BASE_POINT } ;
163247
164248 fn hex_to_field ( hex : & ' static str ) -> FieldElement {
@@ -177,8 +261,8 @@ mod tests {
177261 let y = hex_to_field (
178262 "ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed" ,
179263 ) ;
180- let a = AffinePoint { x, y } . to_extended ( ) ;
181- let twist_a = a. to_untwisted ( ) . to_twisted ( ) ;
264+ let a = AffinePoint { x, y } . to_extensible ( ) ;
265+ let twist_a = a. to_extended ( ) . to_untwisted ( ) . to_twisted ( ) ;
182266 assert_eq ! ( twist_a, a. double( ) . double( ) )
183267 }
184268
@@ -201,28 +285,28 @@ mod tests {
201285 #[ test]
202286 fn test_point_add ( ) {
203287 let a = TWISTED_EDWARDS_BASE_POINT ;
204- let b = a. double ( ) ;
288+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
205289
206290 // A + B = B + A = C
207- let c_1 = a. to_extensible ( ) . add_extended ( & b) . to_extended ( ) ;
208- let c_2 = b. to_extensible ( ) . add_extended ( & a) . to_extended ( ) ;
291+ let c_1 = a. add_extended ( & b) . to_extended ( ) ;
292+ let c_2 = b. add_extended ( & a) . to_extended ( ) ;
209293 assert ! ( c_1 == c_2) ;
210294
211295 // Adding identity point should not change result
212- let c = c_1. to_extensible ( ) . add_extended ( & ExtendedPoint :: IDENTITY ) ;
213- assert ! ( c. to_extended ( ) == c_1) ;
296+ let c = c_1. add_extended ( & ExtendedPoint :: IDENTITY ) ;
297+ assert ! ( c == c_1) ;
214298 }
215299
216300 #[ test]
217301 fn test_point_sub ( ) {
218302 let a = TWISTED_EDWARDS_BASE_POINT ;
219- let b = a. double ( ) ;
303+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
220304
221305 // A - B = C
222- let c_1 = a. to_extensible ( ) . sub_extended ( & b) . to_extended ( ) ;
306+ let c_1 = a. sub_extended ( & b) . to_extended ( ) ;
223307
224308 // -B + A = C
225- let c_2 = b. negate ( ) . to_extensible ( ) . add_extended ( & a) . to_extended ( ) ;
309+ let c_2 = b. negate ( ) . add_extended ( & a) . to_extended ( ) ;
226310 assert ! ( c_1 == c_2) ;
227311 }
228312
@@ -231,6 +315,6 @@ mod tests {
231315 let a = TWISTED_EDWARDS_BASE_POINT ;
232316 let neg_a = a. negate ( ) ;
233317
234- assert ! ( a. to_extensible ( ) . add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
318+ assert ! ( a. add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
235319 }
236320}
0 commit comments