Skip to content

Commit d338e11

Browse files
authored
ed448-goldilocks: split Scalar into EdwardsScalar/DecafScalar (#1284)
Resolves #1229
1 parent 022154d commit d338e11

22 files changed

+998
-583
lines changed

ed448-goldilocks/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ It is intended to be portable, fast, and safe.
1717
## Usage
1818

1919
```rust
20-
use ed448_goldilocks::{EdwardsPoint, CompressedEdwardsY, Scalar, sha3::Shake256};
20+
use ed448_goldilocks::{EdwardsPoint, CompressedEdwardsY, EdwardsScalar, sha3::Shake256};
2121
use elliptic_curve::Field;
2222
use hash2curve::ExpandMsgXof;
2323
use rand_core::OsRng;
2424

25-
let secret_key = Scalar::TWO;
25+
let secret_key = EdwardsScalar::TWO;
2626
let public_key = EdwardsPoint::GENERATOR * &secret_key;
2727

2828
assert_eq!(public_key, EdwardsPoint::GENERATOR + EdwardsPoint::GENERATOR);
2929

30-
let secret_key = Scalar::try_from_rng(&mut OsRng).unwrap();
30+
let secret_key = EdwardsScalar::try_from_rng(&mut OsRng).unwrap();
3131
let public_key = EdwardsPoint::GENERATOR * &secret_key;
3232
let compressed_public_key = public_key.compress();
3333

3434
assert_eq!(compressed_public_key.to_bytes().len(), 57);
3535

36-
let hashed_scalar = Scalar::hash::<ExpandMsgXof<Shake256>>(b"test", b"edwards448_XOF:SHAKE256_ELL2_RO_");
36+
let hashed_scalar = EdwardsScalar::hash::<ExpandMsgXof<Shake256>>(b"test", b"edwards448_XOF:SHAKE256_ELL2_RO_");
3737
let input = hex_literal::hex!("c8c6c8f584e0c25efdb6af5ad234583c56dedd7c33e0c893468e96740fa0cf7f1a560667da40b7bde340a39252e89262fcf707d1180fd43400");
38-
let expected_scalar = Scalar::from_canonical_bytes(&input.into()).unwrap();
38+
let expected_scalar = EdwardsScalar::from_canonical_bytes(&input.into()).unwrap();
3939
assert_eq!(hashed_scalar, expected_scalar);
4040

4141
let hashed_point = EdwardsPoint::hash::<ExpandMsgXof<Shake256>>(b"test", b"edwards448_XOF:SHAKE256_ELL2_RO_");

ed448-goldilocks/src/constants.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::*;
2-
use crate::{Scalar, decaf::DecafPoint};
32

43
pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::ExtendedPoint {
54
X: TWISTED_EDWARDS_BASE_POINT.X,
@@ -12,4 +11,10 @@ pub const DECAF_BASEPOINT: DecafPoint = DecafPoint(curve::twedwards::extended::E
1211
/// $$
1312
/// \ell = 2^\{446\} + 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d.
1413
/// $$
15-
pub const BASEPOINT_ORDER: Scalar = Scalar(ORDER);
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.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
pub mod edwards;
22
pub mod montgomery;
3+
mod scalar;
34
pub(crate) mod scalar_mul;
45
pub(crate) mod twedwards;
56

67
pub use edwards::{AffinePoint, CompressedEdwardsY, EdwardsPoint};
78
pub use montgomery::{MontgomeryPoint, ProjectiveMontgomeryPoint};
9+
pub use scalar::{EdwardsScalar, EdwardsScalarBytes, WideEdwardsScalarBytes};

ed448-goldilocks/src/curve/edwards/affine.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,17 @@ impl TryFrom<AffinePoint> for NonIdentity<AffinePoint> {
136136
}
137137
}
138138

139-
impl Mul<AffinePoint> for Scalar {
139+
impl Mul<AffinePoint> for EdwardsScalar {
140140
type Output = EdwardsPoint;
141141

142142
#[inline]
143+
#[expect(clippy::op_ref, reason = "false-positive")]
143144
fn mul(self, rhs: AffinePoint) -> EdwardsPoint {
144145
self * &rhs
145146
}
146147
}
147148

148-
impl Mul<&AffinePoint> for Scalar {
149+
impl Mul<&AffinePoint> for EdwardsScalar {
149150
type Output = EdwardsPoint;
150151

151152
#[inline]

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

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ 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::BASEPOINT_ORDER;
6+
use crate::constants::EDWARDS_BASEPOINT_ORDER;
77
use crate::curve::edwards::affine::AffinePoint;
88
use crate::curve::montgomery::MontgomeryPoint; // XXX: need to fix this path
99
use crate::curve::scalar_mul::variable_base;
1010
use crate::curve::twedwards::extended::ExtendedPoint as TwistedExtendedPoint;
11-
use crate::field::{FieldElement, Scalar};
11+
use crate::field::FieldElement;
1212
use crate::*;
1313
use elliptic_curve::{
1414
CurveGroup, Error,
@@ -339,7 +339,7 @@ impl PartialEq for EdwardsPoint {
339339
impl Eq for EdwardsPoint {}
340340

341341
impl Group for EdwardsPoint {
342-
type Scalar = Scalar;
342+
type Scalar = EdwardsScalar;
343343

344344
fn try_from_rng<R>(rng: &mut R) -> Result<Self, R::Error>
345345
where
@@ -508,9 +508,9 @@ impl From<&EdwardsPoint> for AffinePoint {
508508
}
509509
}
510510

511-
impl<const N: usize> LinearCombination<[(EdwardsPoint, Scalar); N]> for EdwardsPoint {}
511+
impl<const N: usize> LinearCombination<[(EdwardsPoint, EdwardsScalar); N]> for EdwardsPoint {}
512512

513-
impl LinearCombination<[(EdwardsPoint, Scalar)]> for EdwardsPoint {}
513+
impl LinearCombination<[(EdwardsPoint, EdwardsScalar)]> for EdwardsPoint {}
514514

515515
impl CurveGroup for EdwardsPoint {
516516
type AffineRepr = AffinePoint;
@@ -546,7 +546,7 @@ impl EdwardsPoint {
546546
}
547547

548548
/// Generic scalar multiplication to compute s*P
549-
pub fn scalar_mul(&self, scalar: &Scalar) -> Self {
549+
pub fn scalar_mul(&self, scalar: &EdwardsScalar) -> Self {
550550
// Compute floor(s/4)
551551
let mut scalar_div_four = *scalar;
552552
scalar_div_four.div_by_four();
@@ -558,7 +558,7 @@ impl EdwardsPoint {
558558
}
559559

560560
/// Returns (scalar mod 4) * P in constant time
561-
pub(crate) fn scalar_mod_four(&self, scalar: &Scalar) -> Self {
561+
pub(crate) fn scalar_mod_four(&self, scalar: &EdwardsScalar) -> Self {
562562
// Compute compute (scalar mod 4)
563563
let s_mod_four = scalar[0] & 3;
564564

@@ -727,7 +727,7 @@ impl EdwardsPoint {
727727
/// * `false` if `self` has a nonzero torsion component and is not
728728
/// in the prime-order subgroup.
729729
pub fn is_torsion_free(&self) -> Choice {
730-
(self * BASEPOINT_ORDER).ct_eq(&Self::IDENTITY)
730+
(self * EDWARDS_BASEPOINT_ORDER).ct_eq(&Self::IDENTITY)
731731
}
732732

733733
/// Hash a message to a point on the curve
@@ -972,28 +972,36 @@ impl Neg for EdwardsPoint {
972972
// Scalar multiplication
973973
// ------------------------------------------------------------------------
974974

975-
impl<'b> MulAssign<&'b Scalar> for EdwardsPoint {
976-
fn mul_assign(&mut self, scalar: &'b Scalar) {
975+
impl<'b> MulAssign<&'b EdwardsScalar> for EdwardsPoint {
976+
fn mul_assign(&mut self, scalar: &'b EdwardsScalar) {
977977
let result = *self * scalar;
978978
*self = result;
979979
}
980980
}
981981

982-
define_mul_assign_variants!(LHS = EdwardsPoint, RHS = Scalar);
982+
define_mul_assign_variants!(LHS = EdwardsPoint, RHS = EdwardsScalar);
983983

984-
define_mul_variants!(LHS = EdwardsPoint, RHS = Scalar, Output = EdwardsPoint);
985-
define_mul_variants!(LHS = Scalar, RHS = EdwardsPoint, Output = EdwardsPoint);
984+
define_mul_variants!(
985+
LHS = EdwardsPoint,
986+
RHS = EdwardsScalar,
987+
Output = EdwardsPoint
988+
);
989+
define_mul_variants!(
990+
LHS = EdwardsScalar,
991+
RHS = EdwardsPoint,
992+
Output = EdwardsPoint
993+
);
986994

987-
impl Mul<&Scalar> for &EdwardsPoint {
995+
impl Mul<&EdwardsScalar> for &EdwardsPoint {
988996
type Output = EdwardsPoint;
989997

990998
/// Scalar multiplication: compute `scalar * self`.
991-
fn mul(self, scalar: &Scalar) -> EdwardsPoint {
999+
fn mul(self, scalar: &EdwardsScalar) -> EdwardsPoint {
9921000
self.scalar_mul(scalar)
9931001
}
9941002
}
9951003

996-
impl Mul<&EdwardsPoint> for &Scalar {
1004+
impl Mul<&EdwardsPoint> for &EdwardsScalar {
9971005
type Output = EdwardsPoint;
9981006

9991007
/// Scalar multiplication: compute `scalar * self`.
@@ -1295,24 +1303,24 @@ mod tests {
12951303
use rand_core::SeedableRng;
12961304

12971305
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0);
1298-
let x = Scalar::random(&mut rng);
1299-
let b = Scalar::random(&mut rng);
1306+
let x = EdwardsScalar::random(&mut rng);
1307+
let b = EdwardsScalar::random(&mut rng);
13001308

13011309
let g1 = EdwardsPoint::GENERATOR;
13021310
let g2 = EdwardsPoint::hash_with_defaults(b"test_pow_add_mul");
13031311

13041312
let expected_commitment = g1 * x + g2 * b;
13051313

1306-
let shift = Scalar::from(256u16);
1314+
let shift = EdwardsScalar::from(256u16);
13071315
let x_bytes = x.to_bytes_rfc_8032();
1308-
let mut sum = Scalar::ZERO;
1316+
let mut sum = EdwardsScalar::ZERO;
13091317
let mut components = [EdwardsPoint::IDENTITY; 57];
13101318
for i in 1..57 {
1311-
let r = Scalar::random(&mut rng);
1319+
let r = EdwardsScalar::random(&mut rng);
13121320
sum += r * shift.pow([i as u64]);
1313-
components[i] = g1 * Scalar::from(x_bytes[i]) + g2 * r;
1321+
components[i] = g1 * EdwardsScalar::from(x_bytes[i]) + g2 * r;
13141322
}
1315-
components[0] = g1 * Scalar::from(x_bytes[0]) + g2 * (b - sum);
1323+
components[0] = g1 * EdwardsScalar::from(x_bytes[0]) + g2 * (b - sum);
13161324

13171325
let mut computed_commitment = EdwardsPoint::IDENTITY;
13181326
for i in (0..57).rev() {

ed448-goldilocks/src/curve/montgomery.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
#![allow(non_snake_case)]
1212

1313
// use crate::constants::A_PLUS_TWO_OVER_FOUR;
14+
use crate::EdwardsScalar;
1415
use crate::curve::edwards::extended::EdwardsPoint;
15-
use crate::field::{FieldElement, Scalar};
16+
use crate::field::FieldElement;
1617
use core::fmt;
1718
use core::ops::Mul;
1819
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
@@ -75,11 +76,11 @@ pub struct ProjectiveMontgomeryPoint {
7576
W: FieldElement,
7677
}
7778

78-
impl Mul<&Scalar> for &MontgomeryPoint {
79+
impl Mul<&EdwardsScalar> for &MontgomeryPoint {
7980
type Output = MontgomeryPoint;
8081

8182
#[allow(clippy::suspicious_arithmetic_impl)]
82-
fn mul(self, scalar: &Scalar) -> MontgomeryPoint {
83+
fn mul(self, scalar: &EdwardsScalar) -> MontgomeryPoint {
8384
// Algorithm 8 of Costello-Smith 2017
8485
let affine_u = FieldElement::from_bytes(&self.0);
8586
let mut x0 = ProjectiveMontgomeryPoint::identity();
@@ -104,7 +105,7 @@ impl Mul<&Scalar> for &MontgomeryPoint {
104105
}
105106
}
106107

107-
impl Mul<&MontgomeryPoint> for &Scalar {
108+
impl Mul<&MontgomeryPoint> for &EdwardsScalar {
108109
type Output = MontgomeryPoint;
109110

110111
fn mul(self, point: &MontgomeryPoint) -> MontgomeryPoint {
@@ -221,7 +222,7 @@ mod tests {
221222

222223
#[test]
223224
fn test_montgomery_edwards() {
224-
let scalar = Scalar::from(200u32);
225+
let scalar = EdwardsScalar::from(200u32);
225226
use crate::GOLDILOCKS_BASE_POINT as bp;
226227

227228
// Montgomery scalar mul

0 commit comments

Comments
 (0)