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}