diff --git a/build.rs b/build.rs index 2c30435..6b6e652 100644 --- a/build.rs +++ b/build.rs @@ -26,6 +26,11 @@ extern crate serde; #[cfg(feature = "yolocrypto")] extern crate stdsimd; +// Macros come first! +#[path="src/macros.rs"] +#[macro_use] +mod macros; + // Public modules #[path="src/scalar.rs"] diff --git a/src/edwards.rs b/src/edwards.rs index 5fca4e9..4af3ec5 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -378,12 +378,16 @@ impl<'a, 'b> Add<&'b ExtendedPoint> for &'a ExtendedPoint { } } +define_add_variants!(LHS = ExtendedPoint, RHS = ExtendedPoint, Output = ExtendedPoint); + impl<'b> AddAssign<&'b ExtendedPoint> for ExtendedPoint { fn add_assign(&mut self, _rhs: &'b ExtendedPoint) { *self = (self as &ExtendedPoint) + _rhs; } } +define_add_assign_variants!(LHS = ExtendedPoint, RHS = ExtendedPoint); + impl<'a, 'b> Sub<&'b ExtendedPoint> for &'a ExtendedPoint { type Output = ExtendedPoint; fn sub(self, other: &'b ExtendedPoint) -> ExtendedPoint { @@ -391,12 +395,16 @@ impl<'a, 'b> Sub<&'b ExtendedPoint> for &'a ExtendedPoint { } } +define_sub_variants!(LHS = ExtendedPoint, RHS = ExtendedPoint, Output = ExtendedPoint); + impl<'b> SubAssign<&'b ExtendedPoint> for ExtendedPoint { fn sub_assign(&mut self, _rhs: &'b ExtendedPoint) { *self = (self as &ExtendedPoint) - _rhs; } } +define_sub_assign_variants!(LHS = ExtendedPoint, RHS = ExtendedPoint); + // ------------------------------------------------------------------------ // Negation // ------------------------------------------------------------------------ @@ -414,6 +422,14 @@ impl<'a> Neg for &'a ExtendedPoint { } } +impl Neg for ExtendedPoint { + type Output = ExtendedPoint; + + fn neg(self) -> ExtendedPoint { + -&self + } +} + // ------------------------------------------------------------------------ // Scalar multiplication // ------------------------------------------------------------------------ @@ -425,6 +441,11 @@ impl<'b> MulAssign<&'b Scalar> for ExtendedPoint { } } +define_mul_assign_variants!(LHS = ExtendedPoint, RHS = Scalar); + +define_mul_variants!(LHS = ExtendedPoint, RHS = Scalar, Output = ExtendedPoint); +define_mul_variants!(LHS = Scalar, RHS = ExtendedPoint, Output = ExtendedPoint); + impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint { type Output = ExtendedPoint; /// Scalar multiplication: compute `scalar * self`. @@ -478,7 +499,7 @@ impl<'a, 'b> Mul<&'b ExtendedPoint> for &'a Scalar { /// For scalar multiplication of a basepoint, /// `EdwardsBasepointTable` is approximately 4x faster. fn mul(self, point: &'b ExtendedPoint) -> ExtendedPoint { - point * &self + point * self } } diff --git a/src/lib.rs b/src/lib.rs index 6c4ed32..0baf368 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,10 @@ extern crate serde; #[cfg(all(test, feature = "serde"))] extern crate serde_cbor; +// Internal macros. Must come first! +#[macro_use] +pub(crate) mod macros; + //------------------------------------------------------------------------ // curve25519-dalek public modules //------------------------------------------------------------------------ diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..448d32c --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,123 @@ +// -*- mode: rust; -*- +// +// This file is part of curve25519-dalek. +// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// See LICENSE for licensing information. +// +// Authors: +// - Isis Agora Lovecruft +// - Henry de Valence + +//! Internal macros. + +/// Define borrow and non-borrow variants of `Add`. +macro_rules! define_add_variants { + (LHS = $lhs:ty, RHS = $rhs:ty, Output = $out:ty) => { + impl<'b> Add<&'b $rhs> for $lhs { + type Output = $out; + fn add(self, rhs: &'b $rhs) -> $out { + &self + rhs + } + } + + impl<'a> Add<$rhs> for &'a $lhs { + type Output = $out; + fn add(self, rhs: $rhs) -> $out { + self + &rhs + } + } + + impl Add<$rhs> for $lhs { + type Output = $out; + fn add(self, rhs: $rhs) -> $out { + &self + &rhs + } + } + } +} + +/// Define non-borrow variants of `AddAssign`. +macro_rules! define_add_assign_variants { + (LHS = $lhs:ty, RHS = $rhs:ty) => { + impl AddAssign<$rhs> for $lhs { + fn add_assign(&mut self, rhs: $rhs) { + *self += &rhs; + } + } + } +} + +/// Define borrow and non-borrow variants of `Sub`. +macro_rules! define_sub_variants { + (LHS = $lhs:ty, RHS = $rhs:ty, Output = $out:ty) => { + impl<'b> Sub<&'b $rhs> for $lhs { + type Output = $out; + fn sub(self, rhs: &'b $rhs) -> $out { + &self - rhs + } + } + + impl<'a> Sub<$rhs> for &'a $lhs { + type Output = $out; + fn sub(self, rhs: $rhs) -> $out { + self - &rhs + } + } + + impl Sub<$rhs> for $lhs { + type Output = $out; + fn sub(self, rhs: $rhs) -> $out { + &self - &rhs + } + } + } +} + +/// Define non-borrow variants of `SubAssign`. +macro_rules! define_sub_assign_variants { + (LHS = $lhs:ty, RHS = $rhs:ty) => { + impl SubAssign<$rhs> for $lhs { + fn sub_assign(&mut self, rhs: $rhs) { + *self -= &rhs; + } + } + } +} + +/// Define borrow and non-borrow variants of `Mul`. +macro_rules! define_mul_variants { + (LHS = $lhs:ty, RHS = $rhs:ty, Output = $out:ty) => { + impl<'b> Mul<&'b $rhs> for $lhs { + type Output = $out; + fn mul(self, rhs: &'b $rhs) -> $out { + &self * rhs + } + } + + impl<'a> Mul<$rhs> for &'a $lhs { + type Output = $out; + fn mul(self, rhs: $rhs) -> $out { + self * &rhs + } + } + + impl Mul<$rhs> for $lhs { + type Output = $out; + fn mul(self, rhs: $rhs) -> $out { + &self * &rhs + } + } + } +} + +/// Define non-borrow variants of `MulAssign`. +macro_rules! define_mul_assign_variants { + (LHS = $lhs:ty, RHS = $rhs:ty) => { + impl MulAssign<$rhs> for $lhs { + fn mul_assign(&mut self, rhs: $rhs) { + *self *= &rhs; + } + } + } +} + diff --git a/src/ristretto.rs b/src/ristretto.rs index ee6260e..40d667b 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -925,12 +925,16 @@ impl<'a, 'b> Add<&'b RistrettoPoint> for &'a RistrettoPoint { } } +define_add_variants!(LHS = RistrettoPoint, RHS = RistrettoPoint, Output = RistrettoPoint); + impl<'b> AddAssign<&'b RistrettoPoint> for RistrettoPoint { fn add_assign(&mut self, _rhs: &RistrettoPoint) { *self = (self as &RistrettoPoint) + _rhs; } } +define_add_assign_variants!(LHS = RistrettoPoint, RHS = RistrettoPoint); + impl<'a, 'b> Sub<&'b RistrettoPoint> for &'a RistrettoPoint { type Output = RistrettoPoint; @@ -939,12 +943,16 @@ impl<'a, 'b> Sub<&'b RistrettoPoint> for &'a RistrettoPoint { } } +define_sub_variants!(LHS = RistrettoPoint, RHS = RistrettoPoint, Output = RistrettoPoint); + impl<'b> SubAssign<&'b RistrettoPoint> for RistrettoPoint { fn sub_assign(&mut self, _rhs: &RistrettoPoint) { *self = (self as &RistrettoPoint) - _rhs; } } +define_sub_assign_variants!(LHS = RistrettoPoint, RHS = RistrettoPoint); + impl<'a> Neg for &'a RistrettoPoint { type Output = RistrettoPoint; @@ -953,6 +961,14 @@ impl<'a> Neg for &'a RistrettoPoint { } } +impl Neg for RistrettoPoint { + type Output = RistrettoPoint; + + fn neg(self) -> RistrettoPoint { + -&self + } +} + impl<'b> MulAssign<&'b Scalar> for RistrettoPoint { fn mul_assign(&mut self, scalar: &'b Scalar) { let result = (self as &RistrettoPoint) * scalar; @@ -977,6 +993,12 @@ impl<'a, 'b> Mul<&'b RistrettoPoint> for &'a Scalar { } } +define_mul_assign_variants!(LHS = RistrettoPoint, RHS = Scalar); + +define_mul_variants!(LHS = RistrettoPoint, RHS = Scalar, Output = RistrettoPoint); +define_mul_variants!(LHS = Scalar, RHS = RistrettoPoint, Output = RistrettoPoint); + + /// Given a vector of (possibly secret) scalars and a vector of /// (possibly secret) points, compute `c_1 P_1 + ... + c_n P_n`. /// diff --git a/src/scalar.rs b/src/scalar.rs index 8d12b4e..64a59bc 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -186,6 +186,8 @@ impl<'b> MulAssign<&'b Scalar> for Scalar { } } +define_mul_assign_variants!(LHS = Scalar, RHS = Scalar); + impl<'a, 'b> Mul<&'b Scalar> for &'a Scalar { type Output = Scalar; fn mul(self, _rhs: &'b Scalar) -> Scalar { @@ -193,12 +195,16 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a Scalar { } } +define_mul_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar); + impl<'b> AddAssign<&'b Scalar> for Scalar { fn add_assign(&mut self, _rhs: &'b Scalar) { *self = UnpackedScalar::add(&self.unpack(), &_rhs.unpack()).pack(); } } +define_add_assign_variants!(LHS = Scalar, RHS = Scalar); + impl<'a, 'b> Add<&'b Scalar> for &'a Scalar { type Output = Scalar; fn add(self, _rhs: &'b Scalar) -> Scalar { @@ -206,12 +212,16 @@ impl<'a, 'b> Add<&'b Scalar> for &'a Scalar { } } +define_add_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar); + impl<'b> SubAssign<&'b Scalar> for Scalar { fn sub_assign(&mut self, _rhs: &'b Scalar) { *self = UnpackedScalar::sub(&self.unpack(), &_rhs.unpack()).pack(); } } +define_sub_assign_variants!(LHS = Scalar, RHS = Scalar); + impl<'a, 'b> Sub<&'b Scalar> for &'a Scalar { type Output = Scalar; fn sub(self, _rhs: &'b Scalar) -> Scalar { @@ -219,6 +229,8 @@ impl<'a, 'b> Sub<&'b Scalar> for &'a Scalar { } } +define_sub_variants!(LHS = Scalar, RHS = Scalar, Output = Scalar); + impl<'a> Neg for &'a Scalar { type Output = Scalar; fn neg(self) -> Scalar { @@ -226,6 +238,13 @@ impl<'a> Neg for &'a Scalar { } } +impl<'a> Neg for Scalar { + type Output = Scalar; + fn neg(self) -> Scalar { + -&self + } +} + impl ConditionallyAssignable for Scalar { /// Conditionally assign another Scalar to this one. ///