Skip to content

Commit 7bd2571

Browse files
committed
Implement CurveArithmetic for Curve448
1 parent 8c6327a commit 7bd2571

File tree

6 files changed

+300
-23
lines changed

6 files changed

+300
-23
lines changed

ed448-goldilocks/src/field/element.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
33

44
use super::ConstMontyType;
55
use crate::{
6-
AffinePoint, Decaf448, DecafPoint, Ed448, EdwardsPoint, MontgomeryPoint,
6+
AffinePoint, Decaf448, DecafPoint, Ed448, EdwardsPoint, MontgomeryPoint, ORDER,
77
curve::twedwards::extended::ExtendedPoint as TwistedExtendedPoint,
88
};
99
use elliptic_curve::{
@@ -16,7 +16,10 @@ use elliptic_curve::{
1616
zeroize::DefaultIsZeroes,
1717
};
1818
use hash2curve::{FromOkm, MapToCurve};
19-
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};
19+
use subtle::{
20+
Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess,
21+
CtOption,
22+
};
2023

2124
#[derive(Clone, Copy, Default)]
2225
pub struct FieldElement(pub(crate) ConstMontyType);
@@ -316,6 +319,12 @@ impl FieldElement {
316319
Self(ConstMontyType::new(&U448::from_le_slice(bytes)))
317320
}
318321

322+
pub fn from_repr(bytes: &[u8; 56]) -> CtOption<Self> {
323+
let integer = U448::from_le_slice(bytes);
324+
let is_some = integer.ct_lt(&ORDER);
325+
CtOption::new(Self(ConstMontyType::from_montgomery(integer)), is_some)
326+
}
327+
319328
pub fn double(&self) -> Self {
320329
Self(self.0.double())
321330
}

ed448-goldilocks/src/lib.rs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub use montgomery::{
6868
pub use sign::*;
6969

7070
use elliptic_curve::{
71-
Curve, FieldBytesEncoding, PrimeCurve,
71+
Curve, CurveArithmetic, FieldBytes, FieldBytesEncoding, NonZeroScalar, PrimeCurve,
7272
array::typenum::{U28, U56, U57},
7373
bigint::{ArrayEncoding, U448},
7474
point::PointCompression,
@@ -80,14 +80,14 @@ use hash2curve::GroupDigest;
8080
pub struct Ed448;
8181

8282
/// Bytes of the Ed448 field
83-
pub type Ed448FieldBytes = elliptic_curve::FieldBytes<Ed448>;
83+
pub type Ed448FieldBytes = FieldBytes<Ed448>;
8484

8585
/// Scalar bits of the Ed448 scalar
8686
#[cfg(feature = "bits")]
8787
pub type Ed448ScalarBits = elliptic_curve::scalar::ScalarBits<Ed448>;
8888

8989
/// Non-zero scalar of the Ed448 scalar
90-
pub type Ed448NonZeroScalar = elliptic_curve::NonZeroScalar<Ed448>;
90+
pub type Ed448NonZeroScalar = NonZeroScalar<Ed448>;
9191

9292
impl Curve for Ed448 {
9393
type FieldBytesSize = U57;
@@ -114,7 +114,7 @@ impl FieldBytesEncoding<Ed448> for U448 {
114114
}
115115
}
116116

117-
impl elliptic_curve::CurveArithmetic for Ed448 {
117+
impl CurveArithmetic for Ed448 {
118118
type AffinePoint = AffinePoint;
119119
type ProjectivePoint = EdwardsPoint;
120120
type Scalar = EdwardsScalar;
@@ -129,14 +129,14 @@ impl GroupDigest for Ed448 {
129129
pub struct Decaf448;
130130

131131
/// Bytes of the Decaf448 field
132-
pub type Decaf448FieldBytes = elliptic_curve::FieldBytes<Decaf448>;
132+
pub type Decaf448FieldBytes = FieldBytes<Decaf448>;
133133

134134
/// Scalar bits of the Decaf448 scalar
135135
#[cfg(feature = "bits")]
136136
pub type Decaf448ScalarBits = elliptic_curve::scalar::ScalarBits<Decaf448>;
137137

138138
/// Non-zero scalar of the Decaf448 scalar
139-
pub type Decaf448NonZeroScalar = elliptic_curve::NonZeroScalar<Decaf448>;
139+
pub type Decaf448NonZeroScalar = NonZeroScalar<Decaf448>;
140140

141141
impl Curve for Decaf448 {
142142
type FieldBytesSize = U56;
@@ -163,7 +163,7 @@ impl FieldBytesEncoding<Decaf448> for U448 {
163163
}
164164
}
165165

166-
impl elliptic_curve::CurveArithmetic for Decaf448 {
166+
impl CurveArithmetic for Decaf448 {
167167
type AffinePoint = DecafAffinePoint;
168168
type ProjectivePoint = DecafPoint;
169169
type Scalar = DecafScalar;
@@ -176,3 +176,44 @@ impl GroupDigest for Decaf448 {
176176
/// Curve448 curve.
177177
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
178178
pub struct Curve448;
179+
180+
/// Bytes of the Curve448 field
181+
pub type Curve448FieldBytes = FieldBytes<Curve448>;
182+
183+
/// Scalar bits of the Curve448 scalar
184+
#[cfg(feature = "bits")]
185+
pub type Curve448ScalarBits = elliptic_curve::scalar::ScalarBits<Curve448>;
186+
187+
/// Non-zero scalar of the Curve448 scalar
188+
pub type Curve448NonZeroScalar = NonZeroScalar<Curve448>;
189+
190+
impl Curve for Curve448 {
191+
type FieldBytesSize = U56;
192+
type Uint = U448;
193+
194+
const ORDER: U448 = ORDER;
195+
}
196+
197+
impl PrimeCurve for Curve448 {}
198+
199+
impl PointCompression for Curve448 {
200+
const COMPRESS_POINTS: bool = true;
201+
}
202+
203+
impl FieldBytesEncoding<Curve448> for U448 {
204+
fn decode_field_bytes(field_bytes: &Curve448FieldBytes) -> Self {
205+
U448::from_le_slice(field_bytes)
206+
}
207+
208+
fn encode_field_bytes(&self) -> Curve448FieldBytes {
209+
let mut data = Curve448FieldBytes::default();
210+
data.copy_from_slice(&self.to_le_byte_array()[..]);
211+
data
212+
}
213+
}
214+
215+
impl CurveArithmetic for Curve448 {
216+
type AffinePoint = MontgomeryPoint;
217+
type ProjectivePoint = ProjectiveMontgomeryPoint;
218+
type Scalar = MontgomeryScalar;
219+
}

ed448-goldilocks/src/montgomery/ops.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::field::{ConstMontyType, FieldElement};
33
use core::borrow::Borrow;
44
use core::iter::Sum;
55
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
6+
use elliptic_curve::CurveGroup;
67
use elliptic_curve::bigint::U448;
78

89
use super::{MontgomeryPoint, MontgomeryScalar, MontgomeryXpoint, ProjectiveMontgomeryPoint};
@@ -141,7 +142,7 @@ impl Mul<&MontgomeryScalar> for &ProjectiveMontgomeryPoint {
141142

142143
#[inline]
143144
fn mul(self, scalar: &MontgomeryScalar) -> ProjectiveMontgomeryPoint {
144-
MontgomeryPoint::from(self) * scalar
145+
self.to_affine() * scalar
145146
}
146147
}
147148

@@ -320,9 +321,6 @@ mod test {
320321
* MontgomeryScalar::try_from_rng(&mut OsRng).unwrap();
321322
let p3 = p1 + p2;
322323

323-
assert_eq!(
324-
MontgomeryPoint::from(p3),
325-
(MontgomeryPoint::from(p1) + p2).into()
326-
);
324+
assert_eq!(p3.to_affine(), (p1.to_affine() + p2).into());
327325
}
328326
}

0 commit comments

Comments
 (0)