arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/group.rs
src/group.rsRaw
  1use super::scalar::{Scalar, ScalarBytes, ScalarBytesFromScalar};
  2use core::borrow::Borrow;
  3use core::ops::{Mul, MulAssign};
  4
  5pub type GroupElement = curve25519_dalek::ristretto::RistrettoPoint;
  6pub type CompressedGroup = curve25519_dalek::ristretto::CompressedRistretto;
  7pub const GROUP_BASEPOINT_COMPRESSED: CompressedGroup =
  8  curve25519_dalek::constants::RISTRETTO_BASEPOINT_COMPRESSED;
  9
 10impl<'b> MulAssign<&'b Scalar> for GroupElement {
 11  fn mul_assign(&mut self, scalar: &'b Scalar) {
 12    let result = (self as &GroupElement) * Scalar::decompress_scalar(scalar);
 13    *self = result;
 14  }
 15}
 16
 17impl<'a, 'b> Mul<&'b Scalar> for &'a GroupElement {
 18  type Output = GroupElement;
 19  fn mul(self, scalar: &'b Scalar) -> GroupElement {
 20    self * Scalar::decompress_scalar(scalar)
 21  }
 22}
 23
 24impl<'a, 'b> Mul<&'b GroupElement> for &'a Scalar {
 25  type Output = GroupElement;
 26
 27  fn mul(self, point: &'b GroupElement) -> GroupElement {
 28    Scalar::decompress_scalar(self) * point
 29  }
 30}
 31
 32macro_rules! define_mul_variants {
 33  (LHS = $lhs:ty, RHS = $rhs:ty, Output = $out:ty) => {
 34    impl<'b> Mul<&'b $rhs> for $lhs {
 35      type Output = $out;
 36      fn mul(self, rhs: &'b $rhs) -> $out {
 37        &self * rhs
 38      }
 39    }
 40
 41    impl<'a> Mul<$rhs> for &'a $lhs {
 42      type Output = $out;
 43      fn mul(self, rhs: $rhs) -> $out {
 44        self * &rhs
 45      }
 46    }
 47
 48    impl Mul<$rhs> for $lhs {
 49      type Output = $out;
 50      fn mul(self, rhs: $rhs) -> $out {
 51        &self * &rhs
 52      }
 53    }
 54  };
 55}
 56
 57macro_rules! define_mul_assign_variants {
 58  (LHS = $lhs:ty, RHS = $rhs:ty) => {
 59    impl MulAssign<$rhs> for $lhs {
 60      fn mul_assign(&mut self, rhs: $rhs) {
 61        *self *= &rhs;
 62      }
 63    }
 64  };
 65}
 66
 67define_mul_assign_variants!(LHS = GroupElement, RHS = Scalar);
 68define_mul_variants!(LHS = GroupElement, RHS = Scalar, Output = GroupElement);
 69define_mul_variants!(LHS = Scalar, RHS = GroupElement, Output = GroupElement);
 70
 71pub trait VartimeMultiscalarMul {
 72  type Scalar;
 73  fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Self
 74  where
 75    I: IntoIterator,
 76    I::Item: Borrow<Self::Scalar>,
 77    J: IntoIterator,
 78    J::Item: Borrow<Self>,
 79    Self: Clone;
 80}
 81
 82impl VartimeMultiscalarMul for GroupElement {
 83  type Scalar = super::scalar::Scalar;
 84  fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Self
 85  where
 86    I: IntoIterator,
 87    I::Item: Borrow<Self::Scalar>,
 88    J: IntoIterator,
 89    J::Item: Borrow<Self>,
 90    Self: Clone,
 91  {
 92    use curve25519_dalek::traits::VartimeMultiscalarMul;
 93    <Self as VartimeMultiscalarMul>::vartime_multiscalar_mul(
 94      scalars
 95        .into_iter()
 96        .map(|s| Scalar::decompress_scalar(s.borrow()))
 97        .collect::<Vec<ScalarBytes>>(),
 98      points,
 99    )
100  }
101}