1use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
2
3use serde::{Deserialize, Serialize};
4use subtle::{Choice, ConstantTimeEq};
5
6use super::{OpenPointShares, ScalarKeys};
7use crate::{
8 algebra::elliptic_curve::{Curve, Point, Scalar, ScalarAsExtension},
9 errors::{PrimitiveError, VerificationError},
10 random::{CryptoRngCore, Random, RandomWith},
11 sharing::GlobalCurveKey,
12 types::{
13 heap_array::curve_arrays::{CurvePoints, Scalars, ScalarsAsExtension},
14 ConditionallySelectable,
15 Positive,
16 },
17};
18
19#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(bound = "C: Curve, M: Positive")]
21pub struct CurveKeys<C: Curve, M: Positive> {
22 pub(crate) alpha: GlobalCurveKey<C>,
23 pub(crate) betas: CurvePoints<C, M>,
24}
25
26impl<C: Curve, M: Positive> CurveKeys<C, M> {
27 pub fn new(alpha: GlobalCurveKey<C>, betas: CurvePoints<C, M>) -> Self {
28 CurveKeys { alpha, betas }
29 }
30
31 pub fn get_alpha(&self) -> GlobalCurveKey<C> {
32 self.alpha.clone()
33 }
34
35 pub fn get_alpha_value(&self) -> ScalarAsExtension<C> {
36 *self.alpha
37 }
38
39 pub fn get_betas(&self) -> &CurvePoints<C, M> {
40 &self.betas
41 }
42
43 pub fn compute_mac(&self, values: &CurvePoints<C, M>) -> CurvePoints<C, M> {
46 values * *self.alpha + &self.betas
47 }
48
49 #[inline]
50 pub fn verify_mac(&self, open_shares: &OpenPointShares<C, M>) -> Result<(), PrimitiveError> {
51 let computed_macs = self.compute_mac(open_shares.get_value());
52 bool::from(computed_macs.ct_eq(open_shares.get_mac()))
53 .then_some(())
54 .ok_or(
55 VerificationError::InvalidMAC(
56 serde_json::to_string(&computed_macs).unwrap(),
57 serde_json::to_string(open_shares.get_mac()).unwrap(),
58 )
59 .into(),
60 )
61 }
62}
63
64impl<C: Curve, M: Positive> ConditionallySelectable for CurveKeys<C, M> {
65 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
66 CurveKeys {
67 alpha: GlobalCurveKey::<C>::conditional_select(&a.alpha, &b.alpha, choice),
68 betas: CurvePoints::conditional_select(&a.betas, &b.betas, choice),
69 }
70 }
71}
72
73impl<C: Curve, M: Positive> Random for CurveKeys<C, M> {
78 fn random(mut rng: impl CryptoRngCore) -> Self {
79 let alpha = GlobalCurveKey::<C>::random(&mut rng);
80 let betas = CurvePoints::random(&mut rng);
81 CurveKeys { alpha, betas }
82 }
83}
84
85impl<C: Curve, M: Positive> RandomWith<GlobalCurveKey<C>> for CurveKeys<C, M> {
86 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalCurveKey<C>) -> Self {
87 CurveKeys {
88 alpha,
89 betas: CurvePoints::random(&mut rng),
90 }
91 }
92}
93
94impl<C: Curve, M: Positive> Add for CurveKeys<C, M> {
101 type Output = CurveKeys<C, M>;
102
103 #[inline]
104 fn add(mut self, other: Self) -> Self::Output {
105 debug_assert_eq!(self.alpha, other.alpha);
106 self.betas += other.betas;
107 self
108 }
109}
110
111impl<C: Curve, M: Positive> Add for &CurveKeys<C, M> {
112 type Output = CurveKeys<C, M>;
113
114 #[inline]
115 fn add(self, other: Self) -> Self::Output {
116 debug_assert_eq!(self.alpha, other.alpha);
117 CurveKeys {
118 alpha: self.alpha.clone(),
119 betas: &self.betas + &other.betas,
120 }
121 }
122}
123
124impl<C: Curve, M: Positive> Add<CurveKeys<C, M>> for &CurveKeys<C, M> {
125 type Output = CurveKeys<C, M>;
126
127 #[inline]
128 fn add(self, mut other: CurveKeys<C, M>) -> Self::Output {
129 debug_assert_eq!(self.alpha, other.alpha);
130 other.betas += &self.betas;
131 other
132 }
133}
134
135impl<'a, C: Curve, M: Positive> Add<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
136 type Output = CurveKeys<C, M>;
137
138 #[inline]
139 fn add(mut self, other: &'a CurveKeys<C, M>) -> Self::Output {
140 debug_assert_eq!(self.alpha, other.alpha);
141 self.betas += &other.betas;
142 self
143 }
144}
145
146impl<C: Curve, M: Positive> AddAssign for CurveKeys<C, M> {
149 #[inline]
150 fn add_assign(&mut self, rhs: Self) {
151 self.betas += rhs.betas;
152 }
153}
154
155impl<'a, C: Curve, M: Positive> AddAssign<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
156 #[inline]
157 fn add_assign(&mut self, rhs: &'a CurveKeys<C, M>) {
158 self.betas += &rhs.betas;
159 }
160}
161
162impl<C: Curve, M: Positive> Sub for CurveKeys<C, M> {
165 type Output = CurveKeys<C, M>;
166
167 #[inline]
168 fn sub(mut self, other: Self) -> Self::Output {
169 debug_assert_eq!(self.alpha, other.alpha);
170 self.betas -= other.betas;
171 self
172 }
173}
174
175impl<C: Curve, M: Positive> Sub for &CurveKeys<C, M> {
176 type Output = CurveKeys<C, M>;
177
178 #[inline]
179 fn sub(self, other: Self) -> Self::Output {
180 debug_assert_eq!(self.alpha, other.alpha);
181 CurveKeys {
182 alpha: self.alpha.clone(),
183 betas: &self.betas - &other.betas,
184 }
185 }
186}
187
188impl<C: Curve, M: Positive> Sub<CurveKeys<C, M>> for &CurveKeys<C, M> {
189 type Output = CurveKeys<C, M>;
190
191 #[inline]
192 fn sub(self, other: CurveKeys<C, M>) -> Self::Output {
193 debug_assert_eq!(self.alpha, other.alpha);
194 CurveKeys {
195 betas: &self.betas - other.betas,
196 ..other
197 }
198 }
199}
200
201impl<'a, C: Curve, M: Positive> Sub<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
202 type Output = CurveKeys<C, M>;
203
204 #[inline]
205 fn sub(mut self, other: &'a CurveKeys<C, M>) -> Self::Output {
206 debug_assert_eq!(self.alpha, other.alpha);
207 self.betas -= &other.betas;
208 self
209 }
210}
211
212impl<C: Curve, M: Positive> SubAssign for CurveKeys<C, M> {
215 #[inline]
216 fn sub_assign(&mut self, rhs: Self) {
217 self.betas -= rhs.betas;
218 }
219}
220
221impl<'a, C: Curve, M: Positive> SubAssign<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
222 #[inline]
223 fn sub_assign(&mut self, rhs: &'a CurveKeys<C, M>) {
224 self.betas -= &rhs.betas;
225 }
226}
227
228impl<'a, C: Curve, M: Positive> Mul<&'a ScalarAsExtension<C>> for &'a CurveKeys<C, M> {
231 type Output = CurveKeys<C, M>;
232
233 #[inline]
234 fn mul(self, other: &'a ScalarAsExtension<C>) -> Self::Output {
235 CurveKeys {
236 alpha: self.alpha.clone(),
237 betas: &self.betas * other,
238 }
239 }
240}
241
242impl<'a, C: Curve, M: Positive> Mul<&'a ScalarAsExtension<C>> for CurveKeys<C, M> {
243 type Output = CurveKeys<C, M>;
244
245 #[inline]
246 fn mul(mut self, other: &'a ScalarAsExtension<C>) -> Self::Output {
247 self.betas *= other;
248 self
249 }
250}
251
252impl<'a, C: Curve, M: Positive> Mul<&'a Scalar<C>> for &'a CurveKeys<C, M> {
253 type Output = CurveKeys<C, M>;
254
255 #[inline]
256 fn mul(self, other: &'a Scalar<C>) -> Self::Output {
257 CurveKeys {
258 alpha: self.alpha.clone(),
259 betas: &self.betas * other,
260 }
261 }
262}
263
264impl<'a, C: Curve, M: Positive> Mul<&'a Scalar<C>> for CurveKeys<C, M> {
265 type Output = CurveKeys<C, M>;
266
267 #[inline]
268 fn mul(mut self, other: &'a Scalar<C>) -> Self::Output {
269 self.betas *= other;
270 self
271 }
272}
273
274impl<'a, C: Curve, M: Positive> Mul<&'a ScalarsAsExtension<C, M>> for &'a CurveKeys<C, M> {
275 type Output = CurveKeys<C, M>;
276
277 #[inline]
278 fn mul(self, other: &'a ScalarsAsExtension<C, M>) -> Self::Output {
279 CurveKeys {
280 alpha: self.alpha.clone(),
281 betas: &self.betas * other,
282 }
283 }
284}
285
286impl<'a, C: Curve, M: Positive> Mul<&'a ScalarsAsExtension<C, M>> for CurveKeys<C, M> {
287 type Output = CurveKeys<C, M>;
288
289 #[inline]
290 fn mul(mut self, other: &'a ScalarsAsExtension<C, M>) -> Self::Output {
291 self.betas *= other;
292 self
293 }
294}
295
296impl<'a, C: Curve, M: Positive> Mul<&'a Scalars<C, M>> for &'a CurveKeys<C, M> {
297 type Output = CurveKeys<C, M>;
298
299 #[inline]
300 fn mul(self, other: &'a Scalars<C, M>) -> Self::Output {
301 CurveKeys {
302 alpha: self.alpha.clone(),
303 betas: &self.betas * other,
304 }
305 }
306}
307
308impl<'a, C: Curve, M: Positive> Mul<&'a Scalars<C, M>> for CurveKeys<C, M> {
309 type Output = CurveKeys<C, M>;
310
311 #[inline]
312 fn mul(mut self, other: &'a Scalars<C, M>) -> Self::Output {
313 self.betas *= other;
314 self
315 }
316}
317
318impl<'a, C: Curve, M: Positive> MulAssign<&'a ScalarAsExtension<C>> for CurveKeys<C, M> {
321 #[inline]
322 fn mul_assign(&mut self, rhs: &'a ScalarAsExtension<C>) {
323 self.betas *= rhs;
324 }
325}
326
327impl<'a, C: Curve, M: Positive> MulAssign<&'a Scalar<C>> for CurveKeys<C, M> {
328 #[inline]
329 fn mul_assign(&mut self, rhs: &'a Scalar<C>) {
330 self.betas *= rhs;
331 }
332}
333
334impl<'a, C: Curve, M: Positive> MulAssign<&'a ScalarsAsExtension<C, M>> for CurveKeys<C, M> {
335 #[inline]
336 fn mul_assign(&mut self, rhs: &'a ScalarsAsExtension<C, M>) {
337 self.betas *= rhs;
338 }
339}
340
341impl<'a, C: Curve, M: Positive> MulAssign<&'a Scalars<C, M>> for CurveKeys<C, M> {
342 #[inline]
343 fn mul_assign(&mut self, rhs: &'a Scalars<C, M>) {
344 self.betas *= rhs;
345 }
346}
347impl<C: Curve, M: Positive> Neg for CurveKeys<C, M> {
350 type Output = Self;
351
352 #[inline]
353 fn neg(self) -> Self::Output {
354 CurveKeys {
355 alpha: self.alpha,
356 betas: -self.betas,
357 }
358 }
359}
360
361impl<C: Curve, M: Positive> Neg for &CurveKeys<C, M> {
362 type Output = CurveKeys<C, M>;
363
364 #[inline]
365 fn neg(self) -> Self::Output {
366 CurveKeys {
367 alpha: self.alpha.clone(),
368 betas: -&self.betas,
369 }
370 }
371}
372
373impl<C: Curve, M: Positive> ConstantTimeEq for CurveKeys<C, M> {
376 #[inline]
377 fn ct_eq(&self, other: &Self) -> Choice {
378 self.alpha.ct_eq(&other.alpha) & self.betas.ct_eq(&other.betas)
379 }
380}
381
382impl<C: Curve, M: Positive> From<ScalarKeys<C, M>> for CurveKeys<C, M> {
385 #[inline]
386 fn from(scalar_key: ScalarKeys<C, M>) -> Self {
387 CurveKeys {
388 alpha: scalar_key.alpha,
389 betas: scalar_key.betas * Point::<C>::generator(),
390 }
391 }
392}
393
394#[cfg(test)]
395mod tests {
396 use typenum::U8;
397
398 use super::*;
399 use crate::{
400 algebra::elliptic_curve::Curve25519Ristretto as C,
401 random::{self, Random},
402 };
403 pub type FrExt = ScalarAsExtension<C>;
404 pub type Ps = CurvePoints<C, U8>;
405
406 #[test]
407 fn test_addition() {
408 let mut rng = random::test_rng();
409 let alpha = GlobalCurveKey::<C>::random(&mut rng);
410 let beta1 = Ps::random(&mut rng);
411 let beta2 = Ps::random(&mut rng);
412
413 let key1 = CurveKeys {
414 alpha: alpha.clone(),
415 betas: beta1.clone(),
416 };
417 let key2 = CurveKeys {
418 alpha: alpha.clone(),
419 betas: beta2.clone(),
420 };
421 let expected_result = CurveKeys {
422 alpha,
423 betas: beta1 + beta2,
424 };
425 assert_eq!(key1 + key2, expected_result);
426 }
427
428 #[test]
429 fn test_subtraction() {
430 let mut rng = random::test_rng();
431 let alpha = GlobalCurveKey::<C>::random(&mut rng);
432 let beta1 = Ps::random(&mut rng);
433 let beta2 = Ps::random(&mut rng);
434
435 let key1 = CurveKeys {
436 alpha: alpha.clone(),
437 betas: beta1.clone(),
438 };
439 let key2 = CurveKeys {
440 alpha: alpha.clone(),
441 betas: beta2.clone(),
442 };
443 let expected_result = CurveKeys {
444 alpha,
445 betas: beta1 - beta2,
446 };
447 assert_eq!(key1 - key2, expected_result);
448 }
449
450 #[test]
451 fn test_multiplication() {
452 let mut rng = random::test_rng();
453 let alpha = GlobalCurveKey::<C>::random(&mut rng);
454 let beta1 = Ps::random(&mut rng);
455
456 let key = CurveKeys {
457 alpha: alpha.clone(),
458 betas: beta1.clone(),
459 };
460 let scalar = FrExt::from(3u32);
461 let expected_result = CurveKeys {
462 alpha,
463 betas: beta1 * scalar,
464 };
465 assert_eq!(key * &scalar, expected_result);
466 }
467
468 #[test]
469 fn test_negation() {
470 let mut rng = random::test_rng();
471 let alpha = GlobalCurveKey::<C>::random(&mut rng);
472 let beta1 = Ps::random(&mut rng);
473
474 let key = CurveKeys {
475 alpha: alpha.clone(),
476 betas: beta1.clone(),
477 };
478 let expected_result = CurveKeys {
479 alpha,
480 betas: -beta1,
481 };
482 assert_eq!(-key, expected_result);
483 }
484}