Add an implementation of Scalar inversion

This commit is contained in:
Henry de Valence 2017-04-28 22:59:56 -07:00
parent 653f134bc7
commit 6ea1d4dad2
2 changed files with 39 additions and 0 deletions

View file

@ -166,6 +166,13 @@ pub const l_minus_1: Scalar = Scalar([ 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ]);
/// `lminus1` is the order of base point minus two, i.e. 2^252 +
/// 27742317777372353535851937790883648493 - 2, in little-endian form
pub const l_minus_2: Scalar = Scalar([ 0xeb, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ]);
/// The 8-torsion subgroup Ɛ[8].
///
/// In the case of Curve25519, it is cyclic; the `i`th element of the

View file

@ -209,6 +209,11 @@ impl Scalar {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ])
}
/// Compute the multiplicative inverse of this scalar.
pub fn invert(&self) -> Scalar {
self.unpack().invert().pack()
}
/// Get the bits of the scalar.
pub fn bits(&self) -> [i8;256] {
let mut bits = [0i8; 256];
@ -462,6 +467,19 @@ impl UnpackedScalar {
UnpackedScalar([1,0,0,0,0,0,0,0,0,0,0,0])
}
/// Compute the multiplicative inverse of this scalar.
pub fn invert(&self) -> UnpackedScalar {
let mut y = UnpackedScalar::one();
// Run through bits of l-2 from highest to least
for bit in constants::l_minus_2.bits().iter().rev() {
y = &y * &y;
if *bit == 1 {
y *= self;
}
}
y
}
/// Compute `ab+c (mod l)`.
pub fn multiply_add(a: &UnpackedScalar,
b: &UnpackedScalar,
@ -727,6 +745,14 @@ mod test {
}
}
#[test]
fn invert() {
let x = UnpackedScalar([2,0,0,0,0,0,0,0,0,0,0,0]);
let x_inv = x.invert();
let should_be_one = &x * &x_inv;
assert_eq!(should_be_one.pack(), Scalar::one());
}
// Negating a scalar twice should result in the original scalar.
#[test]
fn scalar_neg() {
@ -757,6 +783,12 @@ mod bench {
b.iter(|| Scalar::multiply_add(&X, &Y, &Z) );
}
#[bench]
fn invert(b: &mut Bencher) {
let x = X.unpack();
b.iter(|| x.invert());
}
#[bench]
fn scalar_unpacked_multiply_add(b: &mut Bencher) {
let x = X.unpack();