Implement Mul for scalar multiplication

This commit is contained in:
Henry de Valence 2017-04-25 16:43:15 -07:00 committed by Henry & Isis
parent 7cbb8dd94e
commit 59453d755d
2 changed files with 27 additions and 14 deletions

View file

@ -79,7 +79,9 @@
use core::fmt::Debug; use core::fmt::Debug;
use core::iter::Iterator; use core::iter::Iterator;
use core::ops::{Add, Sub, Neg, Index}; use core::ops::{Add, Sub, Neg};
use core::ops::{Mul, MulAssign};
use core::ops::Index;
use constants; use constants;
use field::FieldElement; use field::FieldElement;
@ -789,18 +791,20 @@ impl<'a> Neg for &'a AffineNielsPoint {
// Scalar multiplication // Scalar multiplication
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/// Trait for scalar multiplication of an arbitrary point. impl<'b> MulAssign<&'b Scalar> for ExtendedPoint {
pub trait ScalarMult<S> { fn mul_assign(&mut self, scalar: &'b Scalar) {
/// Compute `scalar * self`. let result = (self as &ExtendedPoint) * scalar;
fn scalar_mult(&self, scalar: &S) -> Self; *self = result;
}
} }
impl ScalarMult<Scalar> for ExtendedPoint { impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint {
type Output = ExtendedPoint;
/// Scalar multiplication: compute `scalar * self`. /// Scalar multiplication: compute `scalar * self`.
/// ///
/// Uses a window of size 4. Note: for scalar multiplication of /// Uses a window of size 4. Note: for scalar multiplication of
/// the basepoint, `basepoint_mult` is approximately 4x faster. /// the basepoint, `basepoint_mult` is approximately 4x faster.
fn scalar_mult(&self, scalar: &Scalar) -> ExtendedPoint { fn mul(self, scalar: &'b Scalar) -> ExtendedPoint {
let A = self.to_projective_niels(); let A = self.to_projective_niels();
let mut As: [ProjectiveNielsPoint; 8] = [A; 8]; let mut As: [ProjectiveNielsPoint; 8] = [A; 8];
for i in 0..7 { for i in 0..7 {
@ -1369,7 +1373,7 @@ mod test {
/// Test scalar_mult versus a known scalar multiple from ed25519.py /// Test scalar_mult versus a known scalar multiple from ed25519.py
#[test] #[test]
fn scalar_mult_vs_ed25519py() { fn scalar_mult_vs_ed25519py() {
let aB = constants::ED25519_BASEPOINT.scalar_mult(&A_SCALAR); let aB = &constants::ED25519_BASEPOINT * &A_SCALAR;
assert_eq!(aB.compress_edwards(), A_TIMES_BASEPOINT); assert_eq!(aB.compress_edwards(), A_TIMES_BASEPOINT);
} }
@ -1454,7 +1458,7 @@ mod test {
// N.B. each scalar_mult does 1407 field mults, 1024 field squarings, // N.B. each scalar_mult does 1407 field mults, 1024 field squarings,
// so this does ~ 1M of each operation. // so this does ~ 1M of each operation.
for _ in 0..1_000 { for _ in 0..1_000 {
P = P.scalar_mult(&A_SCALAR); P *= &A_SCALAR;
} }
} }
@ -1501,7 +1505,7 @@ mod bench {
#[bench] #[bench]
fn scalar_mult(b: &mut Bencher) { fn scalar_mult(b: &mut Bencher) {
let bp = constants::ED25519_BASEPOINT; let bp = constants::ED25519_BASEPOINT;
b.iter(|| bp.scalar_mult(&A_SCALAR)); b.iter(|| &bp * &A_SCALAR);
} }
#[bench] #[bench]

View file

@ -30,6 +30,7 @@ use subtle::CTAssignable;
use subtle::CTNegatable; use subtle::CTNegatable;
use core::ops::{Add, Sub, Neg}; use core::ops::{Add, Sub, Neg};
use core::ops::{Mul, MulAssign};
#[cfg(all(not(feature = "std"), feature = "basepoint_table_creation"))] #[cfg(all(not(feature = "std"), feature = "basepoint_table_creation"))]
use collections::boxed::Box; use collections::boxed::Box;
@ -40,7 +41,6 @@ use curve;
use curve::ExtendedPoint; use curve::ExtendedPoint;
use curve::EdwardsBasepointTable; use curve::EdwardsBasepointTable;
use curve::BasepointMult; use curve::BasepointMult;
use curve::ScalarMult;
use curve::Identity; use curve::Identity;
use scalar::Scalar; use scalar::Scalar;
@ -250,9 +250,18 @@ impl<'a> Neg for &'a DecafPoint {
} }
} }
impl ScalarMult<Scalar> for DecafPoint { impl<'b> MulAssign<&'b Scalar> for DecafPoint {
fn scalar_mult(&self, scalar: &Scalar) -> DecafPoint { fn mul_assign(&mut self, scalar: &'b Scalar) {
DecafPoint(self.0.scalar_mult(scalar)) let result = (self as &DecafPoint) * scalar;
*self = result;
}
}
impl<'a, 'b> Mul<&'b Scalar> for &'a DecafPoint {
type Output = DecafPoint;
/// Scalar multiplication: compute `scalar * self`.
fn mul(self, scalar: &'b Scalar) -> DecafPoint {
DecafPoint(&self.0 * scalar)
} }
} }