@@ -73,8 +73,8 @@ impl PartialEq for MontgomeryXpoint {
73
73
/// A Projective point in Montgomery form
74
74
#[ derive( Copy , Clone , Debug , Eq ) ]
75
75
pub struct ProjectiveMontgomeryXpoint {
76
- U : FieldElement ,
77
- W : FieldElement ,
76
+ pub ( super ) U : FieldElement ,
77
+ pub ( super ) W : FieldElement ,
78
78
}
79
79
80
80
impl Mul < & MontgomeryScalar > for & MontgomeryXpoint {
@@ -118,6 +118,30 @@ impl MontgomeryXpoint {
118
118
self . to_projective ( ) . y ( sign) . to_bytes ( )
119
119
}
120
120
121
+ pub ( super ) fn mul_internal (
122
+ & self ,
123
+ scalar : & MontgomeryScalar ,
124
+ ) -> ( ProjectiveMontgomeryXpoint , ProjectiveMontgomeryXpoint ) {
125
+ // Algorithm 8 of Costello-Smith 2017
126
+ let mut x0 = ProjectiveMontgomeryXpoint :: IDENTITY ;
127
+ let mut x1 = self . to_projective ( ) ;
128
+ let diff = x1. U ;
129
+
130
+ let bits = scalar. bits ( ) ;
131
+ let mut swap = 0 ;
132
+ for s in ( 0 ..448 ) . rev ( ) {
133
+ let bit = bits[ s] as u8 ;
134
+ let choice: u8 = swap ^ bit;
135
+
136
+ ProjectiveMontgomeryXpoint :: conditional_swap ( & mut x0, & mut x1, Choice :: from ( choice) ) ;
137
+ differential_add_and_double ( & mut x0, & mut x1, & diff) ;
138
+
139
+ swap = bit;
140
+ }
141
+
142
+ ( x0, x1)
143
+ }
144
+
121
145
/// Convert the point to its form including the y-coordinate
122
146
pub fn to_projective ( & self ) -> ProjectiveMontgomeryXpoint {
123
147
ProjectiveMontgomeryXpoint {
@@ -168,23 +192,7 @@ impl Mul<&MontgomeryScalar> for &ProjectiveMontgomeryXpoint {
168
192
169
193
#[ allow( clippy:: suspicious_arithmetic_impl) ]
170
194
fn mul ( self , scalar : & MontgomeryScalar ) -> ProjectiveMontgomeryXpoint {
171
- // Algorithm 8 of Costello-Smith 2017
172
- let mut x0 = ProjectiveMontgomeryXpoint :: IDENTITY ;
173
- let mut x1 = * self ;
174
-
175
- let bits = scalar. bits ( ) ;
176
- let mut swap = 0 ;
177
- for s in ( 0 ..448 ) . rev ( ) {
178
- let bit = bits[ s] as u8 ;
179
- let choice: u8 = swap ^ bit;
180
-
181
- ProjectiveMontgomeryXpoint :: conditional_swap ( & mut x0, & mut x1, Choice :: from ( choice) ) ;
182
- differential_add_and_double ( & mut x0, & mut x1, & self . U ) ;
183
-
184
- swap = bit;
185
- }
186
-
187
- x0
195
+ self . to_affine ( ) . mul_internal ( scalar) . 0
188
196
}
189
197
}
190
198
@@ -196,6 +204,8 @@ impl Mul<&ProjectiveMontgomeryXpoint> for &MontgomeryScalar {
196
204
}
197
205
}
198
206
207
+ // (1987 Montgomery) Speeding the Pollard and elliptic curve methods of factorization
208
+ // fifth and sixth displays, plus common-subexpression elimination, plus assumption Z1=1
199
209
fn differential_add_and_double (
200
210
P : & mut ProjectiveMontgomeryXpoint ,
201
211
Q : & mut ProjectiveMontgomeryXpoint ,
@@ -371,11 +381,11 @@ mod tests {
371
381
let scalar = MontgomeryScalar :: from ( 200u32 ) ;
372
382
373
383
// Montgomery scalar mul
374
- let montgomery_res = ( & ProjectiveMontgomeryXpoint :: GENERATOR * & scalar) . to_affine ( ) ;
384
+ let montgomery_res =
385
+ ( & ( & ProjectiveMontgomeryXpoint :: GENERATOR * & scalar) * & scalar) . to_affine ( ) ;
375
386
// Goldilocks scalar mul
376
- let goldilocks_point = EdwardsPoint :: GENERATOR
377
- . scalar_mul ( & scalar. to_scalar ( ) )
378
- . to_affine ( ) ;
387
+ let goldilocks_point =
388
+ ( EdwardsPoint :: GENERATOR * scalar. to_scalar ( ) * scalar. to_scalar ( ) ) . to_affine ( ) ;
379
389
380
390
assert_eq ! ( goldilocks_point. to_montgomery_x( ) , montgomery_res) ;
381
391
}
0 commit comments