primitives/sharing/authenticated/batched/
curve_keys.rs

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    /* === Verification === */
44
45    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
73// -------------------------
74// |   Random Generation   |
75// -------------------------
76
77impl<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
94// ------------------------------------
95// | Curve Arithmetic Implementations |
96// ------------------------------------
97
98// === Addition === //
99
100impl<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
146// === AddAssign === //
147
148impl<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
162// === Subtraction === //
163
164impl<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
212// === SubAssign === //
213
214impl<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
228// === (Scalar) Multiplication === //
229
230impl<'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
318// === MulAssign === //
319
320impl<'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}
347// === Negation === //
348
349impl<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
373// === Equality === //
374
375impl<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
382// === Type conversions === //
383
384impl<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}