use super::scalar::{Scalar, ScalarBytes, ScalarBytesFromScalar}; use core::borrow::Borrow; use core::ops::{Mul, MulAssign}; pub type GroupElement = curve25519_dalek::ristretto::RistrettoPoint; pub type CompressedGroup = curve25519_dalek::ristretto::CompressedRistretto; pub const GROUP_BASEPOINT_COMPRESSED: CompressedGroup = curve25519_dalek::constants::RISTRETTO_BASEPOINT_COMPRESSED; impl<'b> MulAssign<&'b Scalar> for GroupElement { fn mul_assign(&mut self, scalar: &'b Scalar) { let result = (self as &GroupElement) * Scalar::decompress_scalar(scalar); *self = result; } } impl<'a, 'b> Mul<&'b Scalar> for &'a GroupElement { type Output = GroupElement; fn mul(self, scalar: &'b Scalar) -> GroupElement { self * Scalar::decompress_scalar(scalar) } } impl<'a, 'b> Mul<&'b GroupElement> for &'a Scalar { type Output = GroupElement; fn mul(self, point: &'b GroupElement) -> GroupElement { Scalar::decompress_scalar(self) * point } } 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 } } }; } 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; } } }; } define_mul_assign_variants!(LHS = GroupElement, RHS = Scalar); define_mul_variants!(LHS = GroupElement, RHS = Scalar, Output = GroupElement); define_mul_variants!(LHS = Scalar, RHS = GroupElement, Output = GroupElement); pub trait VartimeMultiscalarMul { type Scalar; fn vartime_multiscalar_mul(scalars: I, points: J) -> Self where I: IntoIterator, I::Item: Borrow, J: IntoIterator, J::Item: Borrow, Self: Clone; } impl VartimeMultiscalarMul for GroupElement { type Scalar = super::scalar::Scalar; fn vartime_multiscalar_mul(scalars: I, points: J) -> Self where I: IntoIterator, I::Item: Borrow, J: IntoIterator, J::Item: Borrow, Self: Clone, { use curve25519_dalek::traits::VartimeMultiscalarMul; ::vartime_multiscalar_mul( scalars .into_iter() .map(|s| Scalar::decompress_scalar(s.borrow())) .collect::>(), points, ) } }