mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
This represents the first breaking change in a new release series, bumping all crates to the 2024 edition of Rust. As such, the version numbers of all crates have been incremented to represent a new prerelease series: - `curve25519-dalek`: v5.0.0-pre - `ed25519-dalek`: v3.0.0-pre - `x25519-dalek`: v3.0.0-pre Note that this commit isn't intended to cut associated crate releases of these on crates.io, but is merely bumping the version numbers to denote there are pending breaking changes. This commit also includes rustfmt changes which were made as part of the 2024 edition. Also includes clippy fixes.
114 lines
2.6 KiB
Rust
114 lines
2.6 KiB
Rust
use super::{CompressedEdwardsY, EdwardsPoint};
|
|
use crate::traits::Identity;
|
|
use crate::{Scalar, field::FieldElement};
|
|
use core::ops::Mul;
|
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
|
|
|
|
#[cfg(feature = "zeroize")]
|
|
use zeroize::DefaultIsZeroes;
|
|
|
|
/// Affine Edwards point on untwisted curve.
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub struct AffinePoint {
|
|
pub(super) x: FieldElement,
|
|
pub(super) y: FieldElement,
|
|
}
|
|
|
|
impl ConstantTimeEq for AffinePoint {
|
|
fn ct_eq(&self, other: &Self) -> Choice {
|
|
self.x.ct_eq(&other.x) & self.y.ct_eq(&other.y)
|
|
}
|
|
}
|
|
|
|
impl ConditionallySelectable for AffinePoint {
|
|
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
|
Self {
|
|
x: FieldElement::conditional_select(&a.x, &b.x, choice),
|
|
y: FieldElement::conditional_select(&a.y, &b.y, choice),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for AffinePoint {
|
|
fn default() -> AffinePoint {
|
|
AffinePoint::identity()
|
|
}
|
|
}
|
|
|
|
impl Identity for AffinePoint {
|
|
fn identity() -> AffinePoint {
|
|
AffinePoint {
|
|
x: FieldElement::ZERO,
|
|
y: FieldElement::ONE,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PartialEq for AffinePoint {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.ct_eq(other).into()
|
|
}
|
|
}
|
|
|
|
impl Eq for AffinePoint {}
|
|
|
|
#[cfg(feature = "zeroize")]
|
|
impl DefaultIsZeroes for AffinePoint {}
|
|
|
|
impl AffinePoint {
|
|
/// Convert to extended coordinates.
|
|
pub fn to_edwards(self) -> EdwardsPoint {
|
|
EdwardsPoint {
|
|
X: self.x,
|
|
Y: self.y,
|
|
Z: FieldElement::ONE,
|
|
T: &self.x * &self.y,
|
|
}
|
|
}
|
|
|
|
/// Compress affine Edwards coordinates into `CompressedEdwardsY` format.
|
|
#[inline]
|
|
pub fn compress(self) -> CompressedEdwardsY {
|
|
let mut s = self.y.to_bytes();
|
|
s[31] ^= self.x.is_negative().unwrap_u8() << 7;
|
|
CompressedEdwardsY(s)
|
|
}
|
|
}
|
|
|
|
impl Mul<AffinePoint> for Scalar {
|
|
type Output = EdwardsPoint;
|
|
|
|
#[inline]
|
|
fn mul(self, rhs: AffinePoint) -> EdwardsPoint {
|
|
self * &rhs
|
|
}
|
|
}
|
|
|
|
impl Mul<&AffinePoint> for Scalar {
|
|
type Output = EdwardsPoint;
|
|
|
|
#[inline]
|
|
fn mul(self, rhs: &AffinePoint) -> EdwardsPoint {
|
|
rhs.to_edwards() * self
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{AffinePoint, EdwardsPoint, Identity};
|
|
use crate::constants;
|
|
|
|
#[test]
|
|
fn identity_conversion() {
|
|
assert_eq!(
|
|
AffinePoint::identity().to_edwards(),
|
|
EdwardsPoint::identity()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn generator_round_trip() {
|
|
let basepoint = constants::ED25519_BASEPOINT_POINT;
|
|
assert_eq!(basepoint.to_affine().to_edwards(), basepoint);
|
|
}
|
|
}
|