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},
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#[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 #[inline]
51 pub fn new(inner: F::Subfield) -> Self {
52 SubfieldElement(inner)
53 }
54
55 #[inline]
57 pub fn inner(&self) -> F::Subfield {
58 self.0
59 }
60
61 #[inline]
63 pub fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
64 SubfieldElement::new(self.0.pow(exp))
65 }
66
67 #[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 #[inline]
93 pub fn to_le_bytes(&self) -> Array<u8, ByteSize<F::Subfield>> {
94 self.0.to_le_bytes()
95 }
96
97 #[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#[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#[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#[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#[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#[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
250impl<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
267impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
270
271impl<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
324impl<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
372impl<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
403impl<'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
415impl<'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
427impl<'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
439impl<F: FieldExtension> Zero for SubfieldElement<F> {
444 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 fn one() -> Self {
457 SubfieldElement(F::Subfield::ONE)
458 }
459}
460
461impl<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}