primitives/algebra/field/
subfield_element.rs

1use 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::{
17            binary::Gf2_128,
18            mersenne::Mersenne107,
19            ByteSize,
20            FieldElement,
21            FieldExtension,
22            PrimeFieldExtension,
23        },
24        ops::{AccReduce, DefaultDotProduct, IntoWide, MulAccReduce, ReduceWide},
25        uniform_bytes::FromUniformBytes,
26    },
27    errors::PrimitiveError,
28    random::{CryptoRngCore, Random},
29    sharing::unauthenticated::AdditiveShares,
30    types::HeapArray,
31};
32
33pub type Bit = SubfieldElement<Gf2_128>;
34pub type Bits<N> = HeapArray<Bit, N>;
35
36pub type Mersenne107Element = SubfieldElement<Mersenne107>;
37pub type Mersenne107Elements<N> = HeapArray<Mersenne107Element, N>;
38
39/// A subfield element wrapper.
40#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
41pub struct SubfieldElement<F: FieldExtension>(pub(crate) F::Subfield);
42
43impl<F: FieldExtension> SubfieldElement<F> {
44    /// Construct a subfield element from an inner subfield element
45    #[inline]
46    pub fn new(inner: F::Subfield) -> Self {
47        SubfieldElement(inner)
48    }
49
50    /// Get the inner value of the subfield element
51    #[inline]
52    pub fn inner(&self) -> F::Subfield {
53        self.0
54    }
55
56    /// Compute the exponentiation of the given subfield element
57    #[inline]
58    pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
59        SubfieldElement::new(self.0.pow(exp))
60    }
61
62    /// Construct a subfield element from the given bytes
63    #[inline]
64    pub fn from_be_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, PrimitiveError> {
65        let mut bytes = bytes.to_vec();
66        bytes.reverse();
67        Ok(SubfieldElement(
68            F::Subfield::from_le_bytes(&bytes).ok_or_else(|| {
69                PrimitiveError::DeserializationFailed(
70                    "Invalid subfield element encoding".to_string(),
71                )
72            })?,
73        ))
74    }
75
76    pub fn from_le_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, PrimitiveError> {
77        Ok(SubfieldElement(
78            F::Subfield::from_le_bytes(bytes).ok_or_else(|| {
79                PrimitiveError::DeserializationFailed(
80                    "Invalid subfield element encoding".to_string(),
81                )
82            })?,
83        ))
84    }
85
86    /// Convert the subfield element to little-endian bytes
87    #[inline]
88    pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> + '_ {
89        self.0.to_le_bytes()
90    }
91
92    /// Convert the subfield element to big-endian bytes
93    #[inline]
94    pub fn to_be_bytes(&self) -> impl IntoIterator<Item = u8> {
95        self.0
96            .to_le_bytes()
97            .into_iter()
98            .collect::<Vec<_>>()
99            .into_iter()
100            .rev()
101            .collect::<Vec<_>>()
102    }
103
104    pub fn to_biguint(&self) -> num_bigint::BigUint {
105        num_bigint::BigUint::from_bytes_le(
106            self.to_le_bytes().into_iter().collect::<Vec<_>>().as_ref(),
107        )
108    }
109}
110
111impl<F: FieldExtension> Random for SubfieldElement<F> {
112    fn random(mut rng: impl CryptoRngCore) -> Self {
113        SubfieldElement(F::Subfield::random(&mut rng))
114    }
115}
116
117impl<F: FieldExtension> Default for SubfieldElement<F> {
118    fn default() -> Self {
119        Self::zero()
120    }
121}
122
123impl<F: FieldExtension> Serialize for SubfieldElement<F> {
124    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
125        let bytes = self
126            .to_le_bytes()
127            .into_iter()
128            .collect::<Array<u8, ByteSize<F::Subfield>>>();
129        serde_bytes::serialize(AsRef::<[u8]>::as_ref(&bytes), serializer)
130    }
131}
132
133impl<'de, F: FieldExtension> Deserialize<'de> for SubfieldElement<F> {
134    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
135        let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
136        let field_elem = SubfieldElement::from_le_bytes(bytes).map_err(|err| {
137            serde::de::Error::custom(format!("Failed to deserialize field element: {err:?}"))
138        })?;
139        Ok(field_elem)
140    }
141}
142
143impl<F: FieldExtension> Display for SubfieldElement<F> {
144    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
145        write!(f, "{self:?}")
146    }
147}
148
149// --------------
150// | Arithmetic |
151// --------------
152
153// === Addition === //
154
155#[macros::op_variants(owned, borrowed, flipped_commutative)]
156impl<F: FieldExtension> Add<&SubfieldElement<F>> for SubfieldElement<F> {
157    type Output = SubfieldElement<F>;
158
159    #[inline]
160    fn add(self, rhs: &SubfieldElement<F>) -> Self::Output {
161        SubfieldElement(self.0 + rhs.0)
162    }
163}
164
165#[macros::op_variants(owned)]
166impl<'a, F: FieldExtension> AddAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
167    #[inline]
168    fn add_assign(&mut self, rhs: &'a SubfieldElement<F>) {
169        *self = *self + rhs;
170    }
171}
172
173// === Subtraction === //
174
175#[macros::op_variants(owned, borrowed, flipped)]
176impl<F: FieldExtension> Sub<&SubfieldElement<F>> for SubfieldElement<F> {
177    type Output = SubfieldElement<F>;
178
179    #[inline]
180    fn sub(self, rhs: &SubfieldElement<F>) -> Self::Output {
181        SubfieldElement(self.0 - rhs.0)
182    }
183}
184
185#[macros::op_variants(owned)]
186impl<'a, F: FieldExtension> SubAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
187    #[inline]
188    fn sub_assign(&mut self, rhs: &'a SubfieldElement<F>) {
189        *self = *self - rhs;
190    }
191}
192
193// === Multiplication === //
194
195#[macros::op_variants(owned, borrowed, flipped_commutative)]
196impl<F: FieldExtension> Mul<&SubfieldElement<F>> for SubfieldElement<F> {
197    type Output = SubfieldElement<F>;
198
199    #[inline]
200    fn mul(self, rhs: &SubfieldElement<F>) -> Self::Output {
201        SubfieldElement(self.0 * rhs.0)
202    }
203}
204
205#[macros::op_variants(owned, borrowed, flipped_commutative)]
206impl<F: FieldExtension> Mul<&FieldElement<F>> for SubfieldElement<F> {
207    type Output = FieldElement<F>;
208
209    #[inline]
210    fn mul(self, rhs: &FieldElement<F>) -> Self::Output {
211        FieldElement(rhs.0 * self.0)
212    }
213}
214
215#[macros::op_variants(owned)]
216impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
217    #[inline]
218    fn mul_assign(&mut self, rhs: &'a SubfieldElement<F>) {
219        *self = *self * rhs;
220    }
221}
222
223// === Negation === //
224
225#[macros::op_variants(borrowed)]
226impl<F: FieldExtension> Neg for SubfieldElement<F> {
227    type Output = SubfieldElement<F>;
228
229    #[inline]
230    fn neg(self) -> Self::Output {
231        SubfieldElement(-self.0)
232    }
233}
234
235// === Division === //
236
237#[macros::op_variants(owned, borrowed, flipped)]
238impl<F: FieldExtension> Div<&SubfieldElement<F>> for SubfieldElement<F> {
239    type Output = CtOption<SubfieldElement<F>>;
240
241    #[inline]
242    fn div(self, rhs: &SubfieldElement<F>) -> Self::Output {
243        rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
244    }
245}
246
247// === Equality === //
248
249impl<F: FieldExtension> ConstantTimeEq for SubfieldElement<F> {
250    #[inline]
251    fn ct_eq(&self, other: &Self) -> Choice {
252        self.0.ct_eq(&other.0)
253    }
254}
255
256impl<F: FieldExtension> ConditionallySelectable for SubfieldElement<F> {
257    #[inline]
258    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
259        let selected = F::Subfield::conditional_select(&a.0, &b.0, choice);
260        SubfieldElement(selected)
261    }
262}
263
264// === Other === //
265
266impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
267
268// ---------------
269// | Conversions |
270// ---------------
271
272impl<F: FieldExtension> From<bool> for SubfieldElement<F> {
273    #[inline]
274    fn from(value: bool) -> Self {
275        SubfieldElement(F::Subfield::from(value as u64))
276    }
277}
278
279impl<F: FieldExtension> From<u8> for SubfieldElement<F> {
280    #[inline]
281    fn from(value: u8) -> Self {
282        SubfieldElement(F::Subfield::from(value as u64))
283    }
284}
285
286impl<F: FieldExtension> From<u16> for SubfieldElement<F> {
287    #[inline]
288    fn from(value: u16) -> Self {
289        SubfieldElement(F::Subfield::from(value as u64))
290    }
291}
292
293impl<F: FieldExtension> From<u32> for SubfieldElement<F> {
294    #[inline]
295    fn from(value: u32) -> Self {
296        SubfieldElement(F::Subfield::from(value as u64))
297    }
298}
299
300impl<F: FieldExtension> From<u64> for SubfieldElement<F> {
301    #[inline]
302    fn from(value: u64) -> Self {
303        SubfieldElement(F::Subfield::from(value))
304    }
305}
306
307impl<F: FieldExtension> From<u128> for SubfieldElement<F> {
308    #[inline]
309    fn from(value: u128) -> Self {
310        SubfieldElement(F::Subfield::from(value))
311    }
312}
313
314impl<F: PrimeFieldExtension> From<FieldElement<F>> for SubfieldElement<F> {
315    #[inline]
316    fn from(value: FieldElement<F>) -> Self {
317        SubfieldElement(value.0)
318    }
319}
320
321// -------------------
322// | Iterator Traits |
323// -------------------
324
325impl<F: FieldExtension> Sum for SubfieldElement<F> {
326    #[inline]
327    fn sum<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
328        let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
329            F::Subfield::acc(&mut acc, x.0);
330            acc
331        });
332        SubfieldElement(F::Subfield::reduce_mod_order(tmp))
333    }
334}
335
336impl<'a, F: FieldExtension> Sum<&'a SubfieldElement<F>> for SubfieldElement<F> {
337    #[inline]
338    fn sum<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
339        let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
340            F::Subfield::acc(&mut acc, x.0);
341            acc
342        });
343        SubfieldElement(F::Subfield::reduce_mod_order(tmp))
344    }
345}
346
347impl<F: FieldExtension> Product for SubfieldElement<F> {
348    #[inline]
349    fn product<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
350        iter.fold(SubfieldElement::one(), |acc, x| acc * x)
351    }
352}
353
354impl<'a, F: FieldExtension> Product<&'a SubfieldElement<F>> for SubfieldElement<F> {
355    #[inline]
356    fn product<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
357        iter.fold(SubfieldElement::one(), |acc, x| acc * x)
358    }
359}
360
361impl<F: FieldExtension> FromUniformBytes for SubfieldElement<F> {
362    type UniformBytes = <F::Subfield as FromUniformBytes>::UniformBytes;
363
364    fn from_uniform_bytes(bytes: &Array<u8, Self::UniformBytes>) -> Self {
365        Self(F::Subfield::from_uniform_bytes(bytes))
366    }
367}
368
369// Dot product: Subfield<F> x Subfield<F>
370impl<F: FieldExtension> IntoWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
371    #[inline]
372    fn to_wide(&self) -> <F::Subfield as MulAccReduce>::WideType {
373        <F::Subfield as MulAccReduce>::to_wide(&self.0)
374    }
375
376    #[inline]
377    fn zero_wide() -> <F::Subfield as MulAccReduce>::WideType {
378        <F::Subfield as MulAccReduce>::zero_wide()
379    }
380}
381
382impl<F: FieldExtension> ReduceWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
383    #[inline]
384    fn reduce_mod_order(a: <F::Subfield as MulAccReduce>::WideType) -> Self {
385        Self(F::Subfield::reduce_mod_order(a))
386    }
387}
388
389impl<F: FieldExtension> MulAccReduce for SubfieldElement<F> {
390    type WideType = <F::Subfield as MulAccReduce>::WideType;
391
392    #[inline]
393    fn mul_acc(acc: &mut Self::WideType, a: Self, b: Self) {
394        F::Subfield::mul_acc(acc, a.0, b.0);
395    }
396}
397
398impl<F: FieldExtension> DefaultDotProduct for SubfieldElement<F> {}
399
400// Dot product: &Subfield<F> x Subfield<F>
401impl<'a, F: FieldExtension> MulAccReduce<&'a Self, Self> for SubfieldElement<F> {
402    type WideType = <F::Subfield as MulAccReduce>::WideType;
403
404    #[inline]
405    fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: Self) {
406        F::Subfield::mul_acc(acc, a.0, b.0);
407    }
408}
409
410impl<F: FieldExtension> DefaultDotProduct<&Self, Self> for SubfieldElement<F> {}
411
412// Dot product: Subfield<F> x &Subfield<F>
413impl<'a, F: FieldExtension> MulAccReduce<Self, &'a Self> for SubfieldElement<F> {
414    type WideType = <F::Subfield as MulAccReduce>::WideType;
415
416    #[inline]
417    fn mul_acc(acc: &mut Self::WideType, a: Self, b: &'a Self) {
418        F::Subfield::mul_acc(acc, a.0, b.0);
419    }
420}
421
422impl<F: FieldExtension> DefaultDotProduct<Self, &Self> for SubfieldElement<F> {}
423
424// Dot product: &Subfield<F> x &Subfield<F>
425impl<'a, 'b, F: FieldExtension> MulAccReduce<&'a Self, &'b Self> for SubfieldElement<F> {
426    type WideType = <F::Subfield as MulAccReduce>::WideType;
427
428    #[inline]
429    fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: &'b Self) {
430        F::Subfield::mul_acc(acc, a.0, b.0);
431    }
432}
433
434impl<F: FieldExtension> DefaultDotProduct<&Self, &Self> for SubfieldElement<F> {}
435
436// ----------------
437// | Zero and One |
438// ----------------
439
440impl<F: FieldExtension> Zero for SubfieldElement<F> {
441    /// The subfield's additive identity
442    fn zero() -> Self {
443        SubfieldElement(F::Subfield::ZERO)
444    }
445
446    fn is_zero(&self) -> bool {
447        self.0.is_zero().into()
448    }
449}
450
451impl<F: FieldExtension> One for SubfieldElement<F> {
452    /// The subfield's multiplicative identity
453    fn one() -> Self {
454        SubfieldElement(F::Subfield::ONE)
455    }
456}
457
458// ---------------
459// | Field trait |
460// ---------------
461
462impl<F: FieldExtension> Field for SubfieldElement<F> {
463    const ZERO: Self = SubfieldElement(F::Subfield::ZERO);
464    const ONE: Self = SubfieldElement(F::Subfield::ONE);
465
466    fn random(rng: impl RngCore) -> Self {
467        Self(<F::Subfield as Field>::random(rng))
468    }
469
470    fn square(&self) -> Self {
471        SubfieldElement(self.0.square())
472    }
473
474    fn double(&self) -> Self {
475        SubfieldElement(self.0.double())
476    }
477
478    fn invert(&self) -> CtOption<Self> {
479        self.0.invert().map(SubfieldElement)
480    }
481
482    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
483        let (choice, sqrt) = F::Subfield::sqrt_ratio(&num.0, &div.0);
484        (choice, SubfieldElement(sqrt))
485    }
486}