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,
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(PrimitiveError::WrongMAC(
128 serde_json::to_string(&expected_mac).unwrap(),
129 serde_json::to_string(&open_share.mac).unwrap(),
130 ))
131 }
132}
133
134impl<F: FieldExtension> Random for FieldShareKey<F> {
139 fn random(mut rng: impl CryptoRngCore) -> Self {
140 FieldShareKey {
141 alpha: GlobalFieldKey::random(&mut rng),
142 beta: FieldElement::random(&mut rng),
143 }
144 }
145}
146
147impl<F: FieldExtension> RandomWith<GlobalFieldKey<F>> for FieldShareKey<F> {
148 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalFieldKey<F>) -> Self {
149 FieldShareKey {
150 alpha,
151 beta: FieldElement::random(&mut rng),
152 }
153 }
154}
155
156#[macros::op_variants(owned, borrowed, flipped_commutative)]
163impl<F: FieldExtension> Add<&FieldShareKey<F>> for FieldShareKey<F> {
164 type Output = FieldShareKey<F>;
165
166 #[inline]
167 fn add(mut self, other: &FieldShareKey<F>) -> Self::Output {
168 assert_eq!(self.alpha, other.alpha);
169 self.beta += &other.beta;
170 self
171 }
172}
173
174#[macros::op_variants(owned)]
175impl<'a, F: FieldExtension> AddAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
176 #[inline]
177 fn add_assign(&mut self, other: &'a FieldShareKey<F>) {
178 assert_eq!(self.alpha, other.alpha);
179 self.beta += &other.beta;
180 }
181}
182
183#[macros::op_variants(owned, borrowed, flipped)]
186impl<F: FieldExtension> Sub<&FieldShareKey<F>> for FieldShareKey<F> {
187 type Output = FieldShareKey<F>;
188
189 #[inline]
190 fn sub(mut self, other: &FieldShareKey<F>) -> Self::Output {
191 assert_eq!(self.alpha, other.alpha);
192 self.beta -= other.beta;
193 self
194 }
195}
196
197#[macros::op_variants(owned)]
198impl<'a, F: FieldExtension> SubAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
199 #[inline]
200 fn sub_assign(&mut self, other: &'a FieldShareKey<F>) {
201 assert_eq!(self.alpha, other.alpha);
202 self.beta -= &other.beta;
203 }
204}
205
206#[macros::op_variants(owned, borrowed, flipped)]
209impl<'a, F: FieldExtension> Mul<&'a FieldElement<F>> for FieldShareKey<F> {
210 type Output = FieldShareKey<F>;
211
212 #[inline]
213 fn mul(mut self, other: &'a FieldElement<F>) -> Self::Output {
214 self.beta *= other;
215 self
216 }
217}
218
219#[macros::op_variants(owned, borrowed, flipped)]
220impl<'a, F: FieldExtension> Mul<&'a SubfieldElement<F>> for FieldShareKey<F> {
221 type Output = FieldShareKey<F>;
222
223 #[inline]
224 fn mul(mut self, other: &'a SubfieldElement<F>) -> Self::Output {
225 self.beta *= other;
226 self
227 }
228}
229
230#[macros::op_variants(owned)]
231impl<'a, F: FieldExtension> MulAssign<&'a FieldElement<F>> for FieldShareKey<F> {
232 #[inline]
233 fn mul_assign(&mut self, other: &'a FieldElement<F>) {
234 self.beta *= other;
235 }
236}
237
238#[macros::op_variants(owned)]
239impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for FieldShareKey<F> {
240 #[inline]
241 fn mul_assign(&mut self, other: &'a SubfieldElement<F>) {
242 self.beta *= other;
243 }
244}
245
246#[macros::op_variants(borrowed)]
249impl<F: FieldExtension> Neg for FieldShareKey<F> {
250 type Output = FieldShareKey<F>;
251
252 #[inline]
253 fn neg(self) -> Self::Output {
254 FieldShareKey {
255 alpha: self.alpha,
256 beta: -self.beta,
257 }
258 }
259}
260
261impl<F: FieldExtension> FieldShareKey<F> {
264 #[inline]
265 pub fn add_secret_owned(mut self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
266 self.beta -= constant * *self.alpha;
267 Ok(self)
268 }
269
270 #[inline]
271 pub fn add_secret(&self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
272 let mut result = self.clone();
273 result.beta -= constant * *result.alpha;
274 Ok(result)
275 }
276}
277
278impl<F: FieldExtension> ConstantTimeEq for FieldShareKey<F> {
283 #[inline]
284 fn ct_eq(&self, other: &Self) -> Choice {
285 self.alpha.ct_eq(&other.alpha) & self.beta.ct_eq(&other.beta)
286 }
287}
288
289impl<F: FieldExtension> FieldShareKey<F> {
290 #[inline]
291 pub fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
292 FieldShareKey {
293 alpha: GlobalFieldKey::conditional_select(&a.alpha, &b.alpha, choice),
294 beta: FieldElement::conditional_select(&a.beta, &b.beta, choice),
295 }
296 }
297}
298
299#[cfg(test)]
300mod tests {
301
302 use super::*;
303 use crate::algebra::elliptic_curve::{Curve25519Ristretto, ScalarAsExtension};
304
305 pub type Fq = ScalarAsExtension<Curve25519Ristretto>;
306 #[test]
307 fn test_addition() {
308 let alpha = GlobalFieldKey::new(Fq::from(3u32));
309 let key1 = FieldShareKey {
310 alpha: alpha.clone(),
311 beta: Fq::from(10u32),
312 };
313 let key2 = FieldShareKey {
314 alpha: alpha.clone(),
315 beta: Fq::from(7u32),
316 };
317 let expected_result = FieldShareKey {
318 alpha,
319 beta: Fq::from(17u32),
320 };
321 assert_eq!(key1 + key2, expected_result);
322 }
323
324 #[test]
325 fn test_subtraction() {
326 let alpha = GlobalFieldKey::new(Fq::from(3u32));
327 let key1 = FieldShareKey {
328 alpha: alpha.clone(),
329 beta: Fq::from(10u32),
330 };
331 let key2 = FieldShareKey {
332 alpha: alpha.clone(),
333 beta: Fq::from(7u32),
334 };
335 let expected_result = FieldShareKey {
336 alpha,
337 beta: Fq::from(3u32),
338 };
339 assert_eq!(key1 - key2, expected_result);
340 }
341
342 #[test]
343 fn test_multiplication() {
344 let alpha = GlobalFieldKey::new(Fq::from(3u32));
345 let key = FieldShareKey {
346 alpha: alpha.clone(),
347 beta: Fq::from(10u32),
348 };
349 let scalar = Fq::from(3u32);
350 let expected_result = FieldShareKey {
351 alpha,
352 beta: Fq::from(30u32),
353 };
354 assert_eq!(key * scalar, expected_result);
355 }
356
357 #[test]
358 fn test_negation() {
359 let key = FieldShareKey {
360 alpha: GlobalFieldKey::new(Fq::from(5u32)),
361 beta: Fq::from(10u32),
362 };
363 let expected_result = FieldShareKey {
364 alpha: GlobalFieldKey::new(Fq::from(5u32)),
365 beta: -Fq::from(10u32),
366 };
367 assert_eq!(-key, expected_result);
368 }
369}