primitives/sharing/authenticated/
field_key.rs1use 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#[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
63impl<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 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#[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>, pub(crate) beta: FieldElement<F>, }
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 #[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
137impl<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
159impl<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
211impl<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
229impl<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
279impl<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
297impl<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
387impl<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
410impl<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
436impl<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
453impl<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}