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};
9use wincode::{SchemaRead, SchemaWrite};
10
11use super::OpenFieldShare;
12use crate::{
13 algebra::field::{FieldElement, FieldExtension, SubfieldElement},
14 errors::PrimitiveError,
15 random::{CryptoRngCore, Random, RandomWith},
16 types::ConditionallySelectable,
17};
18
19#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, SchemaRead, SchemaWrite)]
23#[serde(bound = "F: FieldExtension")]
24#[repr(C)]
25pub struct GlobalFieldKey<F: FieldExtension>(pub Arc<FieldElement<F>>);
26
27impl<F: FieldExtension> GlobalFieldKey<F> {
28 #[inline]
29 pub fn new(value: FieldElement<F>) -> Self {
30 GlobalFieldKey(Arc::new(value))
31 }
32}
33
34impl<F: FieldExtension> ConditionallySelectable for GlobalFieldKey<F> {
35 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
36 GlobalFieldKey(Arc::new(FieldElement::conditional_select(
37 &a.0, &b.0, choice,
38 )))
39 }
40}
41
42impl<F: FieldExtension> Deref for GlobalFieldKey<F> {
43 type Target = FieldElement<F>;
44
45 #[inline]
46 fn deref(&self) -> &Self::Target {
47 self.0.deref()
48 }
49}
50
51impl<F: FieldExtension> From<Arc<FieldElement<F>>> for GlobalFieldKey<F> {
52 #[inline]
53 fn from(value: Arc<FieldElement<F>>) -> Self {
54 GlobalFieldKey(value)
55 }
56}
57
58impl<F: FieldExtension> From<FieldElement<F>> for GlobalFieldKey<F> {
59 #[inline]
60 fn from(value: FieldElement<F>) -> Self {
61 GlobalFieldKey(Arc::new(value))
62 }
63}
64
65impl<F: FieldExtension> Distribution<GlobalFieldKey<F>> for Standard {
70 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> GlobalFieldKey<F> {
71 GlobalFieldKey::new(Standard.sample(rng))
72 }
73}
74
75impl<F: FieldExtension> RandomWith<usize> for Vec<Vec<GlobalFieldKey<F>>> {
76 fn random_with(mut rng: impl CryptoRngCore, n_parties: usize) -> Self {
78 (0..n_parties)
79 .map(|_| GlobalFieldKey::<F>::random_n(&mut rng, n_parties - 1))
80 .collect()
81 }
82}
83
84#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, SchemaRead, SchemaWrite)]
87#[serde(bound = "F: FieldExtension")]
88#[repr(C)]
89pub struct FieldShareKey<F: FieldExtension> {
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(serde_json::to_string(&open_share.mac).unwrap())
129 })
130 }
131}
132
133impl<F: FieldExtension> Random for FieldShareKey<F> {
138 fn random(mut rng: impl CryptoRngCore) -> Self {
139 FieldShareKey {
140 alpha: GlobalFieldKey::random(&mut rng),
141 beta: FieldElement::random(&mut rng),
142 }
143 }
144}
145
146impl<F: FieldExtension> RandomWith<GlobalFieldKey<F>> for FieldShareKey<F> {
147 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalFieldKey<F>) -> Self {
148 FieldShareKey {
149 alpha,
150 beta: FieldElement::random(&mut rng),
151 }
152 }
153}
154
155#[macros::op_variants(owned, borrowed, flipped_commutative)]
162impl<F: FieldExtension> Add<&FieldShareKey<F>> for FieldShareKey<F> {
163 type Output = FieldShareKey<F>;
164
165 #[inline]
166 fn add(mut self, other: &FieldShareKey<F>) -> Self::Output {
167 assert_eq!(self.alpha, other.alpha);
168 self.beta += &other.beta;
169 self
170 }
171}
172
173#[macros::op_variants(owned)]
174impl<'a, F: FieldExtension> AddAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
175 #[inline]
176 fn add_assign(&mut self, other: &'a FieldShareKey<F>) {
177 assert_eq!(self.alpha, other.alpha);
178 self.beta += &other.beta;
179 }
180}
181
182#[macros::op_variants(owned, borrowed, flipped)]
185impl<F: FieldExtension> Sub<&FieldShareKey<F>> for FieldShareKey<F> {
186 type Output = FieldShareKey<F>;
187
188 #[inline]
189 fn sub(mut self, other: &FieldShareKey<F>) -> Self::Output {
190 assert_eq!(self.alpha, other.alpha);
191 self.beta -= other.beta;
192 self
193 }
194}
195
196#[macros::op_variants(owned)]
197impl<'a, F: FieldExtension> SubAssign<&'a FieldShareKey<F>> for FieldShareKey<F> {
198 #[inline]
199 fn sub_assign(&mut self, other: &'a FieldShareKey<F>) {
200 assert_eq!(self.alpha, other.alpha);
201 self.beta -= &other.beta;
202 }
203}
204
205#[macros::op_variants(owned, borrowed, flipped)]
208impl<'a, F: FieldExtension> Mul<&'a FieldElement<F>> for FieldShareKey<F> {
209 type Output = FieldShareKey<F>;
210
211 #[inline]
212 fn mul(mut self, other: &'a FieldElement<F>) -> Self::Output {
213 self.beta *= other;
214 self
215 }
216}
217
218#[macros::op_variants(owned, borrowed, flipped)]
219impl<'a, F: FieldExtension> Mul<&'a SubfieldElement<F>> for FieldShareKey<F> {
220 type Output = FieldShareKey<F>;
221
222 #[inline]
223 fn mul(mut self, other: &'a SubfieldElement<F>) -> Self::Output {
224 self.beta *= other;
225 self
226 }
227}
228
229#[macros::op_variants(owned)]
230impl<'a, F: FieldExtension> MulAssign<&'a FieldElement<F>> for FieldShareKey<F> {
231 #[inline]
232 fn mul_assign(&mut self, other: &'a FieldElement<F>) {
233 self.beta *= other;
234 }
235}
236
237#[macros::op_variants(owned)]
238impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for FieldShareKey<F> {
239 #[inline]
240 fn mul_assign(&mut self, other: &'a SubfieldElement<F>) {
241 self.beta *= other;
242 }
243}
244
245#[macros::op_variants(borrowed)]
248impl<F: FieldExtension> Neg for FieldShareKey<F> {
249 type Output = FieldShareKey<F>;
250
251 #[inline]
252 fn neg(self) -> Self::Output {
253 FieldShareKey {
254 alpha: self.alpha,
255 beta: -self.beta,
256 }
257 }
258}
259
260impl<F: FieldExtension> FieldShareKey<F> {
263 #[inline]
264 pub fn add_secret_owned(mut self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
265 self.beta -= constant * *self.alpha;
266 Ok(self)
267 }
268
269 #[inline]
270 pub fn add_secret(&self, constant: FieldElement<F>) -> Result<Self, PrimitiveError> {
271 let mut result = self.clone();
272 result.beta -= constant * *result.alpha;
273 Ok(result)
274 }
275}
276
277impl<F: FieldExtension> ConstantTimeEq for FieldShareKey<F> {
282 #[inline]
283 fn ct_eq(&self, other: &Self) -> Choice {
284 self.alpha.ct_eq(&other.alpha) & self.beta.ct_eq(&other.beta)
285 }
286}
287
288impl<F: FieldExtension> FieldShareKey<F> {
289 #[inline]
290 pub fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
291 FieldShareKey {
292 alpha: GlobalFieldKey::conditional_select(&a.alpha, &b.alpha, choice),
293 beta: FieldElement::conditional_select(&a.beta, &b.beta, choice),
294 }
295 }
296}
297
298#[cfg(test)]
299mod tests {
300
301 use super::*;
302 use crate::algebra::elliptic_curve::{Curve25519Ristretto, ScalarAsExtension};
303
304 pub type Fq = ScalarAsExtension<Curve25519Ristretto>;
305 #[test]
306 fn test_addition() {
307 let alpha = GlobalFieldKey::new(Fq::from(3u32));
308 let key1 = FieldShareKey {
309 alpha: alpha.clone(),
310 beta: Fq::from(10u32),
311 };
312 let key2 = FieldShareKey {
313 alpha: alpha.clone(),
314 beta: Fq::from(7u32),
315 };
316 let expected_result = FieldShareKey {
317 alpha,
318 beta: Fq::from(17u32),
319 };
320 assert_eq!(key1 + key2, expected_result);
321 }
322
323 #[test]
324 fn test_subtraction() {
325 let alpha = GlobalFieldKey::new(Fq::from(3u32));
326 let key1 = FieldShareKey {
327 alpha: alpha.clone(),
328 beta: Fq::from(10u32),
329 };
330 let key2 = FieldShareKey {
331 alpha: alpha.clone(),
332 beta: Fq::from(7u32),
333 };
334 let expected_result = FieldShareKey {
335 alpha,
336 beta: Fq::from(3u32),
337 };
338 assert_eq!(key1 - key2, expected_result);
339 }
340
341 #[test]
342 fn test_multiplication() {
343 let alpha = GlobalFieldKey::new(Fq::from(3u32));
344 let key = FieldShareKey {
345 alpha: alpha.clone(),
346 beta: Fq::from(10u32),
347 };
348 let scalar = Fq::from(3u32);
349 let expected_result = FieldShareKey {
350 alpha,
351 beta: Fq::from(30u32),
352 };
353 assert_eq!(key * scalar, expected_result);
354 }
355
356 #[test]
357 fn test_negation() {
358 let key = FieldShareKey {
359 alpha: GlobalFieldKey::new(Fq::from(5u32)),
360 beta: Fq::from(10u32),
361 };
362 let expected_result = FieldShareKey {
363 alpha: GlobalFieldKey::new(Fq::from(5u32)),
364 beta: -Fq::from(10u32),
365 };
366 assert_eq!(-key, expected_result);
367 }
368}