2
2
#![ allow( dead_code) ]
3
3
4
4
use super :: IsogenyMap ;
5
- use super :: affine:: AffinePoint ;
6
5
use super :: extensible:: ExtensiblePoint ;
6
+ use super :: projective:: ProjectiveNielsPoint ;
7
+ use super :: { IsogenyMapResult , affine:: AffineNielsPoint } ;
7
8
use crate :: edwards:: EdwardsPoint as EdwardsExtendedPoint ;
8
9
use crate :: field:: FieldElement ;
9
10
use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
@@ -44,6 +45,11 @@ impl PartialEq for ExtendedPoint {
44
45
self . ct_eq ( other) . into ( )
45
46
}
46
47
}
48
+ impl PartialEq < ExtensiblePoint > for ExtendedPoint {
49
+ fn eq ( & self , other : & ExtensiblePoint ) -> bool {
50
+ self . to_extensible ( ) . ct_eq ( other) . into ( )
51
+ }
52
+ }
47
53
impl Eq for ExtendedPoint { }
48
54
49
55
impl Default for ExtendedPoint {
@@ -70,14 +76,90 @@ impl ExtendedPoint {
70
76
T : FieldElement :: ZERO ,
71
77
} ;
72
78
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
+ }
76
98
}
77
99
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
+ }
81
163
}
82
164
83
165
/// Converts an ExtendedPoint to an ExtensiblePoint
@@ -91,31 +173,32 @@ impl ExtendedPoint {
91
173
}
92
174
}
93
175
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
-
108
176
/// Uses a 2-isogeny to map the point to the Ed448-Goldilocks
109
177
pub fn to_untwisted ( self ) -> EdwardsExtendedPoint {
110
- let IsogenyMap { X, Y, T , Z } = IsogenyMap {
178
+ let IsogenyMapResult { X, Y, Z , T1 , T2 } = IsogenyMap {
111
179
X : self . X ,
112
180
Y : self . Y ,
113
- T : self . T ,
114
181
Z : self . Z ,
182
+ T : self . T ,
115
183
}
116
184
. map ( |f| -f) ;
117
185
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
+ }
119
202
}
120
203
121
204
/// Checks if the point is on the curve
@@ -159,6 +242,7 @@ impl ExtendedPoint {
159
242
#[ cfg( test) ]
160
243
mod tests {
161
244
use super :: * ;
245
+ use crate :: curve:: twedwards:: affine:: AffinePoint ;
162
246
use crate :: { GOLDILOCKS_BASE_POINT , TWISTED_EDWARDS_BASE_POINT } ;
163
247
164
248
fn hex_to_field ( hex : & ' static str ) -> FieldElement {
@@ -177,8 +261,8 @@ mod tests {
177
261
let y = hex_to_field (
178
262
"ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed" ,
179
263
) ;
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 ( ) ;
182
266
assert_eq ! ( twist_a, a. double( ) . double( ) )
183
267
}
184
268
@@ -201,28 +285,28 @@ mod tests {
201
285
#[ test]
202
286
fn test_point_add ( ) {
203
287
let a = TWISTED_EDWARDS_BASE_POINT ;
204
- let b = a. double ( ) ;
288
+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
205
289
206
290
// 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 ( ) ;
209
293
assert ! ( c_1 == c_2) ;
210
294
211
295
// 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) ;
214
298
}
215
299
216
300
#[ test]
217
301
fn test_point_sub ( ) {
218
302
let a = TWISTED_EDWARDS_BASE_POINT ;
219
- let b = a. double ( ) ;
303
+ let b = a. to_extensible ( ) . double ( ) . to_extended ( ) ;
220
304
221
305
// 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 ( ) ;
223
307
224
308
// -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 ( ) ;
226
310
assert ! ( c_1 == c_2) ;
227
311
}
228
312
@@ -231,6 +315,6 @@ mod tests {
231
315
let a = TWISTED_EDWARDS_BASE_POINT ;
232
316
let neg_a = a. negate ( ) ;
233
317
234
- assert ! ( a. to_extensible ( ) . add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
318
+ assert ! ( a. add_extended( & neg_a) == ExtensiblePoint :: IDENTITY ) ;
235
319
}
236
320
}
0 commit comments