Skip to content

Commit 543067d

Browse files
committed
Add y-coordinate recovery
1 parent 853ca1e commit 543067d

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
// Low order points on Curve448 and it's twist
1010
const LOW_A: MontgomeryXpoint = MontgomeryXpoint([
@@ -127,6 +127,11 @@ impl MontgomeryXpoint {
127127
&self.0
128128
}
129129

130+
/// Compute the Y-coordinate
131+
pub fn y(&self, sign: Choice) -> [u8; 56] {
132+
self.to_projective().y(sign).to_bytes()
133+
}
134+
130135
/// Convert the point to a ProjectiveMontgomeryPoint
131136
pub fn to_projective(&self) -> ProjectiveMontgomeryXpoint {
132137
ProjectiveMontgomeryXpoint {
@@ -224,6 +229,18 @@ impl ProjectiveMontgomeryXpoint {
224229
}
225230
}
226231

232+
/// Compute the Y-coordinate
233+
// See https://www.rfc-editor.org/rfc/rfc7748#section-1.
234+
pub fn y(&self, sign: Choice) -> FieldElement {
235+
// v^2 = u^3 + A*u^2 + u
236+
let u_sq = self.U.square();
237+
let v_sq = u_sq * self.U + FieldElement::J * u_sq + self.U;
238+
239+
let mut v = v_sq.sqrt();
240+
v.conditional_negate(v.is_negative() ^ sign);
241+
v
242+
}
243+
227244
/// Convert the point to affine form
228245
pub fn to_affine(&self) -> MontgomeryXpoint {
229246
let x = self.U * self.W.invert();

0 commit comments

Comments
 (0)