mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
Add test that scalar Montgomery reduction matches reduction.
This commit is contained in:
parent
e2cbec81fc
commit
583a45ddc2
3 changed files with 49 additions and 15 deletions
|
|
@ -731,6 +731,38 @@ mod test {
|
||||||
assert_eq!(should_be_unpacked.0, unpacked.0);
|
assert_eq!(should_be_unpacked.0, unpacked.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn montgomery_reduce_matches_reduce() {
|
||||||
|
let mut bignum = [0u8; 64];
|
||||||
|
|
||||||
|
// set bignum = x + 2^256x
|
||||||
|
for i in 0..32 {
|
||||||
|
bignum[ i] = X[i];
|
||||||
|
bignum[32+i] = X[i];
|
||||||
|
}
|
||||||
|
// x + 2^256x (mod l)
|
||||||
|
// = 3958878930004874126169954872055634648693766179881526445624823978500314864344
|
||||||
|
let expected = Scalar([216, 154, 179, 139, 210, 121, 2, 71,
|
||||||
|
69, 99, 158, 216, 23, 173, 63, 100,
|
||||||
|
204, 0, 91, 50, 219, 153, 57, 249,
|
||||||
|
28, 82, 31, 197, 100, 165, 192, 8]);
|
||||||
|
let reduced = Scalar::reduce(&bignum);
|
||||||
|
|
||||||
|
// The reduced scalar should match the expected
|
||||||
|
assert_eq!(reduced.0, expected.0);
|
||||||
|
|
||||||
|
// (x + 2^256x) * R
|
||||||
|
let interim = UnpackedScalar::mul_internal(&UnpackedScalar::from_bytes_wide(&bignum),
|
||||||
|
&constants::R);
|
||||||
|
// ((x + 2^256x) * R) / R (mod l)
|
||||||
|
let montgomery_reduced = UnpackedScalar::montgomery_reduce(&interim);
|
||||||
|
|
||||||
|
// The Montgomery reduced scalar should match the reduced one, as well as the expected
|
||||||
|
assert_eq!(montgomery_reduced.0, reduced.unpack().0);
|
||||||
|
assert_eq!(montgomery_reduced.0, expected.unpack().0)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde_cbor;
|
use serde_cbor;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ impl Scalar32 {
|
||||||
///
|
///
|
||||||
/// This is implemented with a one-level refined Karatsuba decomposition
|
/// This is implemented with a one-level refined Karatsuba decomposition
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_internal(a: &Scalar32, b: &Scalar32) -> [u64; 17] {
|
pub (crate) fn mul_internal(a: &Scalar32, b: &Scalar32) -> [u64; 17] {
|
||||||
let mut z = [0u64; 17];
|
let mut z = [0u64; 17];
|
||||||
|
|
||||||
z[0] = m(a[0],b[0]); // c00
|
z[0] = m(a[0],b[0]); // c00
|
||||||
|
|
@ -289,7 +289,7 @@ impl Scalar32 {
|
||||||
|
|
||||||
/// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^261
|
/// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^261
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn montgomery_reduce(limbs: &[u64; 17]) -> Scalar32 {
|
pub (crate) fn montgomery_reduce(limbs: &[u64; 17]) -> Scalar32 {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn part1(sum: u64) -> (u64, u32) {
|
fn part1(sum: u64) -> (u64, u32) {
|
||||||
|
|
|
||||||
|
|
@ -181,18 +181,20 @@ impl Scalar64 {
|
||||||
|
|
||||||
/// Compute `a * b`
|
/// Compute `a * b`
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul_internal(a: &Scalar64, b: &Scalar64) -> [u128; 9] {
|
pub (crate) fn mul_internal(a: &Scalar64, b: &Scalar64) -> [u128; 9] {
|
||||||
[
|
let mut z = [0u128; 9];
|
||||||
m(a[0],b[0]),
|
|
||||||
m(a[0],b[1]) + m(a[1],b[0]),
|
z[0] = m(a[0],b[0]);
|
||||||
m(a[0],b[2]) + m(a[1],b[1]) + m(a[2],b[0]),
|
z[1] = m(a[0],b[1]) + m(a[1],b[0]);
|
||||||
m(a[0],b[3]) + m(a[1],b[2]) + m(a[2],b[1]) + m(a[3],b[0]),
|
z[2] = m(a[0],b[2]) + m(a[1],b[1]) + m(a[2],b[0]);
|
||||||
m(a[0],b[4]) + m(a[1],b[3]) + m(a[2],b[2]) + m(a[3],b[1]) + m(a[4],b[0]),
|
z[3] = m(a[0],b[3]) + m(a[1],b[2]) + m(a[2],b[1]) + m(a[3],b[0]);
|
||||||
m(a[1],b[4]) + m(a[2],b[3]) + m(a[3],b[2]) + m(a[4],b[1]),
|
z[4] = m(a[0],b[4]) + m(a[1],b[3]) + m(a[2],b[2]) + m(a[3],b[1]) + m(a[4],b[0]);
|
||||||
m(a[2],b[4]) + m(a[3],b[3]) + m(a[4],b[2]),
|
z[5] = m(a[1],b[4]) + m(a[2],b[3]) + m(a[3],b[2]) + m(a[4],b[1]);
|
||||||
m(a[3],b[4]) + m(a[4],b[3]),
|
z[6] = m(a[2],b[4]) + m(a[3],b[3]) + m(a[4],b[2]);
|
||||||
m(a[4],b[4])
|
z[7] = m(a[3],b[4]) + m(a[4],b[3]);
|
||||||
]
|
z[8] = m(a[4],b[4]);
|
||||||
|
|
||||||
|
z
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute `a^2`
|
/// Compute `a^2`
|
||||||
|
|
@ -220,7 +222,7 @@ impl Scalar64 {
|
||||||
|
|
||||||
/// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^260
|
/// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^260
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn montgomery_reduce(limbs: &[u128; 9]) -> Scalar64 {
|
pub (crate) fn montgomery_reduce(limbs: &[u128; 9]) -> Scalar64 {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn part1(sum: u128) -> (u128, u64) {
|
fn part1(sum: u128) -> (u128, u64) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue