Skip to content

Commit 85c484f

Browse files
committed
Introduce CurveAffine trait
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.
1 parent 090a7ec commit 85c484f

File tree

5 files changed

+73
-97
lines changed

5 files changed

+73
-97
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ and this library adheres to Rust's notion of
66
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Added
10+
- `group::CurveAffine`
11+
12+
### Changed
13+
- The curve-related traits have been refactored around the new `CurveAffine`
14+
trait:
15+
- `group::Curve::AffineRepr` has been renamed to `Curve::Affine`.
16+
- All of the trait methods and associated types on the following traits have
17+
been removed (use `group::Curve::Affine` or the `group::CurveAffine` trait
18+
instead; trait implementors must implement `group::CurveAffine` instead
19+
using the same logic):
20+
- `group::cofactor::CofactorCurve`
21+
- `group::cofactor::CofactorCurveAffine`
22+
- `group::prime::PrimeCurve`
23+
- `group::prime::PrimeCurveAffine`
24+
- `group::cofactor::CofactorCurveAffine` and `group::prime::PrimeCurveAffine`
25+
now have blanket implementations for all types `C: group::CurveAffine` where
26+
`C::Curve` implements `CofactorCurve` or `PrimeCurve` respectively.
927

1028
## [0.13.0] - 2022-12-06
1129
### Changed

src/cofactor.rs

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use core::fmt;
2-
use core::ops::{Mul, Neg};
3-
use ff::PrimeField;
41
use subtle::{Choice, CtOption};
52

6-
use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned};
3+
use crate::{prime::PrimeGroup, Curve, CurveAffine, Group, GroupEncoding, GroupOps, GroupOpsOwned};
74

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

5552
/// Efficient representation of an elliptic curve point guaranteed to be
5653
/// in the correct prime order subgroup.
57-
pub trait CofactorCurve:
58-
Curve<AffineRepr = <Self as CofactorCurve>::Affine> + CofactorGroup
59-
{
60-
type Affine: CofactorCurveAffine<Curve = Self, Scalar = Self::Scalar>
61-
+ Mul<Self::Scalar, Output = Self>
62-
+ for<'r> Mul<&'r Self::Scalar, Output = Self>;
63-
}
54+
pub trait CofactorCurve: Curve + CofactorGroup {}
6455

6556
/// Affine representation of an elliptic curve point guaranteed to be
6657
/// in the correct prime order subgroup.
67-
pub trait CofactorCurveAffine:
68-
GroupEncoding
69-
+ Copy
70-
+ Clone
71-
+ Sized
72-
+ Send
73-
+ Sync
74-
+ fmt::Debug
75-
+ PartialEq
76-
+ Eq
77-
+ 'static
78-
+ Neg<Output = Self>
79-
+ Mul<<Self as CofactorCurveAffine>::Scalar, Output = <Self as CofactorCurveAffine>::Curve>
80-
+ for<'r> Mul<
81-
&'r <Self as CofactorCurveAffine>::Scalar,
82-
Output = <Self as CofactorCurveAffine>::Curve,
83-
>
84-
{
85-
type Scalar: PrimeField;
86-
type Curve: CofactorCurve<Affine = Self, Scalar = Self::Scalar>;
87-
88-
/// Returns the additive identity.
89-
fn identity() -> Self;
58+
pub trait CofactorCurveAffine: CurveAffine {}
9059

91-
/// Returns a fixed generator of unknown exponent.
92-
fn generator() -> Self;
93-
94-
/// Determines if this point represents the point at infinity; the
95-
/// additive identity.
96-
fn is_identity(&self) -> Choice;
97-
98-
/// Converts this element to its curve representation.
99-
fn to_curve(&self) -> Self::Curve;
100-
}
60+
impl<C: CurveAffine> CofactorCurveAffine for C where C::Curve: CofactorCurve {}

src/lib.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ pub trait Group:
9292
fn double(&self) -> Self;
9393
}
9494

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

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

107107
for (p, q) in p.iter().zip(q.iter_mut()) {
@@ -110,7 +110,45 @@ pub trait Curve:
110110
}
111111

112112
/// Converts this element into its affine representation.
113-
fn to_affine(&self) -> Self::AffineRepr;
113+
fn to_affine(&self) -> Self::Affine;
114+
}
115+
116+
/// Affine representation of an elliptic curve point.
117+
pub trait CurveAffine:
118+
GroupEncoding
119+
+ Copy
120+
+ Clone
121+
+ Sized
122+
+ Send
123+
+ Sync
124+
+ fmt::Debug
125+
+ PartialEq
126+
+ Eq
127+
+ 'static
128+
+ Neg<Output = Self>
129+
+ Mul<<Self::Curve as Group>::Scalar, Output = Self::Curve>
130+
+ for<'r> Mul<&'r <Self::Curve as Group>::Scalar, Output = Self::Curve>
131+
{
132+
/// The efficient representation for this elliptic curve.
133+
type Curve: Curve<Affine = Self, Scalar = Self::Scalar>;
134+
135+
/// Scalars modulo the order of this group's scalar field.
136+
///
137+
/// This associated type is temporary, and will be removed once downstream users have
138+
/// migrated to using `Curve` as the primary generic bound.
139+
type Scalar: PrimeField;
140+
141+
/// Returns the additive identity.
142+
fn identity() -> Self;
143+
144+
/// Returns a fixed generator of unknown exponent.
145+
fn generator() -> Self;
146+
147+
/// Determines if this point represents the additive identity.
148+
fn is_identity(&self) -> Choice;
149+
150+
/// Converts this affine point to its efficient representation.
151+
fn to_curve(&self) -> Self::Curve;
114152
}
115153

116154
pub trait GroupEncoding: Sized {

src/prime.rs

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,14 @@
1-
use core::fmt;
2-
use core::ops::{Mul, Neg};
3-
use ff::PrimeField;
4-
use subtle::Choice;
5-
6-
use crate::{Curve, Group, GroupEncoding};
1+
use crate::{Curve, CurveAffine, Group, GroupEncoding};
72

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

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

1910
/// Affine representation of an elliptic curve point guaranteed to be
2011
/// in the correct prime order subgroup.
21-
pub trait PrimeCurveAffine: GroupEncoding
22-
+ Copy
23-
+ Clone
24-
+ Sized
25-
+ Send
26-
+ Sync
27-
+ fmt::Debug
28-
+ PartialEq
29-
+ Eq
30-
+ 'static
31-
+ Neg<Output = Self>
32-
+ Mul<<Self as PrimeCurveAffine>::Scalar, Output = <Self as PrimeCurveAffine>::Curve>
33-
+ for<'r> Mul<&'r <Self as PrimeCurveAffine>::Scalar, Output = <Self as PrimeCurveAffine>::Curve>
34-
{
35-
type Scalar: PrimeField;
36-
type Curve: PrimeCurve<Affine = Self, Scalar = Self::Scalar>;
37-
38-
/// Returns the additive identity.
39-
fn identity() -> Self;
40-
41-
/// Returns a fixed generator of unknown exponent.
42-
fn generator() -> Self;
43-
44-
/// Determines if this point represents the point at infinity; the
45-
/// additive identity.
46-
fn is_identity(&self) -> Choice;
12+
pub trait PrimeCurveAffine: CurveAffine {}
4713

48-
/// Converts this element to its curve representation.
49-
fn to_curve(&self) -> Self::Curve;
50-
}
14+
impl<C: CurveAffine> PrimeCurveAffine for C where C::Curve: PrimeCurve {}

src/tests/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ use ff::{Field, PrimeField};
44
use rand::SeedableRng;
55
use rand_xorshift::XorShiftRng;
66

7-
use crate::{
8-
prime::{PrimeCurve, PrimeCurveAffine},
9-
wnaf::WnafGroup,
10-
GroupEncoding, UncompressedEncoding,
11-
};
7+
use crate::{prime::PrimeCurve, wnaf::WnafGroup, CurveAffine, GroupEncoding, UncompressedEncoding};
128

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

427423
pub fn random_uncompressed_encoding_tests<G: PrimeCurve>()
428424
where
429-
<G as PrimeCurve>::Affine: UncompressedEncoding,
425+
G::Affine: UncompressedEncoding,
430426
{
431427
let mut rng = XorShiftRng::from_seed([
432428
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,

0 commit comments

Comments
 (0)