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}