1
1
#![ allow( non_snake_case) ]
2
2
#![ allow( dead_code) ]
3
3
4
- use crate :: curve:: twedwards:: affine:: AffinePoint ;
4
+ use crate :: curve:: twedwards:: affine:: AffineNielsPoint ;
5
5
use crate :: curve:: twedwards:: extensible:: ExtensiblePoint ;
6
- use crate :: edwards :: EdwardsPoint as EdwardsExtendedPoint ;
6
+ use crate :: curve :: twedwards :: projective :: ProjectiveNielsPoint ;
7
7
use crate :: field:: FieldElement ;
8
8
use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
9
9
@@ -43,6 +43,11 @@ impl PartialEq for ExtendedPoint {
43
43
self . ct_eq ( other) . into ( )
44
44
}
45
45
}
46
+ impl PartialEq < ExtensiblePoint > for ExtendedPoint {
47
+ fn eq ( & self , other : & ExtensiblePoint ) -> bool {
48
+ self . to_extensible ( ) . ct_eq ( other) . into ( )
49
+ }
50
+ }
46
51
impl Eq for ExtendedPoint { }
47
52
48
53
impl Default for ExtendedPoint {
@@ -69,14 +74,90 @@ impl ExtendedPoint {
69
74
T : FieldElement :: ZERO ,
70
75
} ;
71
76
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
+ }
75
136
}
76
137
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
+ }
80
161
}
81
162
82
163
/// Converts an ExtendedPoint to an ExtensiblePoint
@@ -90,53 +171,16 @@ impl ExtendedPoint {
90
171
}
91
172
}
92
173
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 ,
132
181
}
133
182
}
134
183
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
-
140
184
/// Checks if the point is on the curve
141
185
pub ( crate ) fn is_on_curve ( & self ) -> Choice {
142
186
let XY = self . X * self . Y ;
@@ -178,6 +222,7 @@ impl ExtendedPoint {
178
222
#[ cfg( test) ]
179
223
mod tests {
180
224
use super :: * ;
225
+ use crate :: curve:: twedwards:: affine:: AffinePoint ;
181
226
use crate :: { GOLDILOCKS_BASE_POINT , TWISTED_EDWARDS_BASE_POINT } ;
182
227
183
228
fn hex_to_field ( hex : & ' static str ) -> FieldElement {
@@ -196,7 +241,7 @@ mod tests {
196
241
let y = hex_to_field (
197
242
"ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed" ,
198
243
) ;
199
- let a = AffinePoint { x, y } . to_extended ( ) ;
244
+ let a = AffinePoint { x, y } . to_extensible ( ) ;
200
245
let twist_a = a. to_untwisted ( ) . to_twisted ( ) ;
201
246
assert_eq ! ( twist_a, a. double( ) . double( ) )
202
247
}
@@ -220,28 +265,28 @@ mod tests {
220
265
#[ test]
221
266
fn test_point_add ( ) {
222
267
let a = TWISTED_EDWARDS_BASE_POINT ;
223
- let b = a. double ( ) ;
268
+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
224
269
225
270
// 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 ( ) ;
228
273
assert ! ( c_1 == c_2) ;
229
274
230
275
// 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) ;
233
278
}
234
279
235
280
#[ test]
236
281
fn test_point_sub ( ) {
237
282
let a = TWISTED_EDWARDS_BASE_POINT ;
238
- let b = a. double ( ) ;
283
+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
239
284
240
285
// 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 ( ) ;
242
287
243
288
// -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 ( ) ;
245
290
assert ! ( c_1 == c_2) ;
246
291
}
247
292
@@ -250,6 +295,6 @@ mod tests {
250
295
let a = TWISTED_EDWARDS_BASE_POINT ;
251
296
let neg_a = a. negate ( ) ;
252
297
253
- assert ! ( a. to_extensible ( ) . add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
298
+ assert ! ( a. add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
254
299
}
255
300
}
0 commit comments