@@ -41,7 +41,7 @@ const LOW_C: MontgomeryXpoint = MontgomeryXpoint([
41
41
] ) ;
42
42
43
43
/// A point in Montgomery form
44
- #[ derive( Copy , Clone ) ]
44
+ #[ derive( Copy , Clone , Eq ) ]
45
45
pub struct MontgomeryXpoint ( pub [ u8 ; 56 ] ) ;
46
46
47
47
impl Default for MontgomeryXpoint {
@@ -69,10 +69,9 @@ impl PartialEq for MontgomeryXpoint {
69
69
self . ct_eq ( other) . into ( )
70
70
}
71
71
}
72
- impl Eq for MontgomeryXpoint { }
73
72
74
73
/// A Projective point in Montgomery form
75
- #[ derive( Copy , Clone , Debug ) ]
74
+ #[ derive( Copy , Clone , Debug , Eq ) ]
76
75
pub struct ProjectiveMontgomeryXpoint {
77
76
U : FieldElement ,
78
77
W : FieldElement ,
@@ -143,6 +142,12 @@ impl MontgomeryXpoint {
143
142
}
144
143
}
145
144
145
+ impl ConstantTimeEq for ProjectiveMontgomeryXpoint {
146
+ fn ct_eq ( & self , other : & Self ) -> Choice {
147
+ self . U . ct_eq ( & other. U ) & self . W . ct_eq ( & other. W )
148
+ }
149
+ }
150
+
146
151
impl ConditionallySelectable for ProjectiveMontgomeryXpoint {
147
152
fn conditional_select ( a : & Self , b : & Self , choice : Choice ) -> Self {
148
153
Self {
@@ -152,6 +157,12 @@ impl ConditionallySelectable for ProjectiveMontgomeryXpoint {
152
157
}
153
158
}
154
159
160
+ impl PartialEq for ProjectiveMontgomeryXpoint {
161
+ fn eq ( & self , other : & Self ) -> bool {
162
+ self . ct_eq ( other) . into ( )
163
+ }
164
+ }
165
+
155
166
impl Mul < & MontgomeryScalar > for & ProjectiveMontgomeryXpoint {
156
167
type Output = ProjectiveMontgomeryXpoint ;
157
168
@@ -341,14 +352,19 @@ impl ProjectiveMontgomeryXpoint {
341
352
342
353
/// Convert the point to its form including the y-coordinate
343
354
pub fn to_extended ( & self , sign : Choice ) -> ProjectiveMontgomeryPoint {
344
- ProjectiveMontgomeryPoint :: new ( self . U , self . y ( sign) , self . W )
355
+ ProjectiveMontgomeryPoint :: conditional_select (
356
+ & ProjectiveMontgomeryPoint :: new ( self . U , self . y ( sign) , self . W ) ,
357
+ & ProjectiveMontgomeryPoint :: IDENTITY ,
358
+ self . ct_eq ( & Self :: IDENTITY ) ,
359
+ )
345
360
}
346
361
}
347
362
348
363
#[ cfg( test) ]
349
364
mod tests {
350
365
use super :: * ;
351
366
use crate :: EdwardsPoint ;
367
+ use elliptic_curve:: CurveGroup ;
352
368
use hex_literal:: hex;
353
369
use sha3:: Shake256 ;
354
370
@@ -366,6 +382,22 @@ mod tests {
366
382
assert_eq ! ( goldilocks_point. to_montgomery_x( ) , montgomery_res) ;
367
383
}
368
384
385
+ #[ test]
386
+ fn test_montgomery_extended ( ) {
387
+ let x_identity = ProjectiveMontgomeryXpoint :: IDENTITY ;
388
+ let identity = ProjectiveMontgomeryPoint :: IDENTITY ;
389
+
390
+ assert_eq ! ( x_identity. to_extended( Choice :: from( 1 ) ) , identity) ;
391
+ }
392
+
393
+ #[ test]
394
+ fn test_montgomery_extended_affine ( ) {
395
+ let x_identity = ProjectiveMontgomeryXpoint :: IDENTITY . to_affine ( ) ;
396
+ let identity = ProjectiveMontgomeryPoint :: IDENTITY . to_affine ( ) ;
397
+
398
+ assert_eq ! ( x_identity. to_extended( Choice :: from( 1 ) ) , identity) ;
399
+ }
400
+
369
401
#[ test]
370
402
fn hash_with_test_vectors ( ) {
371
403
const DST : & [ u8 ] = b"QUUX-V01-CS02-with-curve448_XOF:SHAKE256_ELL2_RO_" ;
0 commit comments