Skip to content

Commit

Permalink
elliptic-curve: consolidate AffineCoordinates trait (#1237)
Browse files Browse the repository at this point in the history
See RustCrypto/elliptic-curves#50 for some historic context.

After being able to get by on `AffineXCoordinate` for generic ECDH and
ECDSA, #1199 added an `AffineYIsOdd` trait which was needed to enable
the generic ECDSA implementation in the `ecdsa` crate to compute the
"recovery ID" for signatures (which is effectively point compression for
the `R` curve point).

This commit consolidates `AffineXCoordinate` and `AffineYIsOdd` into
an `AffineCoordinates` trait.

Some observations since prior discussion in
RustCrypto/elliptic-curves#50:

- Access to coordinates is through bytes, namely `FieldBytes`. This is
  so as to avoid exposing a crate's field element type. This approach
  isn't type safe (base field elements and scalar field elements share
  the same serialization) but does make ECDSA's weird reduction of a
  base field element into the scalar field straightforward in generic
  code.
- Prior to this attempts were made to extract ECDSA-specific bits into a
  trait to handle these conversions, but it complicates both writing
  generic code and optimizing performance. While this still might be
  worth exploring, so far those explorations have largely failed.
- Generally there have been a lot of requests for coordinate access
  specifically for things like point serialization formats. We ended up
  adding "compaction" support upstream but we have had requests for
  several other formats (e.g. Elligator Squared) where direct coordinate
  access would be useful.

This trait can hopefully be replaced by a coordinate access API provided
by the `group` crate in the future. See zkcrypto/group#30
  • Loading branch information
tarcieri authored Feb 1, 2023
1 parent 4ad2fc1 commit d69d5b9
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 13 deletions.
5 changes: 2 additions & 3 deletions elliptic-curve/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign},
point::{AffineXCoordinate, AffineYIsOdd},
point::AffineCoordinates,
scalar::FromUintUnchecked,
scalar::IsHigh,
Curve, FieldBytes, PrimeCurve, ScalarPrimitive,
Expand All @@ -15,8 +15,7 @@ use zeroize::DefaultIsZeroes;
pub trait CurveArithmetic: Curve {
/// Elliptic curve point in affine coordinates.
type AffinePoint: 'static
+ AffineXCoordinate<FieldRepr = FieldBytes<Self>>
+ AffineYIsOdd
+ AffineCoordinates<FieldRepr = FieldBytes<Self>>
+ Copy
+ ConditionallySelectable
+ ConstantTimeEq
Expand Down
6 changes: 2 additions & 4 deletions elliptic-curve/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
generic_array::typenum::U32,
ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign},
pkcs8,
point::{AffineXCoordinate, AffineYIsOdd},
point::AffineCoordinates,
rand_core::RngCore,
scalar::{FromUintUnchecked, IsHigh},
sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint},
Expand Down Expand Up @@ -415,15 +415,13 @@ pub enum AffinePoint {
Other(EncodedPoint),
}

impl AffineXCoordinate for AffinePoint {
impl AffineCoordinates for AffinePoint {
type FieldRepr = FieldBytes;

fn x(&self) -> FieldBytes {
unimplemented!();
}
}

impl AffineYIsOdd for AffinePoint {
fn y_is_odd(&self) -> Choice {
unimplemented!();
}
Expand Down
2 changes: 1 addition & 1 deletion elliptic-curve/src/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
//! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf

use crate::{
point::AffineXCoordinate, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar,
point::AffineCoordinates, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar,
ProjectivePoint, PublicKey,
};
use core::borrow::Borrow;
Expand Down
8 changes: 3 additions & 5 deletions elliptic-curve/src/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ pub type AffinePoint<C> = <C as CurveArithmetic>::AffinePoint;
#[cfg(feature = "arithmetic")]
pub type ProjectivePoint<C> = <C as CurveArithmetic>::ProjectivePoint;

/// Obtain the affine x-coordinate of an elliptic curve point.
pub trait AffineXCoordinate {
/// 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.
type FieldRepr: AsRef<[u8]>;

/// Get the affine x-coordinate as a serialized field element.
fn x(&self) -> Self::FieldRepr;
}

/// Is the affine y-coordinate of this elliptic curve point odd?
pub trait AffineYIsOdd {
/// Is the affine y-coordinate odd?
fn y_is_odd(&self) -> Choice;
}
Expand Down

0 comments on commit d69d5b9

Please sign in to comment.