primitives/sharing/authenticated/
field_key.rs

1use std::{
2    ops::{Add, AddAssign, Deref, Mul, MulAssign, Neg, Sub, SubAssign},
3    sync::Arc,
4};
5
6use rand::{distributions::Standard, prelude::Distribution, Rng};
7use serde::{Deserialize, Serialize};
8use subtle::{Choice, ConstantTimeEq};
9
10use super::OpenFieldShare;
11use crate::{
12    algebra::field::{FieldElement, FieldExtension, SubfieldElement},
13    errors::{PrimitiveError, VerificationError::InvalidMAC},
14    random::{CryptoRngCore, Random, RandomWith},
15    types::ConditionallySelectable,
16};
17
18/// α, a global authentication key for field shares. Each party holds a
19/// global key α for each peer, and uses that α to authenticate all its field shares
20/// (alongside a local key β).
21#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(bound = "F: FieldExtension")]
23pub struct GlobalFieldKey<F: FieldExtension>(pub Arc<FieldElement<F>>);
24
25impl<F: FieldExtension> GlobalFieldKey<F> {
26    #[inline]
27    pub fn new(value: FieldElement<F>) -> Self {
28        GlobalFieldKey(Arc::new(value))
29    }
30}
31
32impl<F: FieldExtension> ConditionallySelectable for GlobalFieldKey<F> {
33    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
34        GlobalFieldKey(Arc::new(FieldElement::conditional_select(
35            &a.0, &b.0, choice,
36        )))
37    }
38}
39
40impl<F: FieldExtension> Deref for GlobalFieldKey<F> {
41    type Target = FieldElement<F>;
42
43    #[inline]
44    fn deref(&self) -> &Self::Target {
45        self.0.deref()
46    }
47}
48
49impl<F: FieldExtension> From<Arc<FieldElement<F>>> for GlobalFieldKey<F> {
50    #[inline]
51    fn from(value: Arc<FieldElement<F>>) -> Self {
52        GlobalFieldKey(value)
53    }
54}
55
56impl<F: FieldExtension> From<FieldElement<F>> for GlobalFieldKey<F> {
57    #[inline]
58    fn from(value: FieldElement<F>) -> Self {
59        GlobalFieldKey(Arc::new(value))
60    }
61}
62
63// -------------------------
64// |   Random Generation   |
65// -------------------------
66
67impl<F: FieldExtension> Distribution<GlobalFieldKey<F>> for Standard {
68    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> GlobalFieldKey<F> {
69        GlobalFieldKey::new(Standard.sample(rng))
70    }
71}
72
73impl<F: FieldExtension> RandomWith<usize> for Vec<Vec<GlobalFieldKey<F>>> {
74    /// Generates `n_parties` vectors of `n_parties - 1` global keys each.
75    fn random_with(mut rng: impl CryptoRngCore, n_parties: usize) -> Self {
76        (0..n_parties)
77            .map(|_| GlobalFieldKey::<F>::random_n(&mut rng, n_parties - 1))
78            .collect()
79    }
80}
81
82// α and β, such that MAC(x) = α · x + β
83// In the context of VOLE, this corresponds to w = Δ · u + v
84#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
85#[serde(bound = "F: FieldExtension")]
86pub struct FieldShareKey<F>
87where
88    F: FieldExtension,
89{
90    pub(crate) alpha: GlobalFieldKey<F>, // α, global key
91    pub(crate) beta: FieldElement<F>,    // β, a local key per shared value.
92}
93
94impl<F: FieldExtension> FieldShareKey<F> {
95    #[inline]
96    pub fn new(alpha: GlobalFieldKey<F>, beta: FieldElement<F>) -> Self {
97        FieldShareKey { alpha, beta }
98    }
99
100    #[inline]
101    pub fn get_alpha(&self) -> GlobalFieldKey<F> {
102        self.alpha.clone()
103    }
104
105    #[inline]
106    pub fn get_alpha_value(&self) -> FieldElement<F> {
107        *self.alpha
108    }
109
110    #[inline]
111    pub fn get_beta(&self) -> &FieldElement<F> {
112        &self.beta
113    }
114
115    /* === Verification === */
116
117    #[inline]
118    pub fn compute_mac(&self, value: &SubfieldElement<F>) -> FieldElement<F> {
119        self.beta + *self.alpha * value
120    }
121
122    #[inline]
123    pub fn verify_mac(&self, open_share: &OpenFieldShare<F>) -> Result<(), PrimitiveError> {
124        let expected_mac = self.compute_mac(&open_share.value);
125        bool::from(FieldElement::ct_eq(&expected_mac, &open_share.mac))
126            .then_some(())
127            .ok_or(
128                InvalidMAC(
129                    serde_json::to_string(&expected_mac).unwrap(),
130                    serde_json::to_string(&open_share.mac).unwrap(),
131                )
132                .into(),
133            )
134    }
135}
136
137// -------------------------
138// |   Random Generation   |
139// -------------------------
140
141impl<F: FieldExtension> Random for FieldShareKey<F> {
142    fn random(mut rng: impl CryptoRngCore) -> Self {
143        FieldShareKey {
144            alpha: GlobalFieldKey::random(&mut rng),
145            beta: FieldElement::random(&mut rng),
146        }
147    }
148}
149
150impl<F: FieldExtension> RandomWith<GlobalFieldKey<F>> for FieldShareKey<F> {
151    fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalFieldKey<F>) -> Self {
152        FieldShareKey {
153            alpha,
154            beta: FieldElement::random(&mut rng),
155        }
156    }
157}
158
159// --------------
160// | Arithmetic |
161// --------------
162
163// === Addition === //
164
165impl<F: FieldExtension> Add for FieldShareKey<F> {
166    type Output = FieldShareKey<F>;
167
168    #[inline]
169    fn add(mut self, other: FieldShareKey<F>) -> Self::Output {
170        assert_eq!(self.alpha, other.alpha);
171        self.beta += other.beta;
172        self
173    }
174}
175
176impl<F: FieldExtension> Add for &FieldShareKey<F> {
177    type Output = FieldShareKey<F>;
178
179    #[inline]
180    fn add(self, other: &FieldShareKey<F>) -> Self::Output {
181        assert_eq!(self.alpha, other.alpha);
182        FieldShareKey {
183            alpha: self.alpha.clone(),
184            beta: self.beta + other.beta,
185        }
186    }
187}
188
189impl<F: FieldExtension> Add<&FieldShareKey<F>> for FieldShareKey<F> {
190    type Output = FieldShareKey<F>;
191
192    #[inline]
193    fn add(mut self, other: &FieldShareKey<F>) -> Self::Output {
194        assert_eq!(self.alpha, other.alpha);
195        self.beta += &other.beta;
196        self
197    }
198}
199
200impl<F: FieldExtension> Add<FieldShareKey<F>> for &FieldShareKey<F> {
201    type Output = FieldShareKey<F>;
202
203    #[inline]
204    fn add(self, mut other: FieldShareKey<F>) -> Self::Output {
205        assert_eq!(self.alpha, other.alpha);
206        other.beta += &self.beta;
207        other
208    }
209}
210
211// === AddAssign === //
212
213impl<F: FieldExtension> AddAssign for FieldShareKey<F> {
214    #[inline]
215    fn add_assign(&mut self, other: Self) {
216        assert_eq!(self.alpha, other.alpha);
217        self.beta += other.beta;
218    }
219}
220
221impl<'a, F: FieldExtension> AddAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
222    #[inline]
223    fn add_assign(&mut self, other: &'a FieldShareKey<F>) {
224        assert_eq!(self.alpha, other.alpha);
225        self.beta += &other.beta;
226    }
227}
228
229// === Subtraction === //
230
231impl<F: FieldExtension> Sub for FieldShareKey<F> {
232    type Output = FieldShareKey<F>;
233
234    #[inline]
235    fn sub(mut self, other: FieldShareKey<F>) -> Self::Output {
236        assert_eq!(self.alpha, other.alpha);
237        self.beta -= other.beta;
238        self
239    }
240}
241
242impl<F: FieldExtension> Sub for &FieldShareKey<F> {
243    type Output = FieldShareKey<F>;
244
245    #[inline]
246    fn sub(self, other: &FieldShareKey<F>) -> Self::Output {
247        assert_eq!(self.alpha, other.alpha);
248        FieldShareKey {
249            alpha: self.alpha.clone(),
250            beta: self.beta - other.beta,
251        }
252    }
253}
254
255impl<F: FieldExtension> Sub<&FieldShareKey<F>> for FieldShareKey<F> {
256    type Output = FieldShareKey<F>;
257
258    #[inline]
259    fn sub(mut self, other: &FieldShareKey<F>) -> Self::Output {
260        assert_eq!(self.alpha, other.alpha);
261        self.beta -= other.beta;
262        self
263    }
264}
265
266impl<F: FieldExtension> Sub<FieldShareKey<F>> for &FieldShareKey<F> {
267    type Output = FieldShareKey<F>;
268
269    #[inline]
270    fn sub(self, other: FieldShareKey<F>) -> Self::Output {
271        assert_eq!(self.alpha, other.alpha);
272        FieldShareKey {
273            alpha: self.alpha.clone(),
274            beta: self.beta - other.beta,
275        }
276    }
277}
278
279// === SubAssign === //
280
281impl<F: FieldExtension> SubAssign for FieldShareKey<F> {
282    #[inline]
283    fn sub_assign(&mut self, other: Self) {
284        assert_eq!(self.alpha, other.alpha);
285        self.beta -= other.beta;
286    }
287}
288
289impl<'a, F: FieldExtension> SubAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
290    #[inline]
291    fn sub_assign(&mut self, other: &'a FieldShareKey<F>) {
292        assert_eq!(self.alpha, other.alpha);
293        self.beta -= &other.beta;
294    }
295}
296
297// === One-to-many multiplication === //
298
299impl<F: FieldExtension> Mul<FieldElement<F>> for FieldShareKey<F> {
300    type Output = FieldShareKey<F>;
301
302    #[inline]
303    fn mul(mut self, other: FieldElement<F>) -> Self::Output {
304        self.beta *= other;
305        self
306    }
307}
308
309impl<'a, F: FieldExtension> Mul<&'a FieldElement<F>> for FieldShareKey<F> {
310    type Output = FieldShareKey<F>;
311
312    #[inline]
313    fn mul(mut self, other: &'a FieldElement<F>) -> Self::Output {
314        self.beta *= other;
315        self
316    }
317}
318
319impl<F: FieldExtension> Mul<FieldElement<F>> for &FieldShareKey<F> {
320    type Output = FieldShareKey<F>;
321
322    #[inline]
323    fn mul(self, other: FieldElement<F>) -> Self::Output {
324        FieldShareKey {
325            alpha: self.alpha.clone(),
326            beta: self.beta * other,
327        }
328    }
329}
330
331impl<'a, F: FieldExtension> Mul<&'a FieldElement<F>> for &'a FieldShareKey<F> {
332    type Output = FieldShareKey<F>;
333
334    #[inline]
335    fn mul(self, other: &'a FieldElement<F>) -> Self::Output {
336        FieldShareKey {
337            alpha: self.alpha.clone(),
338            beta: self.beta * other,
339        }
340    }
341}
342
343impl<F: FieldExtension> Mul<SubfieldElement<F>> for FieldShareKey<F> {
344    type Output = FieldShareKey<F>;
345
346    #[inline]
347    fn mul(mut self, other: SubfieldElement<F>) -> Self::Output {
348        self.beta *= other;
349        self
350    }
351}
352
353impl<'a, F: FieldExtension> Mul<&'a SubfieldElement<F>> for FieldShareKey<F> {
354    type Output = FieldShareKey<F>;
355
356    #[inline]
357    fn mul(mut self, other: &'a SubfieldElement<F>) -> Self::Output {
358        self.beta *= other;
359        self
360    }
361}
362
363impl<F: FieldExtension> Mul<SubfieldElement<F>> for &FieldShareKey<F> {
364    type Output = FieldShareKey<F>;
365
366    #[inline]
367    fn mul(self, other: SubfieldElement<F>) -> Self::Output {
368        FieldShareKey {
369            alpha: self.alpha.clone(),
370            beta: self.beta * other,
371        }
372    }
373}
374
375impl<'a, F: FieldExtension> Mul<&'a SubfieldElement<F>> for &'a FieldShareKey<F> {
376    type Output = FieldShareKey<F>;
377
378    #[inline]
379    fn mul(self, other: &'a SubfieldElement<F>) -> Self::Output {
380        FieldShareKey {
381            alpha: self.alpha.clone(),
382            beta: self.beta * other,
383        }
384    }
385}
386
387// === MulAssign === //
388
389impl<F: FieldExtension> MulAssign for FieldShareKey<F> {
390    #[inline]
391    fn mul_assign(&mut self, other: Self) {
392        self.beta *= other.beta;
393    }
394}
395
396impl<'a, F: FieldExtension> MulAssign<&'a FieldElement<F>> for FieldShareKey<F> {
397    #[inline]
398    fn mul_assign(&mut self, other: &'a FieldElement<F>) {
399        self.beta *= other;
400    }
401}
402
403impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for FieldShareKey<F> {
404    #[inline]
405    fn mul_assign(&mut self, other: &'a SubfieldElement<F>) {
406        self.beta *= other;
407    }
408}
409
410// === Negation === //
411
412impl<F: FieldExtension> Neg for FieldShareKey<F> {
413    type Output = FieldShareKey<F>;
414
415    #[inline]
416    fn neg(self) -> Self::Output {
417        FieldShareKey {
418            alpha: self.alpha,
419            beta: -self.beta,
420        }
421    }
422}
423
424impl<F: FieldExtension> Neg for &FieldShareKey<F> {
425    type Output = FieldShareKey<F>;
426
427    #[inline]
428    fn neg(self) -> Self::Output {
429        FieldShareKey {
430            alpha: self.alpha.clone(),
431            beta: -self.beta,
432        }
433    }
434}
435
436// === Constant Addition === //
437
438impl<F: FieldExtension> FieldShareKey<F> {
439    #[inline]
440    pub fn add_secret_owned(mut self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
441        self.beta -= constant * *self.alpha;
442        Ok(self)
443    }
444
445    #[inline]
446    pub fn add_secret(&self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
447        let mut result = self.clone();
448        result.beta -= constant * *result.alpha;
449        Ok(result)
450    }
451}
452
453// ---------------------------------------
454// |  Constant time Selection / Equality |
455// ---------------------------------------
456
457impl<F: FieldExtension> ConstantTimeEq for FieldShareKey<F> {
458    #[inline]
459    fn ct_eq(&self, other: &Self) -> Choice {
460        self.alpha.ct_eq(&other.alpha) & self.beta.ct_eq(&other.beta)
461    }
462}
463
464impl<F: FieldExtension> FieldShareKey<F> {
465    #[inline]
466    pub fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
467        FieldShareKey {
468            alpha: GlobalFieldKey::conditional_select(&a.alpha, &b.alpha, choice),
469            beta: FieldElement::conditional_select(&a.beta, &b.beta, choice),
470        }
471    }
472}
473
474#[cfg(test)]
475mod tests {
476
477    use super::*;
478    use crate::algebra::elliptic_curve::{Curve25519Ristretto, ScalarAsExtension};
479
480    pub type Fq = ScalarAsExtension<Curve25519Ristretto>;
481    #[test]
482    fn test_addition() {
483        let alpha = GlobalFieldKey::new(Fq::from(3u32));
484        let key1 = FieldShareKey {
485            alpha: alpha.clone(),
486            beta: Fq::from(10u32),
487        };
488        let key2 = FieldShareKey {
489            alpha: alpha.clone(),
490            beta: Fq::from(7u32),
491        };
492        let expected_result = FieldShareKey {
493            alpha,
494            beta: Fq::from(17u32),
495        };
496        assert_eq!(key1 + key2, expected_result);
497    }
498
499    #[test]
500    fn test_subtraction() {
501        let alpha = GlobalFieldKey::new(Fq::from(3u32));
502        let key1 = FieldShareKey {
503            alpha: alpha.clone(),
504            beta: Fq::from(10u32),
505        };
506        let key2 = FieldShareKey {
507            alpha: alpha.clone(),
508            beta: Fq::from(7u32),
509        };
510        let expected_result = FieldShareKey {
511            alpha,
512            beta: Fq::from(3u32),
513        };
514        assert_eq!(key1 - key2, expected_result);
515    }
516
517    #[test]
518    fn test_multiplication() {
519        let alpha = GlobalFieldKey::new(Fq::from(3u32));
520        let key = FieldShareKey {
521            alpha: alpha.clone(),
522            beta: Fq::from(10u32),
523        };
524        let scalar = Fq::from(3u32);
525        let expected_result = FieldShareKey {
526            alpha,
527            beta: Fq::from(30u32),
528        };
529        assert_eq!(key * scalar, expected_result);
530    }
531
532    #[test]
533    fn test_negation() {
534        let key = FieldShareKey {
535            alpha: GlobalFieldKey::new(Fq::from(5u32)),
536            beta: Fq::from(10u32),
537        };
538        let expected_result = FieldShareKey {
539            alpha: GlobalFieldKey::new(Fq::from(5u32)),
540            beta: -Fq::from(10u32),
541        };
542        assert_eq!(-key, expected_result);
543    }
544}