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