From 4da1d795a15fed774cd18d1c33628e6bbe5d5ce2 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 9 May 2017 00:01:48 +0000 Subject: [PATCH] Make scalar multiplication go both ways. Being able to do `P * s`, but not `s * P`, is slightly annoying, particularly with longer equations when it is desired to be able to glance at the maths and see that the code is the same. Now either syntax is allowed. --- src/curve.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/curve.rs b/src/curve.rs index 78ff254..4ad938c 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -817,6 +817,18 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint { } } +impl<'a, 'b> Mul<&'b ExtendedPoint> for &'a Scalar { + type Output = ExtendedPoint; + + /// Scalar multiplication: compute `self * point`. + /// + /// Uses a window of size 4. Note: for scalar multiplication of + /// the basepoint, `basepoint_mult` is approximately 4x faster. + fn mul(self, point: &'b ExtendedPoint) -> ExtendedPoint { + point * &self + } +} + /// Precomputation #[derive(Clone)] pub struct EdwardsBasepointTable(pub [[AffineNielsPoint; 8]; 32]); @@ -1459,6 +1471,17 @@ mod test { } } + #[test] + fn scalarmult_works_both_ways() { + let G: ExtendedPoint = constants::ED25519_BASEPOINT; + let s: Scalar = A_SCALAR; + + let P1 = &G * &s; + let P2 = &s * &G; + + assert!(P1.compress_edwards().to_bytes() == P2.compress_edwards().to_bytes()); + } + mod vartime { use super::super::*; use super::{A_SCALAR, B_SCALAR, A_TIMES_BASEPOINT, DOUBLE_SCALAR_MULT_RESULT};