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::{
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#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
41pub struct SubfieldElement<F: FieldExtension>(pub(crate) F::Subfield);
42
43impl<F: FieldExtension> SubfieldElement<F> {
44 #[inline]
46 pub fn new(inner: F::Subfield) -> Self {
47 SubfieldElement(inner)
48 }
49
50 #[inline]
52 pub fn inner(&self) -> F::Subfield {
53 self.0
54 }
55
56 #[inline]
58 pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
59 SubfieldElement::new(self.0.pow(exp))
60 }
61
62 #[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 #[inline]
88 pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> + '_ {
89 self.0.to_le_bytes()
90 }
91
92 #[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#[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#[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#[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#[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#[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
247impl<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
264impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
267
268impl<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
321impl<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
369impl<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
400impl<'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
412impl<'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
424impl<'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
436impl<F: FieldExtension> Zero for SubfieldElement<F> {
441 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 fn one() -> Self {
454 SubfieldElement(F::Subfield::ONE)
455 }
456}
457
458impl<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}