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<I, J>(scalars: I, points: J) -> Self
							 | 
						|
								  where
							 | 
						|
								    I: IntoIterator,
							 | 
						|
								    I::Item: Borrow<Self::Scalar>,
							 | 
						|
								    J: IntoIterator,
							 | 
						|
								    J::Item: Borrow<Self>,
							 | 
						|
								    Self: Clone;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								impl VartimeMultiscalarMul for GroupElement {
							 | 
						|
								  type Scalar = super::scalar::Scalar;
							 | 
						|
								  fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Self
							 | 
						|
								  where
							 | 
						|
								    I: IntoIterator,
							 | 
						|
								    I::Item: Borrow<Self::Scalar>,
							 | 
						|
								    J: IntoIterator,
							 | 
						|
								    J::Item: Borrow<Self>,
							 | 
						|
								    Self: Clone,
							 | 
						|
								  {
							 | 
						|
								    use curve25519_dalek::traits::VartimeMultiscalarMul;
							 | 
						|
								    <Self as VartimeMultiscalarMul>::vartime_multiscalar_mul(
							 | 
						|
								      scalars
							 | 
						|
								        .into_iter()
							 | 
						|
								        .map(|s| Scalar::decompress_scalar(s.borrow()))
							 | 
						|
								        .collect::<Vec<ScalarBytes>>(),
							 | 
						|
								      points,
							 | 
						|
								    )
							 | 
						|
								  }
							 | 
						|
								}
							 |