@@ -4,7 +4,7 @@ use crate::edwards::extended::EdwardsPoint;
4
4
use crate :: field:: FieldElement ;
5
5
use core:: fmt;
6
6
use core:: ops:: Mul ;
7
- use subtle:: { Choice , ConditionallySelectable , ConstantTimeEq } ;
7
+ use subtle:: { Choice , ConditionallyNegatable , ConditionallySelectable , ConstantTimeEq } ;
8
8
9
9
impl MontgomeryXpoint {
10
10
/// First low order point on Curve448 and it's twist
@@ -131,6 +131,11 @@ impl MontgomeryXpoint {
131
131
& self . 0
132
132
}
133
133
134
+ /// Compute the Y-coordinate
135
+ pub fn y ( & self , sign : Choice ) -> [ u8 ; 56 ] {
136
+ self . to_projective ( ) . y ( sign) . to_bytes ( )
137
+ }
138
+
134
139
/// Convert the point to a ProjectiveMontgomeryPoint
135
140
pub fn to_projective ( & self ) -> ProjectiveMontgomeryXpoint {
136
141
ProjectiveMontgomeryXpoint {
@@ -228,6 +233,18 @@ impl ProjectiveMontgomeryXpoint {
228
233
}
229
234
}
230
235
236
+ /// Compute the Y-coordinate
237
+ // See https://www.rfc-editor.org/rfc/rfc7748#section-1.
238
+ pub fn y ( & self , sign : Choice ) -> FieldElement {
239
+ // v^2 = u^3 + A*u^2 + u
240
+ let u_sq = self . U . square ( ) ;
241
+ let v_sq = u_sq * self . U + FieldElement :: J * u_sq + self . U ;
242
+
243
+ let mut v = v_sq. sqrt ( ) ;
244
+ v. conditional_negate ( v. is_negative ( ) ^ sign) ;
245
+ v
246
+ }
247
+
231
248
/// Convert the point to affine form
232
249
pub fn to_affine ( & self ) -> MontgomeryXpoint {
233
250
let x = self . U * self . W . invert ( ) ;
0 commit comments