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