openzeppelin_crypto/field/mod.rs
1//! This module provides common arithmetics to work with finite fields.
2//! Implementations of some used fields provided in the [`instance`]
3//! module.
4//!
5//! Abstractions and api in this module are similar to Arkworks Algebra [ark-ff
6//! library].
7//!
8//! Here is an example operations over a prime finite field (aka Fp) with a
9//! prime modulus `17` and generator element `3`.
10//!
11//! # Examples
12//!
13//! ```rust
14//! use openzeppelin_crypto::{
15//! arithmetic::uint::U64,
16//! field::{
17//! fp::{Fp64, FpParams, LIMBS_64},
18//! group::AdditiveGroup,
19//! Field,
20//! },
21//! fp_from_num,
22//! from_num,
23//! };
24//!
25//! pub type ExampleField = Fp64<FpParam>;
26//! pub struct FpParam;
27//! impl FpParams<LIMBS_64> for FpParam {
28//! const MODULUS: U64 = from_num!("17");
29//! const GENERATOR: Fp64<FpParam> = fp_from_num!("3");
30//! }
31//!
32//! # fn main() {
33//! let a = ExampleField::from(9);
34//! let b = ExampleField::from(10);
35//!
36//! assert_eq!(a, ExampleField::from(26)); // 26 = 9 mod 17
37//! assert_eq!(a - b, ExampleField::from(16)); // -1 = 16 mod 17
38//! assert_eq!(a + b, ExampleField::from(2)); // 19 = 2 mod 17
39//! assert_eq!(a * b, ExampleField::from(5)); // 90 = 5 mod 17
40//! assert_eq!(a.square(), ExampleField::from(13)); // 81 = 13 mod 17
41//! assert_eq!(b.double(), ExampleField::from(3)); // 20 = 3 mod 17
42//! assert_eq!(a / b, a * b.inverse().unwrap()); // need to unwrap since `b` could be 0 which is not invertible
43//! # }
44//! ```
45//!
46//! [ark-ff library]: https://github.com/arkworks-rs/algebra/tree/master/ff
47use core::{
48 fmt::{Debug, Display},
49 hash::Hash,
50 iter::Product,
51 ops::{Div, DivAssign, Neg},
52};
53
54use group::AdditiveGroup;
55use num_traits::{One, Zero};
56use zeroize::Zeroize;
57
58use crate::bits::BitIteratorBE;
59
60pub mod fp;
61pub mod group;
62pub mod instance;
63pub mod prime;
64
65/// Defines an abstract field.
66/// Types implementing [`Field`] support common field operations such as
67/// addition, subtraction, multiplication, and inverses.
68pub trait Field:
69 'static
70 + Copy
71 + Clone
72 + Debug
73 + Display
74 + Default
75 + Send
76 + Sync
77 + Eq
78 + Zero
79 + One
80 + Ord
81 + Neg<Output = Self>
82 + Zeroize
83 + Sized
84 + Hash
85 + AdditiveGroup<Scalar = Self>
86 + Div<Self, Output = Self>
87 + DivAssign<Self>
88 + for<'a> Div<&'a Self, Output = Self>
89 + for<'a> DivAssign<&'a Self>
90 + for<'a> Div<&'a mut Self, Output = Self>
91 + for<'a> DivAssign<&'a mut Self>
92 + for<'a> Product<&'a Self>
93 + From<u128>
94 + From<u64>
95 + From<u32>
96 + From<u16>
97 + From<u8>
98 + From<i128>
99 + From<i64>
100 + From<i32>
101 + From<i16>
102 + From<i8>
103 + From<bool>
104 + Product<Self>
105{
106 /// The multiplicative identity of the field.
107 const ONE: Self;
108
109 /// Returns the extension degree of this field.
110 #[must_use]
111 fn extension_degree() -> usize;
112
113 /// Returns `self * self`.
114 #[must_use]
115 fn square(&self) -> Self;
116
117 /// Squares `self` in place.
118 fn square_in_place(&mut self) -> &mut Self;
119
120 /// Computes the multiplicative inverse of `self` if `self` is nonzero.
121 fn inverse(&self) -> Option<Self>;
122
123 /// If `self.inverse().is_none()`, this just returns `None`. Otherwise, it
124 /// sets `self` to `self.inverse().unwrap()`.
125 fn inverse_in_place(&mut self) -> Option<&mut Self>;
126
127 /// Returns `self^exp`, where `exp` is an integer.
128 ///
129 /// NOTE: Consumers should pass `exp`'s type `S` with the least bit size
130 /// possible.
131 /// e.g. for `pow(12)` u8 type is small enough to represent `12`.
132 #[must_use]
133 fn pow<S: BitIteratorBE>(&self, exp: S) -> Self {
134 // Variant `Option::<Self>::None` corresponds to `one`.
135 // This approach removes pointless multiplications by one, that
136 // are still expensive.
137 let mut res: Option<Self> = None;
138
139 for has_bit in exp.bit_be_trimmed_iter() {
140 // If res is not empty, square it.
141 if let Some(res) = &mut res {
142 res.square_in_place();
143 }
144
145 // If bit is set,
146 if has_bit {
147 match res {
148 None => {
149 // and res is empty, set it to self.
150 res = Some(*self);
151 }
152 Some(ref mut res) => {
153 // and res is not empty, multiply it by self.
154 *res *= self;
155 }
156 }
157 }
158 }
159
160 // If res is empty, return one.
161 res.unwrap_or(Self::ONE)
162 }
163
164 /// Returns `sum([a_i * b_i])`.
165 #[inline]
166 fn sum_of_products<const T: usize>(a: &[Self; T], b: &[Self; T]) -> Self {
167 let mut sum = Self::zero();
168 for i in 0..a.len() {
169 sum += a[i] * b[i];
170 }
171 sum
172 }
173}