Skip to content

Commit 4ca23f2

Browse files
committed
Add y-coordinate recovery
1 parent 2192ef6 commit 4ca23f2

File tree

1 file changed

+18
-1
lines changed
  • ed448-goldilocks/src/montgomery

1 file changed

+18
-1
lines changed

ed448-goldilocks/src/montgomery/x.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::edwards::extended::EdwardsPoint;
44
use crate::field::FieldElement;
55
use core::fmt;
66
use core::ops::Mul;
7-
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
7+
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};
88

99
impl MontgomeryXpoint {
1010
/// First low order point on Curve448 and it's twist
@@ -131,6 +131,11 @@ impl MontgomeryXpoint {
131131
&self.0
132132
}
133133

134+
/// Compute the Y-coordinate
135+
pub fn y(&self, sign: Choice) -> [u8; 56] {
136+
self.to_projective().y(sign).to_bytes()
137+
}
138+
134139
/// Convert the point to a ProjectiveMontgomeryPoint
135140
pub fn to_projective(&self) -> ProjectiveMontgomeryXpoint {
136141
ProjectiveMontgomeryXpoint {
@@ -228,6 +233,18 @@ impl ProjectiveMontgomeryXpoint {
228233
}
229234
}
230235

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+
231248
/// Convert the point to affine form
232249
pub fn to_affine(&self) -> MontgomeryXpoint {
233250
let x = self.U * self.W.invert();

0 commit comments

Comments
 (0)