primitives/algebra/field/
field_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::{distributions::Standard, prelude::Distribution, RngCore};
11use serde::{Deserialize, Serialize};
12use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
13
14use crate::{
15 algebra::{
16 field::{FieldExtension, PrimeFieldExtension, SubfieldElement},
17 ops::{AccReduce, DefaultDotProduct, IntoWide, MulAccReduce, ReduceWide},
18 uniform_bytes::FromUniformBytes,
19 },
20 errors::SerializationError,
21 impl_borrow_variants,
22 impl_commutative,
23 sharing::unauthenticated::AdditiveShares,
24};
25
26#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
28pub struct FieldElement<F: FieldExtension>(pub(crate) F);
29
30impl<F: FieldExtension> FieldElement<F> {
31 #[inline]
33 pub fn new(inner: F) -> Self {
34 FieldElement(inner)
35 }
36
37 #[inline]
39 pub fn inner(&self) -> F {
40 self.0
41 }
42
43 #[inline]
45 pub fn pow(&self, exp: u64) -> Self {
46 FieldElement::new(self.0.pow([exp]))
47 }
48
49 #[inline]
51 pub fn from_be_bytes(bytes: &[u8]) -> Result<FieldElement<F>, SerializationError> {
52 let bytes = bytes.iter().rev().copied().collect::<Vec<_>>();
53 Ok(FieldElement(
54 F::from_le_bytes(&bytes).ok_or(SerializationError::DeserializationFailed)?,
55 ))
56 }
57
58 #[inline]
59 pub fn from_le_bytes(bytes: &[u8]) -> Result<FieldElement<F>, SerializationError> {
60 Ok(FieldElement(
61 F::from_le_bytes(bytes).ok_or(SerializationError::DeserializationFailed)?,
62 ))
63 }
64
65 #[inline]
67 pub fn to_le_bytes(&self) -> impl IntoIterator<Item = u8> + '_ {
68 self.0.to_le_bytes()
69 }
70
71 #[inline]
73 pub fn to_be_bytes(&self) -> impl IntoIterator<Item = u8> {
74 self.0
75 .to_le_bytes()
76 .into_iter()
77 .collect::<Vec<_>>()
78 .into_iter()
79 .rev()
80 .collect::<Vec<_>>()
81 }
82
83 pub fn to_biguint(&self) -> num_bigint::BigUint {
84 num_bigint::BigUint::from_bytes_le(
85 self.to_le_bytes().into_iter().collect::<Vec<_>>().as_ref(),
86 )
87 }
88}
89
90impl<F: FieldExtension> Distribution<FieldElement<F>> for Standard {
91 fn sample<R: RngCore + ?Sized>(&self, rng: &mut R) -> FieldElement<F> {
92 FieldElement(F::random(rng))
93 }
94}
95
96impl<F: FieldExtension> Default for FieldElement<F> {
97 fn default() -> Self {
98 Self::zero()
99 }
100}
101
102impl<F: FieldExtension> Serialize for FieldElement<F> {
103 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
104 let bytes = self
105 .to_le_bytes()
106 .into_iter()
107 .collect::<Array<u8, F::FieldBytesSize>>();
108 serde_bytes::serialize(AsRef::<[u8]>::as_ref(&bytes), serializer)
109 }
110}
111
112impl<'de, F: FieldExtension> Deserialize<'de> for FieldElement<F> {
113 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
114 let bytes: &[u8] = serde_bytes::deserialize(deserializer)?;
115 let field_elem = FieldElement::from_le_bytes(bytes).map_err(|err| {
116 serde::de::Error::custom(format!("Failed to deserialize field element: {err:?}"))
117 })?;
118 Ok(field_elem)
119 }
120}
121
122impl<F: FieldExtension> Display for FieldElement<F> {
123 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
124 write!(f, "{self:?}")
125 }
126}
127
128impl<F: FieldExtension> Add<&FieldElement<F>> for &FieldElement<F> {
135 type Output = FieldElement<F>;
136
137 #[inline]
138 fn add(self, rhs: &FieldElement<F>) -> Self::Output {
139 FieldElement(self.0 + rhs.0)
140 }
141}
142
143impl_borrow_variants!(FieldElement<F>, Add, add, +, FieldElement<F>, F: FieldExtension);
144
145impl<F: FieldExtension> AddAssign for FieldElement<F> {
148 #[inline]
149 fn add_assign(&mut self, rhs: FieldElement<F>) {
150 *self = *self + rhs;
151 }
152}
153
154impl<'a, F: FieldExtension> AddAssign<&'a FieldElement<F>> for FieldElement<F> {
155 #[inline]
156 fn add_assign(&mut self, rhs: &'a FieldElement<F>) {
157 *self = *self + rhs;
158 }
159}
160
161impl<F: FieldExtension> Sub<&FieldElement<F>> for &FieldElement<F> {
164 type Output = FieldElement<F>;
165
166 #[inline]
167 fn sub(self, rhs: &FieldElement<F>) -> Self::Output {
168 FieldElement(self.0 - rhs.0)
169 }
170}
171impl_borrow_variants!(FieldElement<F>, Sub, sub, -, FieldElement<F>, F: FieldExtension);
172
173impl<F: FieldExtension> SubAssign for FieldElement<F> {
176 #[inline]
177 fn sub_assign(&mut self, rhs: FieldElement<F>) {
178 *self = *self - rhs;
179 }
180}
181
182impl<'a, F: FieldExtension> SubAssign<&'a FieldElement<F>> for FieldElement<F> {
183 #[inline]
184 fn sub_assign(&mut self, rhs: &'a FieldElement<F>) {
185 *self = *self - rhs;
186 }
187}
188
189impl<F: FieldExtension> Mul<&FieldElement<F>> for &FieldElement<F> {
192 type Output = FieldElement<F>;
193
194 #[inline]
195 fn mul(self, rhs: &FieldElement<F>) -> Self::Output {
196 FieldElement(self.0 * rhs.0)
197 }
198}
199impl_borrow_variants!(FieldElement<F>, Mul, mul, *, FieldElement<F>, F: FieldExtension);
200
201impl<F: FieldExtension> Mul<&SubfieldElement<F>> for &FieldElement<F> {
202 type Output = FieldElement<F>;
203
204 #[inline]
205 fn mul(self, rhs: &SubfieldElement<F>) -> Self::Output {
206 FieldElement(self.0 * rhs.0)
207 }
208}
209impl_borrow_variants!(FieldElement<F>, Mul, mul, *, SubfieldElement<F>, F: FieldExtension);
210impl_commutative!(FieldElement<F>, Mul, mul, *, SubfieldElement<F>, F: FieldExtension);
211
212impl<F: FieldExtension> MulAssign for FieldElement<F> {
215 #[inline]
216 fn mul_assign(&mut self, rhs: FieldElement<F>) {
217 *self = *self * rhs;
218 }
219}
220
221impl<'a, F: FieldExtension> MulAssign<&'a FieldElement<F>> for FieldElement<F> {
222 #[inline]
223 fn mul_assign(&mut self, rhs: &'a FieldElement<F>) {
224 *self = *self * rhs;
225 }
226}
227
228impl<F: FieldExtension> MulAssign<SubfieldElement<F>> for FieldElement<F> {
229 #[inline]
230 fn mul_assign(&mut self, rhs: SubfieldElement<F>) {
231 *self = *self * rhs;
232 }
233}
234
235impl<'a, F: FieldExtension> MulAssign<&'a SubfieldElement<F>> for FieldElement<F> {
236 #[inline]
237 fn mul_assign(&mut self, rhs: &'a SubfieldElement<F>) {
238 *self = *self * rhs;
239 }
240}
241
242impl<F: FieldExtension> Neg for &FieldElement<F> {
245 type Output = FieldElement<F>;
246
247 #[inline]
248 fn neg(self) -> Self::Output {
249 FieldElement(-self.0)
250 }
251}
252impl_borrow_variants!(FieldElement<F>, Neg, neg, -, F: FieldExtension);
253
254impl<F: FieldExtension> Div<&FieldElement<F>> for &FieldElement<F> {
257 type Output = CtOption<FieldElement<F>>;
258
259 #[inline]
260 fn div(self, rhs: &FieldElement<F>) -> Self::Output {
261 rhs.0.invert().map(|inv| FieldElement(self.0 * inv))
262 }
263}
264
265impl<F: FieldExtension> Div<FieldElement<F>> for FieldElement<F> {
266 type Output = CtOption<FieldElement<F>>;
267
268 #[inline]
269 fn div(self, rhs: FieldElement<F>) -> Self::Output {
270 (&self).div(&rhs)
271 }
272}
273
274impl<F: FieldExtension> Div<FieldElement<F>> for &FieldElement<F> {
275 type Output = CtOption<FieldElement<F>>;
276
277 #[inline]
278 fn div(self, rhs: FieldElement<F>) -> Self::Output {
279 rhs.0.invert().map(|inv| FieldElement(self.0 * inv))
280 }
281}
282
283impl<F: FieldExtension> Div<&FieldElement<F>> for FieldElement<F> {
284 type Output = CtOption<FieldElement<F>>;
285
286 #[inline]
287 fn div(self, rhs: &FieldElement<F>) -> Self::Output {
288 rhs.0.invert().map(|inv| FieldElement(self.0 * inv))
289 }
290}
291
292impl<F: FieldExtension> ConstantTimeEq for FieldElement<F> {
295 #[inline]
296 fn ct_eq(&self, other: &Self) -> Choice {
297 self.0.ct_eq(&other.0)
298 }
299}
300
301impl<F: FieldExtension> ConditionallySelectable for FieldElement<F> {
302 #[inline]
303 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
304 let selected = F::conditional_select(&a.0, &b.0, choice);
305 FieldElement(selected)
306 }
307}
308
309impl<F: FieldExtension> AdditiveShares for FieldElement<F> {}
312
313impl<F: FieldExtension> From<bool> for FieldElement<F> {
318 #[inline]
319 fn from(value: bool) -> Self {
320 FieldElement(F::from(value as u64))
321 }
322}
323
324impl<F: FieldExtension> From<u8> for FieldElement<F> {
325 #[inline]
326 fn from(value: u8) -> Self {
327 FieldElement(F::from(value as u64))
328 }
329}
330
331impl<F: FieldExtension> From<u16> for FieldElement<F> {
332 #[inline]
333 fn from(value: u16) -> Self {
334 FieldElement(F::from(value as u64))
335 }
336}
337
338impl<F: FieldExtension> From<u32> for FieldElement<F> {
339 #[inline]
340 fn from(value: u32) -> Self {
341 FieldElement(F::from(value as u64))
342 }
343}
344
345impl<F: FieldExtension> From<u64> for FieldElement<F> {
346 #[inline]
347 fn from(value: u64) -> Self {
348 FieldElement(F::from(value))
349 }
350}
351
352impl<F: FieldExtension> From<u128> for FieldElement<F> {
353 #[inline]
354 fn from(value: u128) -> Self {
355 FieldElement(F::from(value))
356 }
357}
358
359impl<F: PrimeFieldExtension> From<SubfieldElement<F>> for FieldElement<F> {
360 #[inline]
361 fn from(value: SubfieldElement<F>) -> Self {
362 FieldElement(value.0)
363 }
364}
365
366impl<F: FieldExtension> Sum for FieldElement<F> {
370 #[inline]
371 fn sum<I: Iterator<Item = FieldElement<F>>>(iter: I) -> Self {
372 let tmp = iter.fold(<F as AccReduce>::zero_wide(), |mut acc, x| {
373 F::acc(&mut acc, x.0);
374 acc
375 });
376
377 FieldElement(F::reduce_mod_order(tmp))
378 }
379}
380
381impl<'a, F: FieldExtension> Sum<&'a FieldElement<F>> for FieldElement<F> {
382 #[inline]
383 fn sum<I: Iterator<Item = &'a FieldElement<F>>>(iter: I) -> Self {
384 let tmp = iter.fold(<F as AccReduce>::zero_wide(), |mut acc, x| {
385 F::acc(&mut acc, x.0);
386 acc
387 });
388
389 FieldElement(F::reduce_mod_order(tmp))
390 }
391}
392
393impl<F: FieldExtension> Product for FieldElement<F> {
394 #[inline]
395 fn product<I: Iterator<Item = FieldElement<F>>>(iter: I) -> Self {
396 iter.fold(FieldElement::one(), |acc, x| acc * x)
397 }
398}
399
400impl<'a, F: FieldExtension> Product<&'a FieldElement<F>> for FieldElement<F> {
401 #[inline]
402 fn product<I: Iterator<Item = &'a FieldElement<F>>>(iter: I) -> Self {
403 iter.fold(FieldElement::one(), |acc, x| acc * x)
404 }
405}
406
407impl<F: FieldExtension> FromUniformBytes for FieldElement<F> {
408 type UniformBytes = <F as FromUniformBytes>::UniformBytes;
409
410 fn from_uniform_bytes(bytes: &Array<u8, Self::UniformBytes>) -> Self {
411 Self(F::from_uniform_bytes(bytes))
412 }
413}
414
415impl<F: FieldExtension> IntoWide<<F as MulAccReduce>::WideType> for FieldElement<F> {
417 #[inline]
418 fn to_wide(&self) -> <F as MulAccReduce>::WideType {
419 <F as MulAccReduce>::to_wide(&self.0)
420 }
421
422 #[inline]
423 fn zero_wide() -> <F as MulAccReduce>::WideType {
424 <F as MulAccReduce>::zero_wide()
425 }
426}
427
428impl<F: FieldExtension> ReduceWide<<F as MulAccReduce>::WideType> for FieldElement<F> {
429 #[inline]
430 fn reduce_mod_order(a: <F as MulAccReduce>::WideType) -> Self {
431 Self(F::reduce_mod_order(a))
432 }
433}
434
435impl<F: FieldExtension> MulAccReduce for FieldElement<F> {
436 type WideType = <F as MulAccReduce>::WideType;
437
438 #[inline]
439 fn mul_acc(acc: &mut Self::WideType, a: Self, b: Self) {
440 F::mul_acc(acc, a.0, b.0);
441 }
442}
443
444impl<F: FieldExtension> DefaultDotProduct for FieldElement<F> {}
445
446impl<'a, F: FieldExtension> MulAccReduce<&'a Self, Self> for FieldElement<F> {
448 type WideType = <F as MulAccReduce>::WideType;
449
450 #[inline]
451 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: Self) {
452 F::mul_acc(acc, a.0, b.0);
453 }
454}
455
456impl<F: FieldExtension> DefaultDotProduct<&Self, Self> for FieldElement<F> {}
457
458impl<'a, F: FieldExtension> MulAccReduce<Self, &'a Self> for FieldElement<F> {
460 type WideType = <F as MulAccReduce>::WideType;
461
462 #[inline]
463 fn mul_acc(acc: &mut Self::WideType, a: Self, b: &'a Self) {
464 F::mul_acc(acc, a.0, b.0);
465 }
466}
467
468impl<F: FieldExtension> DefaultDotProduct<Self, &Self> for FieldElement<F> {}
469
470impl<'a, 'b, F: FieldExtension> MulAccReduce<&'a Self, &'b Self> for FieldElement<F> {
472 type WideType = <F as MulAccReduce>::WideType;
473
474 #[inline]
475 fn mul_acc(acc: &mut Self::WideType, a: &'a Self, b: &'b Self) {
476 F::mul_acc(acc, a.0, b.0);
477 }
478}
479
480impl<F: FieldExtension> DefaultDotProduct<&Self, &Self> for FieldElement<F> {}
481
482impl<F: FieldExtension> Zero for FieldElement<F> {
487 fn zero() -> Self {
489 FieldElement(F::ZERO)
490 }
491
492 fn is_zero(&self) -> bool {
493 self.0.is_zero().into()
494 }
495}
496
497impl<F: FieldExtension> One for FieldElement<F> {
498 fn one() -> Self {
500 FieldElement(F::ONE)
501 }
502}
503
504impl<F: FieldExtension> Field for FieldElement<F> {
509 const ZERO: Self = FieldElement(F::ZERO);
510 const ONE: Self = FieldElement(F::ONE);
511
512 fn random(rng: impl RngCore) -> Self {
513 Self(F::random(rng))
514 }
515
516 fn square(&self) -> Self {
517 FieldElement(self.0.square())
518 }
519
520 fn double(&self) -> Self {
521 FieldElement(self.0.double())
522 }
523
524 fn invert(&self) -> CtOption<Self> {
525 self.0.invert().map(FieldElement)
526 }
527
528 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
529 let (choice, sqrt) = F::sqrt_ratio(&num.0, &div.0);
530 (choice, FieldElement(sqrt))
531 }
532}