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};
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, RandomNonZero},
31 sharing::unauthenticated::AdditiveShares,
32 types::{HeapArray, Positive},
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#[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
48unsafe impl<F: FieldExtension> bytemuck::TransparentWrapper<F::Subfield> for SubfieldElement<F> {}
50
51impl<F: FieldExtension> SubfieldElement<F> {
52 #[inline]
54 pub fn new(inner: F::Subfield) -> Self {
55 SubfieldElement(inner)
56 }
57
58 #[inline]
60 pub fn inner(&self) -> F::Subfield {
61 self.0
62 }
63
64 #[inline]
66 pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
67 SubfieldElement::new(self.0.pow(exp))
68 }
69
70 #[inline]
72 pub fn from_be_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, PrimitiveError> {
73 let mut bytes = bytes.to_vec();
74 bytes.reverse();
75 Ok(SubfieldElement(
76 F::Subfield::from_le_bytes(&bytes).ok_or_else(|| {
77 PrimitiveError::DeserializationFailed(
78 "Invalid subfield element encoding".to_string(),
79 )
80 })?,
81 ))
82 }
83
84 pub fn from_le_bytes(bytes: &[u8]) -> Result<SubfieldElement<F>, PrimitiveError> {
85 Ok(SubfieldElement(
86 F::Subfield::from_le_bytes(bytes).ok_or_else(|| {
87 PrimitiveError::DeserializationFailed(
88 "Invalid subfield element encoding".to_string(),
89 )
90 })?,
91 ))
92 }
93
94 #[inline]
96 pub fn to_le_bytes(&self) -> Array<u8, ByteSize<F::Subfield>> {
97 self.0.to_le_bytes()
98 }
99
100 #[inline]
102 pub fn to_be_bytes(&self) -> Array<u8, ByteSize<F::Subfield>> {
103 let mut rev = self.0.to_le_bytes();
104 rev.as_mut().reverse();
105 rev
106 }
107
108 pub fn to_biguint(&self) -> num_bigint::BigUint {
109 num_bigint::BigUint::from_bytes_le(self.to_le_bytes().as_ref())
110 }
111
112 pub fn to_bigint(&self) -> num_bigint::BigInt {
113 self.to_biguint().into()
114 }
115
116 pub fn random_elements<M: Positive>(rng: impl CryptoRngCore) -> HeapArray<Self, M> {
117 F::Subfield::random_array(rng).wrap_transparent()
118 }
119}
120
121impl<F: FieldExtension> Random for SubfieldElement<F> {
122 fn random(mut rng: impl CryptoRngCore) -> Self {
123 SubfieldElement(Random::random(&mut rng))
124 }
125}
126
127impl<F: FieldExtension> RandomNonZero for SubfieldElement<F> {
128 fn random_non_zero(mut rng: impl CryptoRngCore) -> Result<Self, PrimitiveError> {
129 Ok(SubfieldElement(F::Subfield::random_non_zero(&mut rng)?))
130 }
131}
132
133impl<F: FieldExtension> Default for SubfieldElement<F> {
134 fn default() -> Self {
135 Self::zero()
136 }
137}
138
139impl<F: FieldExtension> Serialize for SubfieldElement<F> {
140 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
141 let bytes = self
142 .to_le_bytes()
143 .into_iter()
144 .collect::<Array<u8, ByteSize<F::Subfield>>>();
145 serde_bytes::serialize(AsRef::<[u8]>::as_ref(&bytes), serializer)
146 }
147}
148
149impl<'de, F: FieldExtension> Deserialize<'de> for SubfieldElement<F> {
150 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
151 let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
152 let field_elem = SubfieldElement::from_le_bytes(bytes).map_err(|err| {
153 serde::de::Error::custom(format!("Failed to deserialize field element: {err:?}"))
154 })?;
155 Ok(field_elem)
156 }
157}
158
159impl<F: FieldExtension> Display for SubfieldElement<F> {
160 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
161 write!(f, "{self:?}")
162 }
163}
164
165#[macros::op_variants(owned, borrowed, flipped_commutative)]
172impl<F: FieldExtension> Add<&SubfieldElement<F>> for SubfieldElement<F> {
173 type Output = SubfieldElement<F>;
174
175 #[inline]
176 fn add(self, rhs: &SubfieldElement<F>) -> Self::Output {
177 SubfieldElement(self.0 + rhs.0)
178 }
179}
180
181#[macros::op_variants(owned)]
182impl<'a, F: FieldExtension> AddAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
183 #[inline]
184 fn add_assign(&mut self, rhs: &'a SubfieldElement<F>) {
185 *self = *self + rhs;
186 }
187}
188
189#[macros::op_variants(owned, borrowed, flipped)]
192impl<F: FieldExtension> Sub<&SubfieldElement<F>> for SubfieldElement<F> {
193 type Output = SubfieldElement<F>;
194
195 #[inline]
196 fn sub(self, rhs: &SubfieldElement<F>) -> Self::Output {
197 SubfieldElement(self.0 - rhs.0)
198 }
199}
200
201#[macros::op_variants(owned)]
202impl<'a, F: FieldExtension> SubAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
203 #[inline]
204 fn sub_assign(&mut self, rhs: &'a SubfieldElement<F>) {
205 *self = *self - rhs;
206 }
207}
208
209#[macros::op_variants(owned, borrowed, flipped_commutative)]
212impl<F: FieldExtension> Mul<&SubfieldElement<F>> for SubfieldElement<F> {
213 type Output = SubfieldElement<F>;
214
215 #[inline]
216 fn mul(self, rhs: &SubfieldElement<F>) -> Self::Output {
217 SubfieldElement(self.0 * rhs.0)
218 }
219}
220
221#[macros::op_variants(owned, borrowed, flipped_commutative)]
222impl<F: FieldExtension> Mul<&FieldElement<F>> for SubfieldElement<F> {
223 type Output = FieldElement<F>;
224
225 #[inline]
226 fn mul(self, rhs: &FieldElement<F>) -> Self::Output {
227 FieldElement(rhs.0 * self.0)
228 }
229}
230
231#[macros::op_variants(owned)]
232impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
233 #[inline]
234 fn mul_assign(&mut self, rhs: &'a SubfieldElement<F>) {
235 *self = *self * rhs;
236 }
237}
238
239#[macros::op_variants(borrowed)]
242impl<F: FieldExtension> Neg for SubfieldElement<F> {
243 type Output = SubfieldElement<F>;
244
245 #[inline]
246 fn neg(self) -> Self::Output {
247 SubfieldElement(-self.0)
248 }
249}
250
251#[macros::op_variants(owned, borrowed, flipped)]
254impl<F: FieldExtension> Div<&SubfieldElement<F>> for SubfieldElement<F> {
255 type Output = CtOption<SubfieldElement<F>>;
256
257 #[inline]
258 fn div(self, rhs: &SubfieldElement<F>) -> Self::Output {
259 rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
260 }
261}
262
263impl<F: FieldExtension> ConstantTimeEq for SubfieldElement<F> {
266 #[inline]
267 fn ct_eq(&self, other: &Self) -> Choice {
268 self.0.ct_eq(&other.0)
269 }
270}
271
272impl<F: FieldExtension> ConditionallySelectable for SubfieldElement<F> {
273 #[inline]
274 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
275 let selected = F::Subfield::conditional_select(&a.0, &b.0, choice);
276 SubfieldElement(selected)
277 }
278}
279
280impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
283
284impl<F: FieldExtension> From<bool> for SubfieldElement<F> {
289 #[inline]
290 fn from(value: bool) -> Self {
291 SubfieldElement(F::Subfield::from(value as u64))
292 }
293}
294
295impl<F: FieldExtension> From<u8> for SubfieldElement<F> {
296 #[inline]
297 fn from(value: u8) -> Self {
298 SubfieldElement(F::Subfield::from(value as u64))
299 }
300}
301
302impl<F: FieldExtension> From<u16> for SubfieldElement<F> {
303 #[inline]
304 fn from(value: u16) -> Self {
305 SubfieldElement(F::Subfield::from(value as u64))
306 }
307}
308
309impl<F: FieldExtension> From<u32> for SubfieldElement<F> {
310 #[inline]
311 fn from(value: u32) -> Self {
312 SubfieldElement(F::Subfield::from(value as u64))
313 }
314}
315
316impl<F: FieldExtension> From<u64> for SubfieldElement<F> {
317 #[inline]
318 fn from(value: u64) -> Self {
319 SubfieldElement(F::Subfield::from(value))
320 }
321}
322
323impl<F: FieldExtension> From<u128> for SubfieldElement<F> {
324 #[inline]
325 fn from(value: u128) -> Self {
326 SubfieldElement(F::Subfield::from(value))
327 }
328}
329
330impl<F: PrimeFieldExtension> From<FieldElement<F>> for SubfieldElement<F> {
331 #[inline]
332 fn from(value: FieldElement<F>) -> Self {
333 SubfieldElement(value.0)
334 }
335}
336
337impl<F: FieldExtension> Sum for SubfieldElement<F> {
342 #[inline]
343 fn sum<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
344 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
345 F::Subfield::acc(&mut acc, x.0);
346 acc
347 });
348 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
349 }
350}
351
352impl<'a, F: FieldExtension> Sum<&'a SubfieldElement<F>> for SubfieldElement<F> {
353 #[inline]
354 fn sum<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
355 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
356 F::Subfield::acc(&mut acc, x.0);
357 acc
358 });
359 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
360 }
361}
362
363impl<F: FieldExtension> Product for SubfieldElement<F> {
364 #[inline]
365 fn product<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
366 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
367 }
368}
369
370impl<'a, F: FieldExtension> Product<&'a SubfieldElement<F>> for SubfieldElement<F> {
371 #[inline]
372 fn product<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
373 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
374 }
375}
376
377impl<F: FieldExtension> FromUniformBytes for SubfieldElement<F> {
378 type UniformBytes = <F::Subfield as FromUniformBytes>::UniformBytes;
379
380 fn from_uniform_bytes(bytes: &Array<u8, Self::UniformBytes>) -> Self {
381 Self(F::Subfield::from_uniform_bytes(bytes))
382 }
383}
384
385impl<F: FieldExtension> IntoWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
387 #[inline]
388 fn to_wide(&self) -> <F::Subfield as MulAccReduce>::WideType {
389 <F::Subfield as MulAccReduce>::to_wide(&self.0)
390 }
391
392 #[inline]
393 fn zero_wide() -> <F::Subfield as MulAccReduce>::WideType {
394 <F::Subfield as MulAccReduce>::zero_wide()
395 }
396}
397
398impl<F: FieldExtension> ReduceWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
399 #[inline]
400 fn reduce_mod_order(a: <F::Subfield as MulAccReduce>::WideType) -> Self {
401 Self(F::Subfield::reduce_mod_order(a))
402 }
403}
404
405impl<F: FieldExtension> MulAccReduce for SubfieldElement<F> {
406 type WideType = <F::Subfield as MulAccReduce>::WideType;
407
408 #[inline]
409 fn mul_acc(acc: &mut Self::WideType, a: Self, b: Self) {
410 F::Subfield::mul_acc(acc, a.0, b.0);
411 }
412}
413
414impl<F: FieldExtension> DefaultDotProduct for SubfieldElement<F> {}
415
416impl<'a, F: FieldExtension> MulAccReduce<&'a Self, Self> for SubfieldElement<F> {
418 type WideType = <F::Subfield as MulAccReduce>::WideType;
419
420 #[inline]
421 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: Self) {
422 F::Subfield::mul_acc(acc, a.0, b.0);
423 }
424}
425
426impl<F: FieldExtension> DefaultDotProduct<&Self, Self> for SubfieldElement<F> {}
427
428impl<'a, F: FieldExtension> MulAccReduce<Self, &'a Self> for SubfieldElement<F> {
430 type WideType = <F::Subfield as MulAccReduce>::WideType;
431
432 #[inline]
433 fn mul_acc(acc: &mut Self::WideType, a: Self, b: &'a Self) {
434 F::Subfield::mul_acc(acc, a.0, b.0);
435 }
436}
437
438impl<F: FieldExtension> DefaultDotProduct<Self, &Self> for SubfieldElement<F> {}
439
440impl<'a, 'b, F: FieldExtension> MulAccReduce<&'a Self, &'b Self> for SubfieldElement<F> {
442 type WideType = <F::Subfield as MulAccReduce>::WideType;
443
444 #[inline]
445 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: &'b Self) {
446 F::Subfield::mul_acc(acc, a.0, b.0);
447 }
448}
449
450impl<F: FieldExtension> DefaultDotProduct<&Self, &Self> for SubfieldElement<F> {}
451
452impl<F: FieldExtension> Zero for SubfieldElement<F> {
457 fn zero() -> Self {
459 SubfieldElement(F::Subfield::ZERO)
460 }
461
462 fn is_zero(&self) -> bool {
463 self.0.is_zero().into()
464 }
465}
466
467impl<F: FieldExtension> One for SubfieldElement<F> {
468 fn one() -> Self {
470 SubfieldElement(F::Subfield::ONE)
471 }
472}
473
474impl<F: FieldExtension> Field for SubfieldElement<F> {
479 const ZERO: Self = SubfieldElement(F::Subfield::ZERO);
480 const ONE: Self = SubfieldElement(F::Subfield::ONE);
481
482 fn random(rng: impl RngCore) -> Self {
483 Self(<F::Subfield as Field>::random(rng))
484 }
485
486 fn square(&self) -> Self {
487 SubfieldElement(self.0.square())
488 }
489
490 fn double(&self) -> Self {
491 SubfieldElement(self.0.double())
492 }
493
494 fn invert(&self) -> CtOption<Self> {
495 self.0.invert().map(SubfieldElement)
496 }
497
498 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
499 let (choice, sqrt) = F::Subfield::sqrt_ratio(&num.0, &div.0);
500 (choice, SubfieldElement(sqrt))
501 }
502}
503
504#[cfg(test)]
505mod tests {
506 use super::*;
507
508 #[test]
509 fn test_subfield_mersenne107_wincode() {
510 let elem = SubfieldElement::<Mersenne107>::new(Mersenne107::from(42u64));
511 let bytes = wincode::serialize(&elem).unwrap();
512
513 let decoded: SubfieldElement<Mersenne107> = wincode::deserialize(&bytes).unwrap();
514
515 assert_eq!(elem, decoded);
516 }
517}