Skip to main content

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