Skip to content

Commit

Permalink
p256: consolidate ProjectivePoint impl blocks (#512)
Browse files Browse the repository at this point in the history
Moves the inherent method definitions to the same impl block as the one
that defines the `IDENTITY` and `GENERATOR` constants.
  • Loading branch information
tarcieri authored Jan 12, 2022
1 parent 2384c41 commit 5b25e50
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 115 deletions.
6 changes: 6 additions & 0 deletions k256/src/arithmetic/projective.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ impl From<ProjectivePoint> for AffinePoint {
}
}

impl From<&ProjectivePoint> for AffinePoint {
fn from(p: &ProjectivePoint) -> AffinePoint {
p.to_affine()
}
}

impl FromEncodedPoint<Secp256k1> for ProjectivePoint {
fn from_encoded_point(p: &EncodedPoint) -> CtOption<Self> {
AffinePoint::from_encoded_point(p).map(ProjectivePoint::from)
Expand Down
240 changes: 125 additions & 115 deletions p256/src/arithmetic/projective.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,122 +54,7 @@ impl ProjectivePoint {
y: AffinePoint::GENERATOR.y,
z: FieldElement::ONE,
};
}

impl Group for ProjectivePoint {
type Scalar = Scalar;

fn random(mut rng: impl RngCore) -> Self {
Self::GENERATOR * Scalar::random(&mut rng)
}

fn identity() -> Self {
Self::IDENTITY
}

fn generator() -> Self {
Self::GENERATOR
}

fn is_identity(&self) -> Choice {
self.ct_eq(&Self::IDENTITY)
}

#[must_use]
fn double(&self) -> Self {
ProjectivePoint::double(self)
}
}

impl GroupEncoding for ProjectivePoint {
type Repr = CompressedPoint;

fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
<AffinePoint as GroupEncoding>::from_bytes(bytes).map(Into::into)
}

fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
// No unchecked conversion possible for compressed points
Self::from_bytes(bytes)
}

fn to_bytes(&self) -> Self::Repr {
self.to_affine().to_bytes()
}
}

impl PrimeGroup for ProjectivePoint {}

impl Curve for ProjectivePoint {
type AffineRepr = AffinePoint;

fn to_affine(&self) -> AffinePoint {
ProjectivePoint::to_affine(self)
}
}

impl PrimeCurve for ProjectivePoint {
type Affine = AffinePoint;
}

impl LinearCombination for ProjectivePoint {}

impl From<AffinePoint> for ProjectivePoint {
fn from(p: AffinePoint) -> Self {
let projective = ProjectivePoint {
x: p.x,
y: p.y,
z: FieldElement::ONE,
};
Self::conditional_select(&projective, &Self::IDENTITY, p.is_identity())
}
}

impl From<ProjectivePoint> for AffinePoint {
fn from(p: ProjectivePoint) -> AffinePoint {
p.to_affine()
}
}

impl FromEncodedPoint<NistP256> for ProjectivePoint {
fn from_encoded_point(p: &EncodedPoint) -> CtOption<Self> {
AffinePoint::from_encoded_point(p).map(ProjectivePoint::from)
}
}

impl ToEncodedPoint<NistP256> for ProjectivePoint {
fn to_encoded_point(&self, compress: bool) -> EncodedPoint {
self.to_affine().to_encoded_point(compress)
}
}

impl ConditionallySelectable for ProjectivePoint {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
ProjectivePoint {
x: FieldElement::conditional_select(&a.x, &b.x, choice),
y: FieldElement::conditional_select(&a.y, &b.y, choice),
z: FieldElement::conditional_select(&a.z, &b.z, choice),
}
}
}

impl ConstantTimeEq for ProjectivePoint {
fn ct_eq(&self, other: &Self) -> Choice {
self.to_affine().ct_eq(&other.to_affine())
}
}

impl DefaultIsZeroes for ProjectivePoint {}

impl Eq for ProjectivePoint {}

impl PartialEq for ProjectivePoint {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
}
}

impl ProjectivePoint {
/// Returns the additive identity of P-256, also known as the "neutral element" or
/// "point at infinity".
#[deprecated(since = "0.10.1", note = "use `ProjectivePoint::IDENTITY` instead")]
Expand Down Expand Up @@ -322,6 +207,131 @@ impl ProjectivePoint {
}
}

impl Group for ProjectivePoint {
type Scalar = Scalar;

fn random(mut rng: impl RngCore) -> Self {
Self::GENERATOR * Scalar::random(&mut rng)
}

fn identity() -> Self {
Self::IDENTITY
}

fn generator() -> Self {
Self::GENERATOR
}

fn is_identity(&self) -> Choice {
self.ct_eq(&Self::IDENTITY)
}

#[must_use]
fn double(&self) -> Self {
ProjectivePoint::double(self)
}
}

impl GroupEncoding for ProjectivePoint {
type Repr = CompressedPoint;

fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
<AffinePoint as GroupEncoding>::from_bytes(bytes).map(Into::into)
}

fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
// No unchecked conversion possible for compressed points
Self::from_bytes(bytes)
}

fn to_bytes(&self) -> Self::Repr {
self.to_affine().to_bytes()
}
}

impl PrimeGroup for ProjectivePoint {}

impl Curve for ProjectivePoint {
type AffineRepr = AffinePoint;

fn to_affine(&self) -> AffinePoint {
ProjectivePoint::to_affine(self)
}
}

impl PrimeCurve for ProjectivePoint {
type Affine = AffinePoint;
}

impl LinearCombination for ProjectivePoint {}

impl From<AffinePoint> for ProjectivePoint {
fn from(p: AffinePoint) -> Self {
let projective = ProjectivePoint {
x: p.x,
y: p.y,
z: FieldElement::ONE,
};
Self::conditional_select(&projective, &Self::IDENTITY, p.is_identity())
}
}

impl From<&AffinePoint> for ProjectivePoint {
fn from(p: &AffinePoint) -> Self {
Self::from(*p)
}
}

impl From<ProjectivePoint> for AffinePoint {
fn from(p: ProjectivePoint) -> AffinePoint {
p.to_affine()
}
}

impl From<&ProjectivePoint> for AffinePoint {
fn from(p: &ProjectivePoint) -> AffinePoint {
p.to_affine()
}
}

impl FromEncodedPoint<NistP256> for ProjectivePoint {
fn from_encoded_point(p: &EncodedPoint) -> CtOption<Self> {
AffinePoint::from_encoded_point(p).map(ProjectivePoint::from)
}
}

impl ToEncodedPoint<NistP256> for ProjectivePoint {
fn to_encoded_point(&self, compress: bool) -> EncodedPoint {
self.to_affine().to_encoded_point(compress)
}
}

impl ConditionallySelectable for ProjectivePoint {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
ProjectivePoint {
x: FieldElement::conditional_select(&a.x, &b.x, choice),
y: FieldElement::conditional_select(&a.y, &b.y, choice),
z: FieldElement::conditional_select(&a.z, &b.z, choice),
}
}
}

impl ConstantTimeEq for ProjectivePoint {
fn ct_eq(&self, other: &Self) -> Choice {
self.to_affine().ct_eq(&other.to_affine())
}
}

impl DefaultIsZeroes for ProjectivePoint {}

impl Eq for ProjectivePoint {}

impl PartialEq for ProjectivePoint {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
}
}

impl Default for ProjectivePoint {
fn default() -> Self {
Self::IDENTITY
Expand Down

0 comments on commit 5b25e50

Please sign in to comment.