primitives/algebra/field/
subfield_element.rs1use std::{
2 fmt::{Display, Formatter, Result as FmtResult},
3 iter::{Product, Sum},
4 ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign},
5};
6
7use ff::Field;
8use hybrid_array::Array;
9use num_traits::{One, Zero};
10use rand::RngCore;
11use serde::{Deserialize, Serialize};
12use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
13
14use crate::{
15 algebra::{
16 field::{binary::Gf2_128, ByteSize, FieldElement, FieldExtension, PrimeFieldExtension},
17 ops::{AccReduce, DefaultDotProduct, IntoWide, MulAccReduce, ReduceWide},
18 uniform_bytes::FromUniformBytes,
19 },
20 errors::SerializationError,
21 impl_borrow_variants,
22 random::{CryptoRngCore, Random},
23 sharing::unauthenticated::AdditiveShares,
24};
25
26pub type Bit = SubfieldElement<Gf2_128>;
27
28#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
30pub struct SubfieldElement<F: FieldExtension>(pub(crate) F::Subfield);
31
32impl<F: FieldExtension> SubfieldElement<F> {
33 #[inline]
35 pub fn new(inner: F::Subfield) -> Self {
36 SubfieldElement(inner)
37 }
38
39 #[inline]
41 pub fn inner(&self) -> F::Subfield {
42 self.0
43 }
44
45 #[inline]
47 pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
48 SubfieldElement::new(self.0.pow(exp))
49 }
50
51 #[inline]
53 pub fn from_be_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, SerializationError> {
54 let bytes = bytes.iter().rev().copied().collect::<Vec<_>>();
55 Ok(SubfieldElement(
56 F::Subfield::from_le_bytes(&bytes).ok_or(SerializationError::DeserializationFailed)?,
57 ))
58 }
59
60 #[inline]
61 pub fn from_le_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, SerializationError> {
62 Ok(SubfieldElement(
63 F::Subfield::from_le_bytes(bytes).ok_or(SerializationError::DeserializationFailed)?,
64 ))
65 }
66
67 #[inline]
69 pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> + '_ {
70 self.0.to_le_bytes()
71 }
72
73 #[inline]
75 pub fn to_be_bytes(&self) -> impl IntoIterator<Item = u8> {
76 self.0
77 .to_le_bytes()
78 .into_iter()
79 .collect::<Vec<_>>()
80 .into_iter()
81 .rev()
82 .collect::<Vec<_>>()
83 }
84
85 pub fn to_biguint(&self) -> num_bigint::BigUint {
86 num_bigint::BigUint::from_bytes_le(
87 self.to_le_bytes().into_iter().collect::<Vec<_>>().as_ref(),
88 )
89 }
90}
91
92impl<F: FieldExtension> Random for SubfieldElement<F> {
93 fn random(mut rng: impl CryptoRngCore) -> Self {
94 SubfieldElement(F::Subfield::random(&mut rng))
95 }
96}
97
98impl<F: FieldExtension> Default for SubfieldElement<F> {
99 fn default() -> Self {
100 Self::zero()
101 }
102}
103
104impl<F: FieldExtension> Serialize for SubfieldElement<F> {
105 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
106 let bytes = self
107 .to_le_bytes()
108 .into_iter()
109 .collect::<Array<u8, ByteSize<F::Subfield>>>();
110 serde_bytes::serialize(AsRef::<[u8]>::as_ref(&bytes), serializer)
111 }
112}
113
114impl<'de, F: FieldExtension> Deserialize<'de> for SubfieldElement<F> {
115 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
116 let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
117 let field_elem = SubfieldElement::from_le_bytes(bytes).map_err(|err| {
118 serde::de::Error::custom(format!("Failed to deserialize field element: {err:?}"))
119 })?;
120 Ok(field_elem)
121 }
122}
123
124impl<F: FieldExtension> Display for SubfieldElement<F> {
125 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
126 write!(f, "{self:?}")
127 }
128}
129
130impl<F: FieldExtension> Add<&SubfieldElement<F>> for &SubfieldElement<F> {
137 type Output = SubfieldElement<F>;
138
139 #[inline]
140 fn add(self, rhs: &SubfieldElement<F>) -> Self::Output {
141 SubfieldElement(self.0 + rhs.0)
142 }
143}
144
145impl_borrow_variants!(SubfieldElement<F>, Add, add, +, SubfieldElement<F>, F: FieldExtension);
146
147impl<F: FieldExtension> AddAssign for SubfieldElement<F> {
150 #[inline]
151 fn add_assign(&mut self, rhs: SubfieldElement<F>) {
152 *self = *self + rhs;
153 }
154}
155
156impl<'a, F: FieldExtension> AddAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
157 #[inline]
158 fn add_assign(&mut self, rhs: &'a SubfieldElement<F>) {
159 *self = *self + rhs;
160 }
161}
162
163impl<F: FieldExtension> Sub<&SubfieldElement<F>> for &SubfieldElement<F> {
166 type Output = SubfieldElement<F>;
167
168 #[inline]
169 fn sub(self, rhs: &SubfieldElement<F>) -> Self::Output {
170 SubfieldElement(self.0 - rhs.0)
171 }
172}
173impl_borrow_variants!(SubfieldElement<F>, Sub, sub, -, SubfieldElement<F>, F: FieldExtension);
174
175impl<F: FieldExtension> SubAssign for SubfieldElement<F> {
178 #[inline]
179 fn sub_assign(&mut self, rhs: SubfieldElement<F>) {
180 *self = *self - rhs;
181 }
182}
183
184impl<'a, F: FieldExtension> SubAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
185 #[inline]
186 fn sub_assign(&mut self, rhs: &'a SubfieldElement<F>) {
187 *self = *self - rhs;
188 }
189}
190
191impl<F: FieldExtension> Mul<&SubfieldElement<F>> for &SubfieldElement<F> {
194 type Output = SubfieldElement<F>;
195
196 #[inline]
197 fn mul(self, rhs: &SubfieldElement<F>) -> Self::Output {
198 SubfieldElement(self.0 * rhs.0)
199 }
200}
201impl_borrow_variants!(SubfieldElement<F>, Mul, mul, *, SubfieldElement<F>, F: FieldExtension);
202
203impl<F: FieldExtension> MulAssign for SubfieldElement<F> {
206 #[inline]
207 fn mul_assign(&mut self, rhs: SubfieldElement<F>) {
208 *self = *self * rhs;
209 }
210}
211
212impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
213 #[inline]
214 fn mul_assign(&mut self, rhs: &'a SubfieldElement<F>) {
215 *self = *self * rhs;
216 }
217}
218
219impl<F: FieldExtension> Neg for &SubfieldElement<F> {
222 type Output = SubfieldElement<F>;
223
224 #[inline]
225 fn neg(self) -> Self::Output {
226 SubfieldElement(-self.0)
227 }
228}
229impl_borrow_variants!(SubfieldElement<F>, Neg, neg, -, F: FieldExtension);
230
231impl<F: FieldExtension> Div<&SubfieldElement<F>> for &SubfieldElement<F> {
234 type Output = CtOption<SubfieldElement<F>>;
235
236 #[inline]
237 fn div(self, rhs: &SubfieldElement<F>) -> Self::Output {
238 rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
239 }
240}
241
242impl<F: FieldExtension> Div<SubfieldElement<F>> for SubfieldElement<F> {
243 type Output = CtOption<SubfieldElement<F>>;
244
245 #[inline]
246 fn div(self, rhs: SubfieldElement<F>) -> Self::Output {
247 (&self).div(&rhs)
248 }
249}
250
251impl<F: FieldExtension> Div<SubfieldElement<F>> for &SubfieldElement<F> {
252 type Output = CtOption<SubfieldElement<F>>;
253
254 #[inline]
255 fn div(self, rhs: SubfieldElement<F>) -> Self::Output {
256 rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
257 }
258}
259
260impl<F: FieldExtension> Div<&SubfieldElement<F>> for SubfieldElement<F> {
261 type Output = CtOption<SubfieldElement<F>>;
262
263 #[inline]
264 fn div(self, rhs: &SubfieldElement<F>) -> Self::Output {
265 rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
266 }
267}
268
269impl<F: FieldExtension> ConstantTimeEq for SubfieldElement<F> {
272 #[inline]
273 fn ct_eq(&self, other: &Self) -> Choice {
274 self.0.ct_eq(&other.0)
275 }
276}
277
278impl<F: FieldExtension> ConditionallySelectable for SubfieldElement<F> {
279 #[inline]
280 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
281 let selected = F::Subfield::conditional_select(&a.0, &b.0, choice);
282 SubfieldElement(selected)
283 }
284}
285
286impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
289
290impl<F: FieldExtension> From<bool> for SubfieldElement<F> {
295 #[inline]
296 fn from(value: bool) -> Self {
297 SubfieldElement(F::Subfield::from(value as u64))
298 }
299}
300
301impl<F: FieldExtension> From<u8> for SubfieldElement<F> {
302 #[inline]
303 fn from(value: u8) -> Self {
304 SubfieldElement(F::Subfield::from(value as u64))
305 }
306}
307
308impl<F: FieldExtension> From<u16> for SubfieldElement<F> {
309 #[inline]
310 fn from(value: u16) -> Self {
311 SubfieldElement(F::Subfield::from(value as u64))
312 }
313}
314
315impl<F: FieldExtension> From<u32> for SubfieldElement<F> {
316 #[inline]
317 fn from(value: u32) -> Self {
318 SubfieldElement(F::Subfield::from(value as u64))
319 }
320}
321
322impl<F: FieldExtension> From<u64> for SubfieldElement<F> {
323 #[inline]
324 fn from(value: u64) -> Self {
325 SubfieldElement(F::Subfield::from(value))
326 }
327}
328
329impl<F: FieldExtension> From<u128> for SubfieldElement<F> {
330 #[inline]
331 fn from(value: u128) -> Self {
332 SubfieldElement(F::Subfield::from(value))
333 }
334}
335
336impl<F: PrimeFieldExtension> From<FieldElement<F>> for SubfieldElement<F> {
337 #[inline]
338 fn from(value: FieldElement<F>) -> Self {
339 SubfieldElement(value.0)
340 }
341}
342
343impl<F: FieldExtension> Sum for SubfieldElement<F> {
348 #[inline]
349 fn sum<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
350 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
351 F::Subfield::acc(&mut acc, x.0);
352 acc
353 });
354 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
355 }
356}
357
358impl<'a, F: FieldExtension> Sum<&'a SubfieldElement<F>> for SubfieldElement<F> {
359 #[inline]
360 fn sum<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
361 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
362 F::Subfield::acc(&mut acc, x.0);
363 acc
364 });
365 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
366 }
367}
368
369impl<F: FieldExtension> Product for SubfieldElement<F> {
370 #[inline]
371 fn product<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
372 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
373 }
374}
375
376impl<'a, F: FieldExtension> Product<&'a SubfieldElement<F>> for SubfieldElement<F> {
377 #[inline]
378 fn product<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
379 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
380 }
381}
382
383impl<F: FieldExtension> FromUniformBytes for SubfieldElement<F> {
384 type UniformBytes = <F::Subfield as FromUniformBytes>::UniformBytes;
385
386 fn from_uniform_bytes(bytes: &Array<u8, Self::UniformBytes>) -> Self {
387 Self(F::Subfield::from_uniform_bytes(bytes))
388 }
389}
390
391impl<F: FieldExtension> IntoWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
393 #[inline]
394 fn to_wide(&self) -> <F::Subfield as MulAccReduce>::WideType {
395 <F::Subfield as MulAccReduce>::to_wide(&self.0)
396 }
397
398 #[inline]
399 fn zero_wide() -> <F::Subfield as MulAccReduce>::WideType {
400 <F::Subfield as MulAccReduce>::zero_wide()
401 }
402}
403
404impl<F: FieldExtension> ReduceWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
405 #[inline]
406 fn reduce_mod_order(a: <F::Subfield as MulAccReduce>::WideType) -> Self {
407 Self(F::Subfield::reduce_mod_order(a))
408 }
409}
410
411impl<F: FieldExtension> MulAccReduce for SubfieldElement<F> {
412 type WideType = <F::Subfield as MulAccReduce>::WideType;
413
414 #[inline]
415 fn mul_acc(acc: &mut Self::WideType, a: Self, b: Self) {
416 F::Subfield::mul_acc(acc, a.0, b.0);
417 }
418}
419
420impl<F: FieldExtension> DefaultDotProduct for SubfieldElement<F> {}
421
422impl<'a, F: FieldExtension> MulAccReduce<&'a Self, Self> for SubfieldElement<F> {
424 type WideType = <F::Subfield as MulAccReduce>::WideType;
425
426 #[inline]
427 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: Self) {
428 F::Subfield::mul_acc(acc, a.0, b.0);
429 }
430}
431
432impl<F: FieldExtension> DefaultDotProduct<&Self, Self> for SubfieldElement<F> {}
433
434impl<'a, F: FieldExtension> MulAccReduce<Self, &'a Self> for SubfieldElement<F> {
436 type WideType = <F::Subfield as MulAccReduce>::WideType;
437
438 #[inline]
439 fn mul_acc(acc: &mut Self::WideType, a: Self, b: &'a Self) {
440 F::Subfield::mul_acc(acc, a.0, b.0);
441 }
442}
443
444impl<F: FieldExtension> DefaultDotProduct<Self, &Self> for SubfieldElement<F> {}
445
446impl<'a, 'b, F: FieldExtension> MulAccReduce<&'a Self, &'b Self> for SubfieldElement<F> {
448 type WideType = <F::Subfield as MulAccReduce>::WideType;
449
450 #[inline]
451 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: &'b Self) {
452 F::Subfield::mul_acc(acc, a.0, b.0);
453 }
454}
455
456impl<F: FieldExtension> DefaultDotProduct<&Self, &Self> for SubfieldElement<F> {}
457
458impl<F: FieldExtension> Zero for SubfieldElement<F> {
463 fn zero() -> Self {
465 SubfieldElement(F::Subfield::ZERO)
466 }
467
468 fn is_zero(&self) -> bool {
469 self.0.is_zero().into()
470 }
471}
472
473impl<F: FieldExtension> One for SubfieldElement<F> {
474 fn one() -> Self {
476 SubfieldElement(F::Subfield::ONE)
477 }
478}
479
480impl<F: FieldExtension> Field for SubfieldElement<F> {
485 const ZERO: Self = SubfieldElement(F::Subfield::ZERO);
486 const ONE: Self = SubfieldElement(F::Subfield::ONE);
487
488 fn random(rng: impl RngCore) -> Self {
489 Self(<F::Subfield as Field>::random(rng))
490 }
491
492 fn square(&self) -> Self {
493 SubfieldElement(self.0.square())
494 }
495
496 fn double(&self) -> Self {
497 SubfieldElement(self.0.double())
498 }
499
500 fn invert(&self) -> CtOption<Self> {
501 self.0.invert().map(SubfieldElement)
502 }
503
504 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
505 let (choice, sqrt) = F::Subfield::sqrt_ratio(&num.0, &div.0);
506 (choice, SubfieldElement(sqrt))
507 }
508}