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