Skip to content

Commit a442897

Browse files
committed
Implement Reduce for MontgomeryScalar
1 parent 022faaa commit a442897

File tree

5 files changed

+30
-20
lines changed

5 files changed

+30
-20
lines changed

ed448-goldilocks/src/edwards/scalar.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::Ed448;
22
use crate::field::{CurveWithScalar, ORDER, Scalar, ScalarBytes, WideScalarBytes};
33

44
use elliptic_curve::array::Array;
5-
use elliptic_curve::bigint::{Limb, NonZero, U448, U704};
6-
use elliptic_curve::consts::{U57, U84, U88};
5+
use elliptic_curve::bigint::{Limb, U448};
6+
use elliptic_curve::consts::{U57, U84};
77
use elliptic_curve::ops::Reduce;
88
use elliptic_curve::scalar::FromUintUnchecked;
99
use subtle::{Choice, CtOption};
@@ -84,17 +84,7 @@ impl From<&EdwardsScalar> for elliptic_curve::scalar::ScalarBits<Ed448> {
8484

8585
impl Reduce<Array<u8, U84>> for EdwardsScalar {
8686
fn reduce(value: &Array<u8, U84>) -> Self {
87-
const SEMI_WIDE_MODULUS: NonZero<U704> = NonZero::<U704>::new_unwrap(U704::from_be_hex(
88-
"00000000000000000000000000000000000000000000000000000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3",
89-
));
90-
let mut tmp = Array::<u8, U88>::default();
91-
tmp[4..].copy_from_slice(&value[..]);
92-
93-
let mut num = U704::from_be_slice(&tmp[..]);
94-
num %= SEMI_WIDE_MODULUS;
95-
let mut words = [0; U448::LIMBS];
96-
words.copy_from_slice(&num.to_words()[..U448::LIMBS]);
97-
Scalar::new(U448::from_words(words))
87+
Self::from_okm_u84(value)
9888
}
9989
}
10090

ed448-goldilocks/src/field/element.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,15 +531,13 @@ mod tests {
531531
.unwrap();
532532
let mut data = Array::<u8, U84>::default();
533533
expander.fill_bytes(&mut data).unwrap();
534-
// TODO: This should be `Curve448FieldElement`.
535534
let u0 = FieldElement::reduce(&data);
536535
let mut e_u0 = *expected_u0;
537536
e_u0.reverse();
538537
let mut e_u1 = *expected_u1;
539538
e_u1.reverse();
540539
assert_eq!(u0.to_bytes(), e_u0);
541540
expander.fill_bytes(&mut data).unwrap();
542-
// TODO: This should be `Curve448FieldElement`.
543541
let u1 = FieldElement::reduce(&data);
544542
assert_eq!(u1.to_bytes(), e_u1);
545543
}

ed448-goldilocks/src/field/scalar.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use elliptic_curve::{
1313
Array, ArraySize,
1414
typenum::{Prod, Unsigned},
1515
},
16-
bigint::{Integer, Limb, U448, U896, Word, Zero},
17-
consts::U2,
16+
bigint::{Integer, Limb, NonZero, U448, U704, U896, Word, Zero},
17+
consts::{U2, U84, U88},
1818
ff::{Field, helpers},
1919
ops::{Invert, Reduce, ReduceNonZero},
2020
scalar::{FromUintUnchecked, IsHigh},
@@ -815,4 +815,18 @@ impl<C: CurveWithScalar> Scalar<C> {
815815
pub fn to_scalar<O: CurveWithScalar>(&self) -> Scalar<O> {
816816
Scalar::new(self.scalar)
817817
}
818+
819+
pub(crate) fn from_okm_u84(data: &Array<u8, U84>) -> Self {
820+
const SEMI_WIDE_MODULUS: NonZero<U704> = NonZero::<U704>::new_unwrap(U704::from_be_hex(
821+
"00000000000000000000000000000000000000000000000000000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3",
822+
));
823+
let mut tmp = Array::<u8, U88>::default();
824+
tmp[4..].copy_from_slice(&data[..]);
825+
826+
let mut num = U704::from_be_slice(&tmp[..]);
827+
num %= SEMI_WIDE_MODULUS;
828+
let mut words = [0; U448::LIMBS];
829+
words.copy_from_slice(&num.to_words()[..U448::LIMBS]);
830+
Scalar::new(U448::from_words(words))
831+
}
818832
}

ed448-goldilocks/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ impl Curve for Curve448 {
189189
type FieldBytesSize = U56;
190190
type Uint = U448;
191191

192-
const ORDER: NonZero<U448> = ORDER;
192+
const ORDER: Odd<U448> = ORDER;
193193
}
194194

195195
impl PrimeCurve for Curve448 {}

ed448-goldilocks/src/montgomery/scalar.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use elliptic_curve::array::Array;
12
use elliptic_curve::bigint::{Limb, U448};
2-
use elliptic_curve::consts::U56;
3+
use elliptic_curve::consts::{U56, U84};
4+
use elliptic_curve::ops::Reduce;
35
use elliptic_curve::scalar::FromUintUnchecked;
46
use subtle::{Choice, CtOption};
57

@@ -14,7 +16,7 @@ impl CurveWithScalar for Curve448 {
1416
U448::from_le_slice(&input[..56]),
1517
U448::from_le_slice(&input[56..112]),
1618
);
17-
Scalar::new(U448::rem_wide_vartime(value, &ORDER))
19+
Scalar::new(U448::rem_wide_vartime(value, ORDER.as_nz_ref()))
1820
}
1921

2022
fn from_canonical_bytes(bytes: &ScalarBytes<Self>) -> subtle::CtOption<Scalar<Self>> {
@@ -64,6 +66,12 @@ impl From<&MontgomeryScalar> for elliptic_curve::scalar::ScalarBits<Curve448> {
6466
}
6567
}
6668

69+
impl Reduce<Array<u8, U84>> for MontgomeryScalar {
70+
fn reduce(value: &Array<u8, U84>) -> Self {
71+
Self::from_okm_u84(value)
72+
}
73+
}
74+
6775
#[cfg(test)]
6876
mod test {
6977
use super::*;

0 commit comments

Comments
 (0)