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, 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> Default for SubfieldElement<F> {
128 fn default() -> Self {
129 Self::zero()
130 }
131}
132
133impl<F: FieldExtension> Serialize for SubfieldElement<F> {
134 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
135 let bytes = self
136 .to_le_bytes()
137 .into_iter()
138 .collect::<Array<u8, ByteSize<F::Subfield>>>();
139 serde_bytes::serialize(AsRef::<[u8]>::as_ref(&bytes), serializer)
140 }
141}
142
143impl<'de, F: FieldExtension> Deserialize<'de> for SubfieldElement<F> {
144 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
145 let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
146 let field_elem = SubfieldElement::from_le_bytes(bytes).map_err(|err| {
147 serde::de::Error::custom(format!("Failed to deserialize field element: {err:?}"))
148 })?;
149 Ok(field_elem)
150 }
151}
152
153impl<F: FieldExtension> Display for SubfieldElement<F> {
154 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
155 write!(f, "{self:?}")
156 }
157}
158
159#[macros::op_variants(owned, borrowed, flipped_commutative)]
166impl<F: FieldExtension> Add<&SubfieldElement<F>> for SubfieldElement<F> {
167 type Output = SubfieldElement<F>;
168
169 #[inline]
170 fn add(self, rhs: &SubfieldElement<F>) -> Self::Output {
171 SubfieldElement(self.0 + rhs.0)
172 }
173}
174
175#[macros::op_variants(owned)]
176impl<'a, F: FieldExtension> AddAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
177 #[inline]
178 fn add_assign(&mut self, rhs: &'a SubfieldElement<F>) {
179 *self = *self + rhs;
180 }
181}
182
183#[macros::op_variants(owned, borrowed, flipped)]
186impl<F: FieldExtension> Sub<&SubfieldElement<F>> for SubfieldElement<F> {
187 type Output = SubfieldElement<F>;
188
189 #[inline]
190 fn sub(self, rhs: &SubfieldElement<F>) -> Self::Output {
191 SubfieldElement(self.0 - rhs.0)
192 }
193}
194
195#[macros::op_variants(owned)]
196impl<'a, F: FieldExtension> SubAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
197 #[inline]
198 fn sub_assign(&mut self, rhs: &'a SubfieldElement<F>) {
199 *self = *self - rhs;
200 }
201}
202
203#[macros::op_variants(owned, borrowed, flipped_commutative)]
206impl<F: FieldExtension> Mul<&SubfieldElement<F>> for SubfieldElement<F> {
207 type Output = SubfieldElement<F>;
208
209 #[inline]
210 fn mul(self, rhs: &SubfieldElement<F>) -> Self::Output {
211 SubfieldElement(self.0 * rhs.0)
212 }
213}
214
215#[macros::op_variants(owned, borrowed, flipped_commutative)]
216impl<F: FieldExtension> Mul<&FieldElement<F>> for SubfieldElement<F> {
217 type Output = FieldElement<F>;
218
219 #[inline]
220 fn mul(self, rhs: &FieldElement<F>) -> Self::Output {
221 FieldElement(rhs.0 * self.0)
222 }
223}
224
225#[macros::op_variants(owned)]
226impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for SubfieldElement<F> {
227 #[inline]
228 fn mul_assign(&mut self, rhs: &'a SubfieldElement<F>) {
229 *self = *self * rhs;
230 }
231}
232
233#[macros::op_variants(borrowed)]
236impl<F: FieldExtension> Neg for SubfieldElement<F> {
237 type Output = SubfieldElement<F>;
238
239 #[inline]
240 fn neg(self) -> Self::Output {
241 SubfieldElement(-self.0)
242 }
243}
244
245#[macros::op_variants(owned, borrowed, flipped)]
248impl<F: FieldExtension> Div<&SubfieldElement<F>> for SubfieldElement<F> {
249 type Output = CtOption<SubfieldElement<F>>;
250
251 #[inline]
252 fn div(self, rhs: &SubfieldElement<F>) -> Self::Output {
253 rhs.0.invert().map(|inv| SubfieldElement(self.0 * inv))
254 }
255}
256
257impl<F: FieldExtension> ConstantTimeEq for SubfieldElement<F> {
260 #[inline]
261 fn ct_eq(&self, other: &Self) -> Choice {
262 self.0.ct_eq(&other.0)
263 }
264}
265
266impl<F: FieldExtension> ConditionallySelectable for SubfieldElement<F> {
267 #[inline]
268 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
269 let selected = F::Subfield::conditional_select(&a.0, &b.0, choice);
270 SubfieldElement(selected)
271 }
272}
273
274impl<F: FieldExtension> AdditiveShares for SubfieldElement<F> {}
277
278impl<F: FieldExtension> From<bool> for SubfieldElement<F> {
283 #[inline]
284 fn from(value: bool) -> Self {
285 SubfieldElement(F::Subfield::from(value as u64))
286 }
287}
288
289impl<F: FieldExtension> From<u8> for SubfieldElement<F> {
290 #[inline]
291 fn from(value: u8) -> Self {
292 SubfieldElement(F::Subfield::from(value as u64))
293 }
294}
295
296impl<F: FieldExtension> From<u16> for SubfieldElement<F> {
297 #[inline]
298 fn from(value: u16) -> Self {
299 SubfieldElement(F::Subfield::from(value as u64))
300 }
301}
302
303impl<F: FieldExtension> From<u32> for SubfieldElement<F> {
304 #[inline]
305 fn from(value: u32) -> Self {
306 SubfieldElement(F::Subfield::from(value as u64))
307 }
308}
309
310impl<F: FieldExtension> From<u64> for SubfieldElement<F> {
311 #[inline]
312 fn from(value: u64) -> Self {
313 SubfieldElement(F::Subfield::from(value))
314 }
315}
316
317impl<F: FieldExtension> From<u128> for SubfieldElement<F> {
318 #[inline]
319 fn from(value: u128) -> Self {
320 SubfieldElement(F::Subfield::from(value))
321 }
322}
323
324impl<F: PrimeFieldExtension> From<FieldElement<F>> for SubfieldElement<F> {
325 #[inline]
326 fn from(value: FieldElement<F>) -> Self {
327 SubfieldElement(value.0)
328 }
329}
330
331impl<F: FieldExtension> Sum for SubfieldElement<F> {
336 #[inline]
337 fn sum<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
338 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
339 F::Subfield::acc(&mut acc, x.0);
340 acc
341 });
342 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
343 }
344}
345
346impl<'a, F: FieldExtension> Sum<&'a SubfieldElement<F>> for SubfieldElement<F> {
347 #[inline]
348 fn sum<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
349 let tmp = iter.fold(<F::Subfield as AccReduce>::zero_wide(), |mut acc, x| {
350 F::Subfield::acc(&mut acc, x.0);
351 acc
352 });
353 SubfieldElement(F::Subfield::reduce_mod_order(tmp))
354 }
355}
356
357impl<F: FieldExtension> Product for SubfieldElement<F> {
358 #[inline]
359 fn product<I: Iterator<Item = SubfieldElement<F>>>(iter: I) -> Self {
360 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
361 }
362}
363
364impl<'a, F: FieldExtension> Product<&'a SubfieldElement<F>> for SubfieldElement<F> {
365 #[inline]
366 fn product<I: Iterator<Item = &'a SubfieldElement<F>>>(iter: I) -> Self {
367 iter.fold(SubfieldElement::one(), |acc, x| acc * x)
368 }
369}
370
371impl<F: FieldExtension> FromUniformBytes for SubfieldElement<F> {
372 type UniformBytes = <F::Subfield as FromUniformBytes>::UniformBytes;
373
374 fn from_uniform_bytes(bytes: &Array<u8, Self::UniformBytes>) -> Self {
375 Self(F::Subfield::from_uniform_bytes(bytes))
376 }
377}
378
379impl<F: FieldExtension> IntoWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
381 #[inline]
382 fn to_wide(&self) -> <F::Subfield as MulAccReduce>::WideType {
383 <F::Subfield as MulAccReduce>::to_wide(&self.0)
384 }
385
386 #[inline]
387 fn zero_wide() -> <F::Subfield as MulAccReduce>::WideType {
388 <F::Subfield as MulAccReduce>::zero_wide()
389 }
390}
391
392impl<F: FieldExtension> ReduceWide<<F::Subfield as MulAccReduce>::WideType> for SubfieldElement<F> {
393 #[inline]
394 fn reduce_mod_order(a: <F::Subfield as MulAccReduce>::WideType) -> Self {
395 Self(F::Subfield::reduce_mod_order(a))
396 }
397}
398
399impl<F: FieldExtension> MulAccReduce for SubfieldElement<F> {
400 type WideType = <F::Subfield as MulAccReduce>::WideType;
401
402 #[inline]
403 fn mul_acc(acc: &mut Self::WideType, a: Self, b: Self) {
404 F::Subfield::mul_acc(acc, a.0, b.0);
405 }
406}
407
408impl<F: FieldExtension> DefaultDotProduct for SubfieldElement<F> {}
409
410impl<'a, F: FieldExtension> MulAccReduce<&'a Self, Self> for SubfieldElement<F> {
412 type WideType = <F::Subfield as MulAccReduce>::WideType;
413
414 #[inline]
415 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: Self) {
416 F::Subfield::mul_acc(acc, a.0, b.0);
417 }
418}
419
420impl<F: FieldExtension> DefaultDotProduct<&Self, Self> for SubfieldElement<F> {}
421
422impl<'a, F: FieldExtension> MulAccReduce<Self, &'a Self> for SubfieldElement<F> {
424 type WideType = <F::Subfield as MulAccReduce>::WideType;
425
426 #[inline]
427 fn mul_acc(acc: &mut Self::WideType, a: Self, b: &'a Self) {
428 F::Subfield::mul_acc(acc, a.0, b.0);
429 }
430}
431
432impl<F: FieldExtension> DefaultDotProduct<Self, &Self> for SubfieldElement<F> {}
433
434impl<'a, 'b, F: FieldExtension> MulAccReduce<&'a Self, &'b Self> for SubfieldElement<F> {
436 type WideType = <F::Subfield as MulAccReduce>::WideType;
437
438 #[inline]
439 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: &'b Self) {
440 F::Subfield::mul_acc(acc, a.0, b.0);
441 }
442}
443
444impl<F: FieldExtension> DefaultDotProduct<&Self, &Self> for SubfieldElement<F> {}
445
446impl<F: FieldExtension> Zero for SubfieldElement<F> {
451 fn zero() -> Self {
453 SubfieldElement(F::Subfield::ZERO)
454 }
455
456 fn is_zero(&self) -> bool {
457 self.0.is_zero().into()
458 }
459}
460
461impl<F: FieldExtension> One for SubfieldElement<F> {
462 fn one() -> Self {
464 SubfieldElement(F::Subfield::ONE)
465 }
466}
467
468impl<F: FieldExtension> Field for SubfieldElement<F> {
473 const ZERO: Self = SubfieldElement(F::Subfield::ZERO);
474 const ONE: Self = SubfieldElement(F::Subfield::ONE);
475
476 fn random(rng: impl RngCore) -> Self {
477 Self(<F::Subfield as Field>::random(rng))
478 }
479
480 fn square(&self) -> Self {
481 SubfieldElement(self.0.square())
482 }
483
484 fn double(&self) -> Self {
485 SubfieldElement(self.0.double())
486 }
487
488 fn invert(&self) -> CtOption<Self> {
489 self.0.invert().map(SubfieldElement)
490 }
491
492 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
493 let (choice, sqrt) = F::Subfield::sqrt_ratio(&num.0, &div.0);
494 (choice, SubfieldElement(sqrt))
495 }
496}
497
498#[cfg(test)]
499mod tests {
500 use super::*;
501
502 #[test]
503 fn test_subfield_mersenne107_wincode() {
504 let elem = SubfieldElement::<Mersenne107>::new(Mersenne107::from(42u64));
505 let bytes = wincode::serialize(&elem).unwrap();
506
507 let decoded: SubfieldElement<Mersenne107> = wincode::deserialize(&bytes).unwrap();
508
509 assert_eq!(elem, decoded);
510 }
511}