mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
Optimize scalar inversion by implementing square()
This shows an 11% speedup for invert()
This commit is contained in:
parent
ae4660db3e
commit
6747133519
1 changed files with 50 additions and 1 deletions
|
|
@ -568,7 +568,7 @@ impl UnpackedScalar {
|
||||||
let mut y = UnpackedScalar::one();
|
let mut y = UnpackedScalar::one();
|
||||||
// Run through bits of l-2 from highest to least
|
// Run through bits of l-2 from highest to least
|
||||||
for bit in constants::l_minus_2.bits().iter().rev() {
|
for bit in constants::l_minus_2.bits().iter().rev() {
|
||||||
y = UnpackedScalar::multiply_add(&y, &y, &UnpackedScalar::zero());
|
y = y.square();
|
||||||
if *bit == 1 {
|
if *bit == 1 {
|
||||||
y = UnpackedScalar::multiply_add(&y, self, &UnpackedScalar::zero());
|
y = UnpackedScalar::multiply_add(&y, self, &UnpackedScalar::zero());
|
||||||
}
|
}
|
||||||
|
|
@ -576,6 +576,40 @@ impl UnpackedScalar {
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute `a^2 (mod l)`.
|
||||||
|
pub fn square(&self) -> UnpackedScalar {
|
||||||
|
let a = self.0;
|
||||||
|
let mut result = [0i64; 24];
|
||||||
|
|
||||||
|
result[0] = a[0]*a[0];
|
||||||
|
result[1] = 2i64 * a[0]*a[1];
|
||||||
|
result[2] = 2i64 * (a[0]*a[2]) + a[1]*a[1];
|
||||||
|
result[3] = 2i64 * (a[0]*a[3] + a[1]*a[2]);
|
||||||
|
result[4] = 2i64 * (a[0]*a[4] + a[1]*a[3]) + a[2]*a[2];
|
||||||
|
result[5] = 2i64 * (a[0]*a[5] + a[1]*a[4] + a[2]*a[3]);
|
||||||
|
result[6] = 2i64 * (a[0]*a[6] + a[1]*a[5] + a[2]*a[4]) + a[3]*a[3];
|
||||||
|
result[7] = 2i64 * (a[0]*a[7] + a[1]*a[6] + a[2]*a[5] + a[3]*a[4]);
|
||||||
|
result[8] = 2i64 * (a[0]*a[8] + a[1]*a[7] + a[2]*a[6] + a[3]*a[5]) + a[4]*a[4];
|
||||||
|
result[9] = 2i64 * (a[0]*a[9] + a[1]*a[8] + a[2]*a[7] + a[3]*a[6] + a[4]*a[5]);
|
||||||
|
result[10] = 2i64 * (a[0]*a[10] + a[1]*a[9] + a[2]*a[8] + a[3]*a[7] + a[4]*a[6]) + a[5]*a[5];
|
||||||
|
result[11] = 2i64 * (a[0]*a[11] + a[1]*a[10] + a[2]*a[9] + a[3]*a[8] + a[4]*a[7] + a[5]*a[6]);
|
||||||
|
result[12] = 2i64 * (a[1]*a[11] + a[2]*a[10] + a[3]*a[9] + a[4]*a[8] + a[5]*a[7]) + a[6]*a[6];
|
||||||
|
result[13] = 2i64 * (a[2]*a[11] + a[3]*a[10] + a[4]*a[9] + a[5]*a[8] + a[6]*a[7]);
|
||||||
|
result[14] = 2i64 * (a[3]*a[11] + a[4]*a[10] + a[5]*a[9] + a[6]*a[8]) + a[7]*a[7];
|
||||||
|
result[15] = 2i64 * (a[4]*a[11] + a[5]*a[10] + a[6]*a[9] + a[7]*a[8]);
|
||||||
|
result[16] = 2i64 * (a[5]*a[11] + a[6]*a[10] + a[7]*a[9]) + a[8]*a[8];
|
||||||
|
result[17] = 2i64 * (a[6]*a[11] + a[7]*a[10] + a[8]*a[9]);
|
||||||
|
result[18] = 2i64 * (a[7]*a[11] + a[8]*a[10]) + a[9]*a[9];
|
||||||
|
result[19] = 2i64 * (a[8]*a[11] + a[9]*a[10]);
|
||||||
|
result[20] = 2i64 * (a[9]*a[11]) + a[10]*a[10];
|
||||||
|
result[21] = 2i64 * (a[10]*a[11]);
|
||||||
|
result[22] = a[11]*a[11];
|
||||||
|
result[23] = 0i64;
|
||||||
|
|
||||||
|
// Reduce limbs
|
||||||
|
UnpackedScalar::reduce_limbs(&mut result)
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute `ab+c (mod l)`.
|
/// Compute `ab+c (mod l)`.
|
||||||
pub fn multiply_add(a: &UnpackedScalar,
|
pub fn multiply_add(a: &UnpackedScalar,
|
||||||
b: &UnpackedScalar,
|
b: &UnpackedScalar,
|
||||||
|
|
@ -838,6 +872,15 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn square() {
|
||||||
|
let expected = Scalar::multiply_add(&X, &X, &Scalar::zero());
|
||||||
|
let actual = X.unpack().square().pack();
|
||||||
|
for i in 0..32 {
|
||||||
|
assert!(expected[i] == actual[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scalar_reduce() {
|
fn scalar_reduce() {
|
||||||
let mut bignum = [0u8; 64];
|
let mut bignum = [0u8; 64];
|
||||||
|
|
@ -914,6 +957,12 @@ mod bench {
|
||||||
b.iter(|| x.invert());
|
b.iter(|| x.invert());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn square(b: &mut Bencher) {
|
||||||
|
let x = X.unpack();
|
||||||
|
b.iter(|| x.square());
|
||||||
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn scalar_unpacked_multiply_add(b: &mut Bencher) {
|
fn scalar_unpacked_multiply_add(b: &mut Bencher) {
|
||||||
let x = X.unpack();
|
let x = X.unpack();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue