From 67288e5552a23d3ec9acf518870c148db898a093 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 5 Jun 2025 09:16:11 -0600 Subject: [PATCH 1/3] elliptic-curve: expose `AffineCoordinates::y` In the past we've deliberately avoided exposing the y-coordinate to prevent the possibility of things like invalid curve attacks, although with time we have exposed more and more to support things like alternative point compression formats. See #1237 for some history. We're now trying to use these traits with Edwards curves like Curve25519 (in `curve25519-dalek`) and Ed448-Goldilocks, which use compressed Edwards y-coordinates as their compressed point format. That requires y-coordinate access. As such, this changes the previous `y_is_odd` method, which was used to implement SEC1-like compressed points, to a full `fn y` which returns a serialized field element for the y-coordinate. Closes #1019 --- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/point.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 98d4c8e1d..2743f7eca 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -473,7 +473,7 @@ impl AffineCoordinates for AffinePoint { unimplemented!(); } - fn y_is_odd(&self) -> Choice { + fn y(&self) -> FieldBytes { unimplemented!(); } } diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index ee4eded44..04cc15ea7 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -28,8 +28,8 @@ pub trait AffineCoordinates { /// Get the affine x-coordinate as a serialized field element. fn x(&self) -> Self::FieldRepr; - /// Is the affine y-coordinate odd? - fn y_is_odd(&self) -> Choice; + /// Get the affine y-coordinate as a serialized field element. + fn y(&self) -> Self::FieldRepr; } /// Normalize point(s) in projective representation by converting them to their affine ones. From 029da825acd756305f12177c1730bbc73b698b36 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 5 Jun 2025 09:43:51 -0600 Subject: [PATCH 2/3] Add back `y_is_odd` This is quite hard to express via the trait-based interface otherwise, which is needed for ECDSA recovery, at the very least. We can experiment with getting rid of this before the next release, but preserving it ensures this change isn't breaking for now. --- elliptic-curve/src/dev.rs | 4 ++++ elliptic-curve/src/point.rs | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2743f7eca..f386c1485 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -476,6 +476,10 @@ impl AffineCoordinates for AffinePoint { fn y(&self) -> FieldBytes { unimplemented!(); } + + fn y_is_odd(&self) -> Choice { + unimplemented!(); + } } impl ConstantTimeEq for AffinePoint { diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 04cc15ea7..c6e87e37f 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -22,7 +22,7 @@ pub type ProjectivePoint = ::ProjectivePoint; /// Access to the affine coordinates of an elliptic curve point. // TODO: use zkcrypto/group#30 coordinate API when available pub trait AffineCoordinates { - /// Field element representation. + /// Field element representation with curve-specific serialization/endianness. type FieldRepr: AsRef<[u8]>; /// Get the affine x-coordinate as a serialized field element. @@ -30,6 +30,9 @@ pub trait AffineCoordinates { /// Get the affine y-coordinate as a serialized field element. fn y(&self) -> Self::FieldRepr; + + /// Is the affine y-coordinate odd? + fn y_is_odd(&self) -> Choice; } /// Normalize point(s) in projective representation by converting them to their affine ones. From 6af8222b26a1b960deb4870863350a47e2d1c3de Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 5 Jun 2025 09:52:17 -0600 Subject: [PATCH 3/3] Add `AffineCoordinates::x_is_odd` For symmetry with `y_is_odd`. This is also useful for point compression using an Edwards y-coordinate. --- elliptic-curve/src/dev.rs | 4 ++++ elliptic-curve/src/point.rs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f386c1485..5d1eb8887 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -477,6 +477,10 @@ impl AffineCoordinates for AffinePoint { unimplemented!(); } + fn x_is_odd(&self) -> Choice { + unimplemented!(); + } + fn y_is_odd(&self) -> Choice { unimplemented!(); } diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index c6e87e37f..2eec19245 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -31,6 +31,9 @@ pub trait AffineCoordinates { /// Get the affine y-coordinate as a serialized field element. fn y(&self) -> Self::FieldRepr; + /// Is the affine x-coordinate odd? + fn x_is_odd(&self) -> Choice; + /// Is the affine y-coordinate odd? fn y_is_odd(&self) -> Choice; }