Skip to content

Commit

Permalink
Introduce CurveAffine trait
Browse files Browse the repository at this point in the history
This unifies the methods previously exposed by the `PrimeCurveAffine`
and `CofactorCurveAffine` traits. The prime-order and cofactor traits
are now all marker traits, and their affine-specific traits are
automatically derived.
  • Loading branch information
str4d committed Jul 30, 2023
1 parent 090a7ec commit 696c212
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 97 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `group::CurveAffine`

### Changed
- The curve-related traits have been refactored around the new `CurveAffine`
trait:
- `group::Curve::AffineRepr` has been renamed to `Curve::Affine`.
- All of the trait methods and associated types on the following traits have
been removed (use `group::Curve::Affine` or the `group::CurveAffine` trait
instead; trait implementors must implement `group::CurveAffine` instead
using the same logic):
- `group::cofactor::CofactorCurve`
- `group::cofactor::CofactorCurveAffine`
- `group::prime::PrimeCurve`
- `group::prime::PrimeCurveAffine`
- `group::cofactor::CofactorCurveAffine` and `group::prime::PrimeCurveAffine`
now have blanket implementations for all types `C: group::CurveAffine` where
`C::Curve` implements `CofactorCurve` or `PrimeCurve` respectively.

## [0.13.0] - 2022-12-06
### Changed
Expand Down
48 changes: 4 additions & 44 deletions src/cofactor.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use core::fmt;
use core::ops::{Mul, Neg};
use ff::PrimeField;
use subtle::{Choice, CtOption};

use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned};
use crate::{prime::PrimeGroup, Curve, CurveAffine, Group, GroupEncoding, GroupOps, GroupOpsOwned};

/// This trait represents an element of a cryptographic group with a large prime-order
/// subgroup and a comparatively-small cofactor.
Expand Down Expand Up @@ -54,47 +51,10 @@ pub trait CofactorGroup:

/// Efficient representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CofactorCurve:
Curve<AffineRepr = <Self as CofactorCurve>::Affine> + CofactorGroup
{
type Affine: CofactorCurveAffine<Curve = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<&'r Self::Scalar, Output = Self>;
}
pub trait CofactorCurve: Curve + CofactorGroup {}

/// Affine representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CofactorCurveAffine:
GroupEncoding
+ Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ PartialEq
+ Eq
+ 'static
+ Neg<Output = Self>
+ Mul<<Self as CofactorCurveAffine>::Scalar, Output = <Self as CofactorCurveAffine>::Curve>
+ for<'r> Mul<
&'r <Self as CofactorCurveAffine>::Scalar,
Output = <Self as CofactorCurveAffine>::Curve,
>
{
type Scalar: PrimeField;
type Curve: CofactorCurve<Affine = Self, Scalar = Self::Scalar>;

/// Returns the additive identity.
fn identity() -> Self;
pub trait CofactorCurveAffine: CurveAffine {}

/// Returns a fixed generator of unknown exponent.
fn generator() -> Self;

/// Determines if this point represents the point at infinity; the
/// additive identity.
fn is_identity(&self) -> Choice;

/// Converts this element to its curve representation.
fn to_curve(&self) -> Self::Curve;
}
impl<C: CurveAffine> CofactorCurveAffine for C where C::Curve: CofactorCurve {}
49 changes: 42 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,16 @@ pub trait Group:
fn double(&self) -> Self;
}

/// Efficient representation of an elliptic curve point guaranteed.
pub trait Curve:
Group + GroupOps<<Self as Curve>::AffineRepr> + GroupOpsOwned<<Self as Curve>::AffineRepr>
{
/// Efficient representation of an elliptic curve point.
pub trait Curve: Group + GroupOps<Self::Affine> + GroupOpsOwned<Self::Affine> {
/// The affine representation for this elliptic curve.
type AffineRepr;
type Affine: CurveAffine<Curve = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<&'r Self::Scalar, Output = Self>;

/// Converts a batch of projective elements into affine elements. This function will
/// panic if `p.len() != q.len()`.
fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
fn batch_normalize(p: &[Self], q: &mut [Self::Affine]) {
assert_eq!(p.len(), q.len());

for (p, q) in p.iter().zip(q.iter_mut()) {
Expand All @@ -110,7 +110,42 @@ pub trait Curve:
}

/// Converts this element into its affine representation.
fn to_affine(&self) -> Self::AffineRepr;
fn to_affine(&self) -> Self::Affine;
}

/// Affine representation of an elliptic curve point.
pub trait CurveAffine:
GroupEncoding
+ Copy
+ fmt::Debug
+ Eq
+ Send
+ Sync
+ 'static
+ Neg<Output = Self>
+ Mul<<Self::Curve as Group>::Scalar, Output = Self::Curve>
+ for<'r> Mul<&'r <Self::Curve as Group>::Scalar, Output = Self::Curve>
{
/// The efficient representation for this elliptic curve.
type Curve: Curve<Affine = Self, Scalar = Self::Scalar>;

/// Scalars modulo the order of this group's scalar field.
///
/// This associated type is temporary, and will be removed once downstream users have
/// migrated to using `Curve` as the primary generic bound.
type Scalar: PrimeField;

/// Returns the additive identity.
fn identity() -> Self;

/// Returns a fixed generator of unknown exponent.
fn generator() -> Self;

/// Determines if this point represents the additive identity.
fn is_identity(&self) -> Choice;

/// Converts this affine point to its efficient representation.
fn to_curve(&self) -> Self::Curve;
}

pub trait GroupEncoding: Sized {
Expand Down
44 changes: 4 additions & 40 deletions src/prime.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,14 @@
use core::fmt;
use core::ops::{Mul, Neg};
use ff::PrimeField;
use subtle::Choice;

use crate::{Curve, Group, GroupEncoding};
use crate::{Curve, CurveAffine, Group, GroupEncoding};

/// This trait represents an element of a prime-order cryptographic group.
pub trait PrimeGroup: Group + GroupEncoding {}

/// Efficient representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait PrimeCurve: Curve<AffineRepr = <Self as PrimeCurve>::Affine> + PrimeGroup {
type Affine: PrimeCurveAffine<Curve = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<&'r Self::Scalar, Output = Self>;
}
pub trait PrimeCurve: Curve + PrimeGroup {}

/// Affine representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait PrimeCurveAffine: GroupEncoding
+ Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ PartialEq
+ Eq
+ 'static
+ Neg<Output = Self>
+ Mul<<Self as PrimeCurveAffine>::Scalar, Output = <Self as PrimeCurveAffine>::Curve>
+ for<'r> Mul<&'r <Self as PrimeCurveAffine>::Scalar, Output = <Self as PrimeCurveAffine>::Curve>
{
type Scalar: PrimeField;
type Curve: PrimeCurve<Affine = Self, Scalar = Self::Scalar>;

/// Returns the additive identity.
fn identity() -> Self;

/// Returns a fixed generator of unknown exponent.
fn generator() -> Self;

/// Determines if this point represents the point at infinity; the
/// additive identity.
fn is_identity(&self) -> Choice;
pub trait PrimeCurveAffine: CurveAffine {}

/// Converts this element to its curve representation.
fn to_curve(&self) -> Self::Curve;
}
impl<C: CurveAffine> PrimeCurveAffine for C where C::Curve: PrimeCurve {}
8 changes: 2 additions & 6 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ use ff::{Field, PrimeField};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;

use crate::{
prime::{PrimeCurve, PrimeCurveAffine},
wnaf::WnafGroup,
GroupEncoding, UncompressedEncoding,
};
use crate::{prime::PrimeCurve, wnaf::WnafGroup, CurveAffine, GroupEncoding, UncompressedEncoding};

pub fn curve_tests<G: PrimeCurve>() {
let mut rng = XorShiftRng::from_seed([
Expand Down Expand Up @@ -426,7 +422,7 @@ fn random_compressed_encoding_tests<G: PrimeCurve>() {

pub fn random_uncompressed_encoding_tests<G: PrimeCurve>()
where
<G as PrimeCurve>::Affine: UncompressedEncoding,
G::Affine: UncompressedEncoding,
{
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
Expand Down

0 comments on commit 696c212

Please sign in to comment.