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