primitives/sharing/authenticated/
curve_key.rs1use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
2
3use serde::{Deserialize, Serialize};
4use subtle::{Choice, ConstantTimeEq};
5
6use super::{GlobalFieldKey, ScalarKey};
7use crate::{
8 algebra::elliptic_curve::{Curve, Point, Scalar, ScalarAsExtension, ScalarField},
9 errors::PrimitiveError,
10 random::{CryptoRngCore, Random, RandomWith},
11 sharing::OpenPointShare,
12 types::ConditionallySelectable,
13};
14
15pub type GlobalCurveKey<C> = GlobalFieldKey<ScalarField<C>>;
16
17#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(bound = "C: Curve")]
21pub struct CurveKey<C: Curve> {
22 pub(crate) alpha: GlobalCurveKey<C>,
23 pub(crate) beta: Point<C>,
24}
25
26impl<C: Curve> CurveKey<C> {
27 pub fn new(alpha: GlobalCurveKey<C>, beta: Point<C>) -> Self {
28 CurveKey { alpha, beta }
29 }
30
31 pub fn compute_mac(&self, value: &Point<C>) -> Point<C> {
32 self.beta + value * *self.alpha
33 }
34
35 #[inline]
36 pub fn verify_mac(&self, open_share: &OpenPointShare<C>) -> Result<(), PrimitiveError> {
37 let expected_mac = self.compute_mac(&open_share.value);
38 bool::from(expected_mac.ct_eq(&open_share.mac))
39 .then_some(())
40 .ok_or_else(|| {
41 PrimitiveError::WrongMAC(serde_json::to_string(&open_share.mac).unwrap())
42 })
43 }
44
45 pub fn get_alpha(&self) -> GlobalCurveKey<C> {
46 self.alpha.clone()
47 }
48
49 pub fn get_alpha_value(&self) -> ScalarAsExtension<C> {
50 *self.alpha
51 }
52
53 pub fn get_beta(&self) -> Point<C> {
54 self.beta
55 }
56
57 pub fn zero_batch(alphas: Vec<GlobalCurveKey<C>>) -> Vec<CurveKey<C>> {
58 alphas
59 .iter()
60 .map(|alpha| CurveKey::new(alpha.clone(), Point::<C>::identity()))
61 .collect()
62 }
63}
64
65impl<C: Curve> ConditionallySelectable for CurveKey<C> {
66 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
67 CurveKey {
68 alpha: GlobalCurveKey::<C>::conditional_select(&a.alpha, &b.alpha, choice),
69 beta: Point::conditional_select(&a.beta, &b.beta, choice),
70 }
71 }
72}
73
74impl<C: Curve> Random for CurveKey<C> {
79 fn random(mut rng: impl CryptoRngCore) -> Self {
80 let alpha = GlobalCurveKey::<C>::random(&mut rng);
81 let beta = Point::<C>::random(&mut rng);
82 CurveKey { alpha, beta }
83 }
84}
85
86impl<C: Curve> RandomWith<GlobalCurveKey<C>> for CurveKey<C> {
87 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalCurveKey<C>) -> Self {
88 CurveKey {
89 alpha,
90 beta: Point::random(&mut rng),
91 }
92 }
93}
94
95#[macros::op_variants(owned, borrowed, flipped_commutative)]
101impl<'a, C: Curve> Add<&'a CurveKey<C>> for CurveKey<C> {
102 type Output = CurveKey<C>;
103
104 #[inline]
105 fn add(self, other: &'a CurveKey<C>) -> Self::Output {
106 assert_eq!(self.alpha, other.alpha);
107 CurveKey {
108 beta: self.beta + other.beta,
109 ..self
110 }
111 }
112}
113
114#[macros::op_variants(owned)]
115impl<'a, C: Curve> AddAssign<&'a CurveKey<C>> for CurveKey<C> {
116 #[inline]
117 fn add_assign(&mut self, rhs: &'a CurveKey<C>) {
118 assert_eq!(self.alpha, rhs.alpha);
119 self.beta += rhs.beta;
120 }
121}
122
123#[macros::op_variants(owned, borrowed, flipped)]
126impl<'a, C: Curve> Sub<&'a CurveKey<C>> for CurveKey<C> {
127 type Output = CurveKey<C>;
128
129 #[inline]
130 fn sub(self, other: &'a CurveKey<C>) -> Self::Output {
131 assert_eq!(self.alpha, other.alpha);
132 CurveKey {
133 beta: self.beta - other.beta,
134 ..self
135 }
136 }
137}
138
139#[macros::op_variants(owned)]
142impl<'a, C: Curve> SubAssign<&'a CurveKey<C>> for CurveKey<C> {
143 #[inline]
144 fn sub_assign(&mut self, rhs: &'a CurveKey<C>) {
145 assert_eq!(self.alpha, rhs.alpha);
146 self.beta -= rhs.beta;
147 }
148}
149
150#[macros::op_variants(owned, borrowed, flipped)]
153impl<'a, C: Curve> Mul<&'a ScalarAsExtension<C>> for CurveKey<C> {
154 type Output = CurveKey<C>;
155
156 #[inline]
157 fn mul(self, other: &'a ScalarAsExtension<C>) -> Self::Output {
158 CurveKey {
159 beta: self.beta * other,
160 ..self
161 }
162 }
163}
164
165#[macros::op_variants(owned, borrowed, flipped)]
166impl<'a, C: Curve> Mul<&'a Scalar<C>> for CurveKey<C> {
167 type Output = CurveKey<C>;
168
169 #[inline]
170 fn mul(self, other: &'a Scalar<C>) -> Self::Output {
171 CurveKey {
172 beta: self.beta * other,
173 ..self
174 }
175 }
176}
177
178#[macros::op_variants(owned)]
181impl<'a, C: Curve> MulAssign<&'a ScalarAsExtension<C>> for CurveKey<C> {
182 #[inline]
183 fn mul_assign(&mut self, rhs: &'a ScalarAsExtension<C>) {
184 self.beta *= rhs;
185 }
186}
187
188#[macros::op_variants(owned)]
189impl<'a, C: Curve> MulAssign<&'a Scalar<C>> for CurveKey<C> {
190 #[inline]
191 fn mul_assign(&mut self, rhs: &'a Scalar<C>) {
192 self.beta *= rhs;
193 }
194}
195
196#[macros::op_variants(borrowed)]
199impl<C: Curve> Neg for CurveKey<C> {
200 type Output = CurveKey<C>;
201
202 #[inline]
203 fn neg(self) -> Self::Output {
204 CurveKey {
205 alpha: self.alpha,
206 beta: -self.beta,
207 }
208 }
209}
210
211impl<C: Curve> ConstantTimeEq for CurveKey<C> {
214 #[inline]
215 fn ct_eq(&self, other: &Self) -> Choice {
216 self.alpha.ct_eq(&other.alpha) & self.beta.ct_eq(&other.beta)
217 }
218}
219
220impl<C: Curve> From<ScalarKey<C>> for CurveKey<C> {
223 #[inline]
224 fn from(scalar_key: ScalarKey<C>) -> Self {
225 CurveKey {
226 alpha: scalar_key.alpha,
227 beta: scalar_key.beta * Point::<C>::generator(),
228 }
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use super::*;
235 use crate::algebra::elliptic_curve::Curve25519Ristretto as C;
236
237 pub type FrExt = ScalarAsExtension<C>;
238 pub type P = Point<C>;
239
240 #[test]
241 fn test_addition() {
242 let mut rng = rand::thread_rng();
243 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
244 let beta1 = P::random(&mut rng);
245 let beta2 = P::random(&mut rng);
246
247 let key1 = CurveKey {
248 alpha: alpha.clone(),
249 beta: beta1,
250 };
251 let key2 = CurveKey {
252 alpha: alpha.clone(),
253 beta: beta2,
254 };
255 let expected_result = CurveKey {
256 alpha,
257 beta: beta1 + beta2,
258 };
259 assert_eq!(key1 + key2, expected_result);
260 }
261
262 #[test]
263 fn test_subtraction() {
264 let mut rng = rand::thread_rng();
265 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
266 let beta1 = P::random(&mut rng);
267 let beta2 = P::random(&mut rng);
268
269 let key1 = CurveKey {
270 alpha: alpha.clone(),
271 beta: beta1,
272 };
273 let key2 = CurveKey {
274 alpha: alpha.clone(),
275 beta: beta2,
276 };
277 let expected_result = CurveKey {
278 alpha,
279 beta: beta1 - beta2,
280 };
281 assert_eq!(key1 - key2, expected_result);
282 }
283
284 #[test]
285 fn test_multiplication() {
286 let mut rng = rand::thread_rng();
287 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
288 let beta1 = P::random(&mut rng);
289
290 let key = CurveKey {
291 alpha: alpha.clone(),
292 beta: beta1,
293 };
294 let scalar = FrExt::from(3u32);
295 let expected_result = CurveKey {
296 alpha,
297 beta: beta1 * scalar,
298 };
299 assert_eq!(key * scalar, expected_result);
300 }
301
302 #[test]
303 fn test_negation() {
304 let mut rng = rand::thread_rng();
305 let alpha = GlobalCurveKey::<C>::new(FrExt::random(&mut rng));
306 let beta1 = P::random(&mut rng);
307
308 let key = CurveKey {
309 alpha: alpha.clone(),
310 beta: beta1,
311 };
312 let expected_result = CurveKey {
313 alpha,
314 beta: -beta1,
315 };
316 assert_eq!(-key, expected_result);
317 }
318}