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 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#[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 #[inline]
47 pub fn new(inner: F::Subfield) -> Self {
48 SubfieldElement(inner)
49 }
50
51 #[inline]
53 pub fn inner(&self) -> F::Subfield {
54 self.0
55 }
56
57 #[inline]
59 pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
60 SubfieldElement::new(self.0.pow(exp))
61 }
62
63 #[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 #[inline]
89 pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> + '_ {
90 self.0.to_le_bytes()
91 }
92
93 #[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#[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#[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#[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#[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#[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
248impl<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
265impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
268
269impl<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
322impl<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
370impl<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
401impl<'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
413impl<'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
425impl<'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
437impl<F: FieldExtension> Zero for SubfieldElement<F> {
442 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 fn one() -> Self {
455 SubfieldElement(F::Subfield::ONE)
456 }
457}
458
459impl<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}