Skip to content

Commit e8b3a04

Browse files
authored
ed448-goldilocks: assorted fixes and improvements (#1302)
* `DecafPoint` is always torsion free * Use `Uint::to_le_byte_array()` directly * Use `is_negative()` directly * Enforce constant-time `FieldElement::square_n()` * Simplify `FieldElement::square_n()` and protect against zero * Use double optimization where appropriate * Use `Uint::is_odd()` directly * Hide `EDWARDS_BASEPOINT_ORDER` * Use squaring instead of multiplication where appropriate
1 parent cfafae2 commit e8b3a04

File tree

7 files changed

+27
-46
lines changed

7 files changed

+27
-46
lines changed

ed448-goldilocks/src/constants.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,3 @@ pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::E
66
Z: TWISTED_EDWARDS_BASE_POINT.Z,
77
T: TWISTED_EDWARDS_BASE_POINT.T,
88
});
9-
10-
/// `BASEPOINT_ORDER` is the order of the Ed448 basepoint, i.e.,
11-
/// $$
12-
/// \ell = 2^\{446\} + 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d.
13-
/// $$
14-
pub const EDWARDS_BASEPOINT_ORDER: EdwardsScalar = EdwardsScalar::new(ORDER);
15-
16-
/// `BASEPOINT_ORDER` is the order of the Decaf448 basepoint, i.e.,
17-
/// $$
18-
/// \ell = 2^\{446\} + 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d.
19-
/// $$
20-
pub const DECAF_BASEPOINT_ORDER: DecafScalar = DecafScalar::new(ORDER);

ed448-goldilocks/src/curve/twedwards/extended.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl ExtendedPoint {
115115

116116
// Compute x
117117
let xy = x * y;
118-
let x_numerator = xy + xy;
118+
let x_numerator = xy.double();
119119
let x_denom = y.square() - (a * x.square());
120120
let new_x = x_numerator * x_denom.invert();
121121

ed448-goldilocks/src/curve/twedwards/extensible.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl ExtensiblePoint {
5252
pub fn double(&self) -> ExtensiblePoint {
5353
let A = self.X.square();
5454
let B = self.Y.square();
55-
let C = self.Z.square() + self.Z.square();
55+
let C = self.Z.square().double();
5656
let D = -A;
5757
let E = (self.X + self.Y).square() - A - B;
5858
let G = D + B;

ed448-goldilocks/src/decaf/points.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::constants::{DECAF_BASEPOINT, DECAF_BASEPOINT_ORDER};
1+
use crate::constants::DECAF_BASEPOINT;
22
use crate::curve::twedwards::extended::ExtendedPoint;
33
use crate::field::FieldElement;
44
use crate::*;
@@ -226,7 +226,7 @@ impl CofactorGroup for DecafPoint {
226226
}
227227

228228
fn is_torsion_free(&self) -> Choice {
229-
(self * DECAF_BASEPOINT_ORDER).ct_eq(&Self::IDENTITY)
229+
Choice::from(1)
230230
}
231231
}
232232

@@ -550,7 +550,7 @@ impl CompressedDecaf {
550550
let (I, ok) = (v * u1_sqr).inverse_square_root();
551551

552552
let Dx = I * u1;
553-
let Dxs = (s + s) * Dx;
553+
let Dxs = s.double() * Dx;
554554

555555
let mut X = (Dxs * I) * v;
556556
let k = Dxs * FieldElement::DECAF_FACTOR;

ed448-goldilocks/src/edwards/extended.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use core::fmt::{Display, Formatter, LowerHex, Result as FmtResult, UpperHex};
33
use core::iter::Sum;
44
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
55

6-
use crate::constants::EDWARDS_BASEPOINT_ORDER;
76
use crate::curve::scalar_mul::variable_base;
87
use crate::curve::twedwards::extended::ExtendedPoint as TwistedExtendedPoint;
98
use crate::field::FieldElement;
@@ -673,7 +672,7 @@ impl EdwardsPoint {
673672

674673
// Compute x
675674
let xy = x * y;
676-
let x_numerator = xy + xy;
675+
let x_numerator = xy.double();
677676
let x_denom = y.square() - (a * x.square());
678677
let new_x = x_numerator * x_denom.invert();
679678

@@ -724,7 +723,7 @@ impl EdwardsPoint {
724723
/// * `false` if `self` has a nonzero torsion component and is not
725724
/// in the prime-order subgroup.
726725
pub fn is_torsion_free(&self) -> Choice {
727-
(self * EDWARDS_BASEPOINT_ORDER).ct_eq(&Self::IDENTITY)
726+
(self * EdwardsScalar::new(ORDER)).ct_eq(&Self::IDENTITY)
728727
}
729728

730729
/// Hash a message to a point on the curve

ed448-goldilocks/src/field/element.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
use elliptic_curve::{
1010
array::Array,
1111
bigint::{
12-
NonZero, U448, U704,
12+
Integer, NonZero, U448, U704,
1313
consts::{U56, U84, U88},
1414
},
1515
group::cofactor::CofactorGroup,
@@ -258,8 +258,7 @@ impl FieldElement {
258258
pub const ZERO: Self = Self(ConstMontyType::new(&U448::ZERO));
259259

260260
pub fn is_negative(&self) -> Choice {
261-
let bytes = self.to_bytes();
262-
(bytes[0] & 1).into()
261+
self.0.retrieve().is_odd()
263262
}
264263

265264
/// Inverts a field element
@@ -276,13 +275,10 @@ impl FieldElement {
276275
}
277276

278277
/// Squares a field element `n` times
279-
fn square_n(&self, mut n: u32) -> FieldElement {
280-
let mut result = self.square();
278+
fn square_n<const N: u32>(&self) -> FieldElement {
279+
let mut result = *self;
281280

282-
// Decrease value by 1 since we just did a squaring
283-
n -= 1;
284-
285-
for _ in 0..n {
281+
for _ in 0..N {
286282
result = result.square();
287283
}
288284

@@ -320,7 +316,7 @@ impl FieldElement {
320316
}
321317

322318
pub fn double(&self) -> Self {
323-
Self(self.0.add(&self.0))
319+
Self(self.0.double())
324320
}
325321

326322
/// Computes the inverse square root of a field element
@@ -333,25 +329,25 @@ impl FieldElement {
333329
l2 = l1 * self;
334330
l1 = l2.square();
335331
l2 = l1 * self;
336-
l1 = l2.square_n(3);
332+
l1 = l2.square_n::<3>();
337333
l0 = l2 * l1;
338-
l1 = l0.square_n(3);
334+
l1 = l0.square_n::<3>();
339335
l0 = l2 * l1;
340-
l2 = l0.square_n(9);
336+
l2 = l0.square_n::<9>();
341337
l1 = l0 * l2;
342-
l0 = l1 * l1;
338+
l0 = l1.square();
343339
l2 = l0 * self;
344-
l0 = l2.square_n(18);
340+
l0 = l2.square_n::<18>();
345341
l2 = l1 * l0;
346-
l0 = l2.square_n(37);
342+
l0 = l2.square_n::<37>();
347343
l1 = l2 * l0;
348-
l0 = l1.square_n(37);
344+
l0 = l1.square_n::<37>();
349345
l1 = l2 * l0;
350-
l0 = l1.square_n(111);
346+
l0 = l1.square_n::<111>();
351347
l2 = l1 * l0;
352348
l0 = l2.square();
353349
l1 = l0 * self;
354-
l0 = l1.square_n(223);
350+
l0 = l1.square_n::<223>();
355351
l1 = l2 * l0;
356352
l2 = l1.square();
357353
l0 = l2 * self;
@@ -418,7 +414,7 @@ impl FieldElement {
418414
let e = b * c;
419415

420416
let mut a = n * e;
421-
a.conditional_negate(!Choice::from(a.0.retrieve().bit(0)) ^ square);
417+
a.conditional_negate(!a.is_negative() ^ square);
422418

423419
let c = e * ONE_MINUS_TWO_D;
424420
let b = c.square();
@@ -429,7 +425,7 @@ impl FieldElement {
429425
let b = b - Self::ONE;
430426

431427
let c = a.square();
432-
let a = a + a;
428+
let a = a.double();
433429
let e = c + Self::ONE;
434430
let T = a * e;
435431
let X = a * b;

ed448-goldilocks/src/field/scalar.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl<C: CurveWithScalar> Field for Scalar<C> {
314314
}
315315

316316
fn double(&self) -> Self {
317-
self + self
317+
self.double()
318318
}
319319

320320
fn invert(&self) -> CtOption<Self> {
@@ -641,7 +641,7 @@ impl<C: CurveWithScalar> Scalar<C> {
641641

642642
/// Compute `self` + `self` mod ℓ
643643
pub const fn double(&self) -> Self {
644-
self.addition(self)
644+
Self::new(self.scalar.double_mod(&ORDER))
645645
}
646646

647647
/// Compute `self` - `rhs` mod ℓ
@@ -728,9 +728,7 @@ impl<C: CurveWithScalar> Scalar<C> {
728728

729729
/// Convert this `Scalar` to a little-endian byte array.
730730
pub fn to_bytes(&self) -> [u8; 56] {
731-
let bytes = self.scalar.to_le_bytes();
732-
let output: [u8; 56] = core::array::from_fn(|i| bytes[i]);
733-
output
731+
self.scalar.to_le_byte_array().0
734732
}
735733

736734
/// Invert this scalar

0 commit comments

Comments
 (0)