Skip to main content

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,
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_else(|| {
55                PrimitiveError::WrongMAC(serde_json::to_string(open_shares.get_mac()).unwrap())
56            })
57    }
58}
59
60impl<C: Curve, M: Positive> ConditionallySelectable for CurveKeys<C, M> {
61    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
62        CurveKeys {
63            alpha: GlobalCurveKey::<C>::conditional_select(&a.alpha, &b.alpha, choice),
64            betas: CurvePoints::conditional_select(&a.betas, &b.betas, choice),
65        }
66    }
67}
68
69// -------------------------
70// |   Random Generation   |
71// -------------------------
72
73impl<C: Curve, M: Positive> Random for CurveKeys<C, M> {
74    fn random(mut rng: impl CryptoRngCore) -> Self {
75        let alpha = GlobalCurveKey::<C>::random(&mut rng);
76        let betas = CurvePoints::random(&mut rng);
77        CurveKeys { alpha, betas }
78    }
79}
80
81impl<C: Curve, M: Positive> RandomWith<GlobalCurveKey<C>> for CurveKeys<C, M> {
82    fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalCurveKey<C>) -> Self {
83        CurveKeys {
84            alpha,
85            betas: CurvePoints::random(&mut rng),
86        }
87    }
88}
89
90// ------------------------------------
91// | Curve Arithmetic Implementations |
92// ------------------------------------
93
94// === Addition === //
95
96#[macros::op_variants(owned, borrowed, flipped_commutative)]
97impl<'a, C: Curve, M: Positive> Add<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
98    type Output = CurveKeys<C, M>;
99
100    #[inline]
101    fn add(mut self, other: &'a CurveKeys<C, M>) -> Self::Output {
102        assert_eq!(self.alpha, other.alpha);
103        self.betas += &other.betas;
104        self
105    }
106}
107
108#[macros::op_variants(owned)]
109impl<'a, C: Curve, M: Positive> AddAssign<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
110    #[inline]
111    fn add_assign(&mut self, rhs: &'a CurveKeys<C, M>) {
112        assert_eq!(self.alpha, rhs.alpha);
113        self.betas += &rhs.betas;
114    }
115}
116
117// === Subtraction === //
118
119#[macros::op_variants(owned, borrowed, flipped)]
120impl<'a, C: Curve, M: Positive> Sub<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
121    type Output = CurveKeys<C, M>;
122
123    #[inline]
124    fn sub(mut self, other: &'a CurveKeys<C, M>) -> Self::Output {
125        assert_eq!(self.alpha, other.alpha);
126        self.betas -= &other.betas;
127        self
128    }
129}
130
131#[macros::op_variants(owned)]
132impl<'a, C: Curve, M: Positive> SubAssign<&'a CurveKeys<C, M>> for CurveKeys<C, M> {
133    #[inline]
134    fn sub_assign(&mut self, rhs: &'a CurveKeys<C, M>) {
135        assert_eq!(self.alpha, rhs.alpha);
136        self.betas -= &rhs.betas;
137    }
138}
139
140// === (Scalar) Multiplication === //
141
142#[macros::op_variants(owned, borrowed)]
143impl<'a, C: Curve, M: Positive> Mul<&'a ScalarAsExtension<C>> for CurveKeys<C, M> {
144    type Output = CurveKeys<C, M>;
145
146    #[inline]
147    fn mul(mut self, other: &'a ScalarAsExtension<C>) -> Self::Output {
148        self.betas *= other;
149        self
150    }
151}
152
153#[macros::op_variants(owned, borrowed)]
154impl<'a, C: Curve, M: Positive> Mul<&'a Scalar<C>> for CurveKeys<C, M> {
155    type Output = CurveKeys<C, M>;
156
157    #[inline]
158    fn mul(mut self, other: &'a Scalar<C>) -> Self::Output {
159        self.betas *= other;
160        self
161    }
162}
163
164#[macros::op_variants(owned, borrowed)]
165impl<'a, C: Curve, M: Positive> Mul<&'a ScalarsAsExtension<C, M>> for CurveKeys<C, M> {
166    type Output = CurveKeys<C, M>;
167
168    #[inline]
169    fn mul(mut self, other: &'a ScalarsAsExtension<C, M>) -> Self::Output {
170        self.betas *= other;
171        self
172    }
173}
174
175#[macros::op_variants(owned, borrowed)]
176impl<'a, C: Curve, M: Positive> Mul<&'a Scalars<C, M>> for CurveKeys<C, M> {
177    type Output = CurveKeys<C, M>;
178
179    #[inline]
180    fn mul(mut self, other: &'a Scalars<C, M>) -> Self::Output {
181        self.betas *= other;
182        self
183    }
184}
185
186// === MulAssign === //
187
188#[macros::op_variants(owned)]
189impl<'a, C: Curve, M: Positive> MulAssign<&'a ScalarAsExtension<C>> for CurveKeys<C, M> {
190    #[inline]
191    fn mul_assign(&mut self, rhs: &'a ScalarAsExtension<C>) {
192        self.betas *= rhs;
193    }
194}
195
196#[macros::op_variants(owned)]
197impl<'a, C: Curve, M: Positive> MulAssign<&'a Scalar<C>> for CurveKeys<C, M> {
198    #[inline]
199    fn mul_assign(&mut self, rhs: &'a Scalar<C>) {
200        self.betas *= rhs;
201    }
202}
203
204#[macros::op_variants(owned)]
205impl<'a, C: Curve, M: Positive> MulAssign<&'a ScalarsAsExtension<C, M>> for CurveKeys<C, M> {
206    #[inline]
207    fn mul_assign(&mut self, rhs: &'a ScalarsAsExtension<C, M>) {
208        self.betas *= rhs;
209    }
210}
211
212#[macros::op_variants(owned)]
213impl<'a, C: Curve, M: Positive> MulAssign<&'a Scalars<C, M>> for CurveKeys<C, M> {
214    #[inline]
215    fn mul_assign(&mut self, rhs: &'a Scalars<C, M>) {
216        self.betas *= rhs;
217    }
218}
219// === Negation === //
220
221#[macros::op_variants(borrowed)]
222impl<C: Curve, M: Positive> Neg for CurveKeys<C, M> {
223    type Output = CurveKeys<C, M>;
224
225    #[inline]
226    fn neg(self) -> Self::Output {
227        CurveKeys {
228            alpha: self.alpha,
229            betas: -self.betas,
230        }
231    }
232}
233
234// === Equality === //
235
236impl<C: Curve, M: Positive> ConstantTimeEq for CurveKeys<C, M> {
237    #[inline]
238    fn ct_eq(&self, other: &Self) -> Choice {
239        self.alpha.ct_eq(&other.alpha) & self.betas.ct_eq(&other.betas)
240    }
241}
242
243// === Type conversions === //
244
245impl<C: Curve, M: Positive> From<ScalarKeys<C, M>> for CurveKeys<C, M> {
246    #[inline]
247    fn from(scalar_key: ScalarKeys<C, M>) -> Self {
248        CurveKeys {
249            alpha: scalar_key.alpha,
250            betas: scalar_key.betas * Point::<C>::generator(),
251        }
252    }
253}
254
255#[cfg(test)]
256mod tests {
257    use typenum::U8;
258
259    use super::*;
260    use crate::{
261        algebra::elliptic_curve::Curve25519Ristretto as C,
262        random::{self, Random},
263    };
264    pub type FrExt = ScalarAsExtension<C>;
265    pub type Ps = CurvePoints<C, U8>;
266
267    #[test]
268    fn test_addition() {
269        let mut rng = random::test_rng();
270        let alpha = GlobalCurveKey::<C>::random(&mut rng);
271        let beta1 = Ps::random(&mut rng);
272        let beta2 = Ps::random(&mut rng);
273
274        let key1 = CurveKeys {
275            alpha: alpha.clone(),
276            betas: beta1.clone(),
277        };
278        let key2 = CurveKeys {
279            alpha: alpha.clone(),
280            betas: beta2.clone(),
281        };
282        let expected_result = CurveKeys {
283            alpha,
284            betas: beta1 + beta2,
285        };
286        assert_eq!(key1 + key2, expected_result);
287    }
288
289    #[test]
290    fn test_subtraction() {
291        let mut rng = random::test_rng();
292        let alpha = GlobalCurveKey::<C>::random(&mut rng);
293        let beta1 = Ps::random(&mut rng);
294        let beta2 = Ps::random(&mut rng);
295
296        let key1 = CurveKeys {
297            alpha: alpha.clone(),
298            betas: beta1.clone(),
299        };
300        let key2 = CurveKeys {
301            alpha: alpha.clone(),
302            betas: beta2.clone(),
303        };
304        let expected_result = CurveKeys {
305            alpha,
306            betas: beta1 - beta2,
307        };
308        assert_eq!(key1 - key2, expected_result);
309    }
310
311    #[test]
312    fn test_multiplication() {
313        let mut rng = random::test_rng();
314        let alpha = GlobalCurveKey::<C>::random(&mut rng);
315        let beta1 = Ps::random(&mut rng);
316
317        let key = CurveKeys {
318            alpha: alpha.clone(),
319            betas: beta1.clone(),
320        };
321        let scalar = FrExt::from(3u32);
322        let expected_result = CurveKeys {
323            alpha,
324            betas: beta1 * scalar,
325        };
326        assert_eq!(key * scalar, expected_result);
327    }
328
329    #[test]
330    fn test_negation() {
331        let mut rng = random::test_rng();
332        let alpha = GlobalCurveKey::<C>::random(&mut rng);
333        let beta1 = Ps::random(&mut rng);
334
335        let key = CurveKeys {
336            alpha: alpha.clone(),
337            betas: beta1.clone(),
338        };
339        let expected_result = CurveKeys {
340            alpha,
341            betas: -beta1,
342        };
343        assert_eq!(-key, expected_result);
344    }
345}