Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4af7c38
implement KeyInit for SigningKey
carloskiki Mar 3, 2025
878ade7
move behind "digest" feature
carloskiki Mar 5, 2025
1a6ea17
implement KeySizeUser for VerifyingKey
carloskiki Mar 5, 2025
0fcca09
move imports behind "digest" feature
carloskiki Mar 9, 2025
8898298
update "digest" feature description
carloskiki Mar 9, 2025
3d36f72
fix import statements
carloskiki Mar 24, 2025
0f8392f
first batch of trait implementations
carloskiki Apr 27, 2025
a4c10d8
fix: FieldElement trait for CurveArithmetic
carloskiki Apr 27, 2025
c0a313b
remove unecessary digest requirements
carloskiki Apr 27, 2025
8cf3f00
impl ShrAssign for Scalar
carloskiki Apr 27, 2025
f5365ed
impl Reduce for Scalar
carloskiki Apr 27, 2025
9579a5b
impl Ord for Scalar
carloskiki Apr 27, 2025
15a8763
impl IsHigh for Scalar
carloskiki Apr 27, 2025
3b72a93
implement trivial AsRef for Scalar
carloskiki Apr 27, 2025
9dbf077
implementation typechecks
carloskiki Apr 27, 2025
0841636
complete implementations
carloskiki Apr 27, 2025
72ba9e7
fix: things not being behind feature flag
carloskiki Apr 27, 2025
49f41fa
remove comment
carloskiki Apr 27, 2025
a3c3f52
fix: clippy lints
carloskiki Apr 27, 2025
d82f71e
fix comment wording
carloskiki Apr 27, 2025
5d8774f
standardize Zeroize impls
carloskiki Apr 27, 2025
6d6a91c
fix: comment wording
carloskiki Apr 27, 2025
aa1bdba
fix: test compilation
carloskiki Apr 27, 2025
4cb744f
clean comment
carloskiki Jun 8, 2025
bff18e4
add `EdwardsAffinePoint` for `elliptic-curve` trait implementations
carloskiki Jun 8, 2025
51c523b
Merge branch 'main' of https://github.com/dalek-cryptography/curve255…
carloskiki Jun 8, 2025
48962e7
Revert "add `EdwardsAffinePoint` for `elliptic-curve` trait implement…
carloskiki Jun 8, 2025
a2082d8
Merge branch 'main' into elliptic-curve
carloskiki Jun 8, 2025
7805902
fixup implementation with new affine point
carloskiki Jun 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion curve25519-dalek/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ digest = { version = "0.10", default-features = false, optional = true }
subtle = { version = "2.6.0", default-features = false, features = ["const-generics"]}
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
zeroize = { version = "1", default-features = false, optional = true }
elliptic-curve = { version = "0.13", optional = true }

[target.'cfg(target_arch = "x86_64")'.dependencies]
cpufeatures = "0.2.17"
Expand All @@ -66,8 +67,9 @@ default = ["alloc", "precomputed-tables", "zeroize"]
alloc = ["zeroize?/alloc"]
precomputed-tables = []
legacy_compatibility = []
group = ["dep:group", "rand_core"]
group = ["dep:group", "rand_core", "digest"]
group-bits = ["group", "ff/bits"]
elliptic-curve = ["group", "dep:ff", "dep:elliptic-curve"]

[target.'cfg(all(not(curve25519_dalek_backend = "fiat"), not(curve25519_dalek_backend = "serial"), target_arch = "x86_64"))'.dependencies]
curve25519-dalek-derive = { version = "0.1", path = "../curve25519-dalek-derive" }
Expand Down
25 changes: 25 additions & 0 deletions curve25519-dalek/src/ed25519.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use elliptic_curve::{bigint::U256, consts::U32, Curve, CurveArithmetic, FieldBytesEncoding};

use crate::{constants::BASEPOINT_ORDER_PRIVATE, edwards::affine::AffinePoint, EdwardsPoint, Scalar};

/// QUESTION: I don't know where to put this singleton. Maybe in the crate's root?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably put it in edwards.rs

#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Ed25519;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ed25519 is the name of the EdDSA variant.

RFC7748 calls the Edwards form of the curve "edwards25519"


impl Curve for Ed25519 {
type FieldBytesSize = U32;

type Uint = U256;

const ORDER: Self::Uint = U256::from_le_slice(&BASEPOINT_ORDER_PRIVATE.bytes);
}

impl CurveArithmetic for Ed25519 {
type AffinePoint = AffinePoint;

type ProjectivePoint = EdwardsPoint;

type Scalar = Scalar;
}

impl FieldBytesEncoding<Ed25519> for U256 {}
141 changes: 113 additions & 28 deletions curve25519-dalek/src/edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
// affine and projective cakes and eat both of them too.
#![allow(non_snake_case)]

mod affine;
pub(crate) mod affine;

use cfg_if::cfg_if;
use core::array::TryFromSliceError;
Expand All @@ -105,7 +105,7 @@ use core::ops::{AddAssign, SubAssign};
use core::ops::{Mul, MulAssign};

#[cfg(feature = "digest")]
use digest::{generic_array::typenum::U64, Digest};
use digest::{generic_array::typenum::{U64, U32}, Digest};

#[cfg(feature = "group")]
use {
Expand All @@ -122,7 +122,7 @@ use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use zeroize::DefaultIsZeroes;

use crate::constants;

Expand Down Expand Up @@ -433,24 +433,10 @@ impl Default for EdwardsPoint {
// ------------------------------------------------------------------------

#[cfg(feature = "zeroize")]
impl Zeroize for CompressedEdwardsY {
/// Reset this `CompressedEdwardsY` to the compressed form of the identity element.
fn zeroize(&mut self) {
self.0.zeroize();
self.0[0] = 1;
}
}
impl DefaultIsZeroes for CompressedEdwardsY {}

#[cfg(feature = "zeroize")]
impl Zeroize for EdwardsPoint {
/// Reset this `EdwardsPoint` to the identity element.
fn zeroize(&mut self) {
self.X.zeroize();
self.Y = FieldElement::ONE;
self.Z = FieldElement::ONE;
self.T.zeroize();
}
}
impl DefaultIsZeroes for EdwardsPoint {}

// ------------------------------------------------------------------------
// Validity checks (for debugging, not CT)
Expand Down Expand Up @@ -859,6 +845,24 @@ impl EdwardsPoint {
}
}

// ------------------------------------------------------------------------
// Elliptic curve traits
// ------------------------------------------------------------------------

#[cfg(feature = "elliptic-curve")]
impl elliptic_curve::ops::LinearCombination for EdwardsPoint {
fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
EdwardsPoint::multiscalar_mul([k, l], [x, y])
}
}
#[cfg(feature = "elliptic-curve")]
impl elliptic_curve::ops::MulByGenerator for EdwardsPoint {
fn mul_by_generator(scalar: &Self::Scalar) -> Self {
Self::mul_base(scalar)
}
}


// ------------------------------------------------------------------------
// Multiscalar Multiplication impls
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -1358,6 +1362,15 @@ impl Debug for EdwardsPoint {
// group traits
// ------------------------------------------------------------------------

#[cfg(feature = "group")]
impl group::Curve for EdwardsPoint {
type AffineRepr = AffinePoint;

fn to_affine(&self) -> Self::AffineRepr {
EdwardsPoint::to_affine(*self)
}
}

// Use the full trait path to avoid Group::identity overlapping Identity::identity in the
// rest of the module (e.g. tests).
#[cfg(feature = "group")]
Expand Down Expand Up @@ -1388,10 +1401,10 @@ impl group::Group for EdwardsPoint {

#[cfg(feature = "group")]
impl GroupEncoding for EdwardsPoint {
type Repr = [u8; 32];
type Repr = digest::generic_array::GenericArray<u8, U32>;

fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
let repr = CompressedEdwardsY(*bytes);
let repr = CompressedEdwardsY(<[u8; 32]>::from(*bytes));
let (is_valid_y_coord, X, Y, Z) = decompress::step_1(&repr);
CtOption::new(decompress::step_2(&repr, X, Y, Z), is_valid_y_coord)
}
Expand All @@ -1402,7 +1415,7 @@ impl GroupEncoding for EdwardsPoint {
}

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

Expand Down Expand Up @@ -1599,11 +1612,7 @@ impl ConditionallySelectable for SubgroupPoint {
}

#[cfg(all(feature = "group", feature = "zeroize"))]
impl Zeroize for SubgroupPoint {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl DefaultIsZeroes for SubgroupPoint {}

#[cfg(feature = "group")]
impl group::Group for SubgroupPoint {
Expand Down Expand Up @@ -1655,7 +1664,7 @@ impl GroupEncoding for SubgroupPoint {
}

fn to_bytes(&self) -> Self::Repr {
self.0.compress().to_bytes()
self.0.compress().to_bytes().into()
}
}

Expand All @@ -1680,6 +1689,82 @@ impl CofactorGroup for EdwardsPoint {
}
}

// ------------------------------------------------------------------------
// Interop between CompressedEdwardsY and EdwardsPoint for group traits
// ------------------------------------------------------------------------

// Again, we assume throughout that CompressedEdwardsY is a valid point (this is not what we
// want, just something that somewhat works until we know what to do).

impl From<AffinePoint> for EdwardsPoint {
fn from(value: AffinePoint) -> Self {
value.to_edwards()
}
}

impl From<&AffinePoint> for EdwardsPoint {
fn from(value: &AffinePoint) -> Self {
value.to_edwards()
}
}


impl From<EdwardsPoint> for AffinePoint {
fn from(value: EdwardsPoint) -> Self {
value.to_affine()
}
}

impl From<&EdwardsPoint> for AffinePoint {
fn from(value: &EdwardsPoint) -> Self {
value.to_affine()
}
}

impl Add<&AffinePoint> for &EdwardsPoint {
type Output = EdwardsPoint;

fn add(self, other: &AffinePoint) -> EdwardsPoint {
self + EdwardsPoint::from(other)
}
}

define_add_variants!(
LHS = EdwardsPoint,
RHS = AffinePoint,
Output = EdwardsPoint
);

impl AddAssign<&AffinePoint> for EdwardsPoint {
fn add_assign(&mut self, rhs: &AffinePoint) {
*self += EdwardsPoint::from(rhs);
}
}

define_add_assign_variants!(LHS = EdwardsPoint, RHS = AffinePoint);

impl Sub<&AffinePoint> for &EdwardsPoint {
type Output = EdwardsPoint;

fn sub(self, other: &AffinePoint) -> EdwardsPoint {
self - EdwardsPoint::from(other)
}
}

define_sub_variants!(
LHS = EdwardsPoint,
RHS = AffinePoint,
Output = EdwardsPoint
);

impl SubAssign<&AffinePoint> for EdwardsPoint {
fn sub_assign(&mut self, rhs: &AffinePoint) {
*self -= EdwardsPoint::from(rhs);
}
}

define_sub_assign_variants!(LHS = EdwardsPoint, RHS = AffinePoint);

// ------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions curve25519-dalek/src/edwards/affine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ impl Mul<&AffinePoint> for Scalar {
}
}

#[cfg(feature = "elliptic-curve")]
impl elliptic_curve::point::AffineCoordinates for AffinePoint {
type FieldRepr = digest::generic_array::GenericArray<u8, digest::consts::U32>;

fn x(&self) -> Self::FieldRepr {
self.x.to_bytes().into()
}

fn y_is_odd(&self) -> Choice {
Choice::from(self.y.to_bytes()[0] & 1)
}
}

#[cfg(test)]
mod tests {
use super::{AffinePoint, EdwardsPoint, Identity};
Expand Down
3 changes: 3 additions & 0 deletions curve25519-dalek/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,6 @@ pub use crate::{
// Build time diagnostics for validation
#[cfg(curve25519_dalek_diagnostics = "build")]
mod diagnostics;

#[cfg(feature = "elliptic-curve")]
mod ed25519;
Loading