acir_field/
generic_ark.rs

1use num_bigint::BigUint;
2
3/// This trait is extremely unstable and WILL have breaking changes.
4pub trait AcirField:
5    Sized
6    + std::fmt::Display
7    + std::fmt::Debug
8    + Default
9    + Clone
10    + Copy
11    + std::ops::Neg<Output = Self>
12    + std::ops::Add<Self, Output = Self>
13    + std::ops::Sub<Self, Output = Self>
14    + std::ops::Mul<Self, Output = Self>
15    + std::ops::Div<Self, Output = Self>
16    + std::ops::AddAssign<Self>
17    + std::ops::SubAssign<Self>
18    + PartialOrd
19    + From<usize>
20    + From<u128>
21    // + From<u64>
22    + From<u32>
23    // + From<u16>
24    // + From<u8>
25    + From<bool>
26    + std::hash::Hash
27    + Eq
28    + 'static
29{
30    fn one() -> Self;
31    fn zero() -> Self;
32
33    fn is_zero(&self) -> bool;
34    fn is_one(&self) -> bool;
35    fn pow(&self, exponent: &Self) -> Self;
36
37    /// Maximum number of bits needed to represent a field element
38    /// This is not the amount of bits being used to represent a field element
39    /// Example, you only need 254 bits to represent a field element in BN256
40    /// But the representation uses 256 bits, so the top two bits are always zero
41    /// This method would return 254
42    fn max_num_bits() -> u32;
43
44    /// Maximum numbers of bytes needed to represent a field element
45    /// We are not guaranteed that the number of bits being used to represent a field element
46    /// will always be divisible by 8. If the case that it is not, we add one to the max number of bytes
47    /// For example, a max bit size of 254 would give a max byte size of 32.
48    fn max_num_bytes() -> u32;
49
50    fn modulus() -> BigUint;
51
52    /// This is the number of bits required to represent this specific field element
53    fn num_bits(&self) -> u32;
54
55    /// Downcast the field into a `u128`.
56    /// Panic if the value does not fit
57    fn to_u128(self) -> u128;
58
59    /// Downcast the field into a `u128` if it fits into 128 bits, otherwise return `None`.
60    fn try_into_u128(self) -> Option<u128>;
61
62    /// Downcast the field into a `i128`.
63    /// Panic if the value does not fit
64    fn to_i128(self) -> i128;
65
66    fn try_into_i128(self) -> Option<i128>;
67
68    fn try_to_u64(&self) -> Option<u64>;
69
70    fn try_to_u32(&self) -> Option<u32>;
71
72    /// Computes the inverse or returns zero if the inverse does not exist
73    /// Before using this FieldElement, please ensure that this behavior is necessary
74    fn inverse(&self) -> Self;
75
76    /// Returns the vale of this field as a hex string without the `0x` prefix.
77    /// The returned string will have a length equal to the maximum number of hex
78    /// digits needed to represent the maximum value of this field.
79    fn to_hex(self) -> String;
80
81    /// Returns the value of this field as a hex string with leading zeroes removed,
82    /// prepended with `0x`.
83    /// A singular '0' will be prepended as well if the trimmed string has an odd length.
84    fn to_short_hex(self) -> String;
85
86    fn from_hex(hex_str: &str) -> Option<Self>;
87
88    fn to_be_bytes(self) -> Vec<u8>;
89
90    /// Converts bytes into a FieldElement and applies a reduction if needed.
91    fn from_be_bytes_reduce(bytes: &[u8]) -> Self;
92
93    /// Converts bytes in little-endian order into a FieldElement and applies a reduction if needed.
94    fn from_le_bytes_reduce(bytes: &[u8]) -> Self;
95
96    /// Converts the field element to a vector of bytes in little-endian order
97    fn to_le_bytes(self) -> Vec<u8>;
98
99    /// Returns the closest number of bytes to the bits specified
100    /// This method truncates
101    fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec<u8>;
102}
103
104/// Define a _newtype_ wrapper around an `AcirField` by implementing all the
105/// boilerplate for forwarding the field operations.
106///
107/// This allows the wrapper to implement traits such as `Arbitrary`, and then
108/// be used by code that is generic in `F: AcirField`.
109///
110/// # Example
111/// ```ignore
112/// field_wrapper!(TestField, FieldElement);
113/// ```
114#[macro_export]
115macro_rules! field_wrapper {
116    ($wrapper:ident, $field:ident) => {
117        #[derive(
118            Clone,
119            Debug,
120            PartialEq,
121            Eq,
122            Hash,
123            PartialOrd,
124            Copy,
125            Default,
126            serde::Serialize,
127            serde::Deserialize,
128        )]
129        struct $wrapper(pub $field);
130
131        impl $crate::AcirField for $wrapper {
132            fn one() -> Self {
133                Self($field::one())
134            }
135
136            fn zero() -> Self {
137                Self($field::zero())
138            }
139
140            fn is_zero(&self) -> bool {
141                self.0.is_zero()
142            }
143
144            fn is_one(&self) -> bool {
145                self.0.is_one()
146            }
147
148            fn pow(&self, exponent: &Self) -> Self {
149                Self(self.0.pow(&exponent.0))
150            }
151
152            fn max_num_bits() -> u32 {
153                $field::max_num_bits()
154            }
155
156            fn max_num_bytes() -> u32 {
157                $field::max_num_bytes()
158            }
159
160            fn modulus() -> ::num_bigint::BigUint {
161                $field::modulus()
162            }
163
164            fn num_bits(&self) -> u32 {
165                self.0.num_bits()
166            }
167
168            fn to_u128(self) -> u128 {
169                self.0.to_u128()
170            }
171
172            fn try_into_u128(self) -> Option<u128> {
173                self.0.try_into_u128()
174            }
175
176            fn try_into_i128(self) -> Option<i128> {
177                self.0.try_into_i128()
178            }
179
180            fn to_i128(self) -> i128 {
181                self.0.to_i128()
182            }
183
184            fn try_to_u64(&self) -> Option<u64> {
185                self.0.try_to_u64()
186            }
187
188            fn try_to_u32(&self) -> Option<u32> {
189                self.0.try_to_u32()
190            }
191
192            fn inverse(&self) -> Self {
193                Self(self.0.inverse())
194            }
195
196            fn to_hex(self) -> String {
197                self.0.to_hex()
198            }
199
200            fn to_short_hex(self) -> String {
201                self.0.to_short_hex()
202            }
203
204            fn from_hex(hex_str: &str) -> Option<Self> {
205                $field::from_hex(hex_str).map(Self)
206            }
207
208            fn to_be_bytes(self) -> Vec<u8> {
209                self.0.to_be_bytes()
210            }
211
212            fn from_be_bytes_reduce(bytes: &[u8]) -> Self {
213                Self($field::from_be_bytes_reduce(bytes))
214            }
215
216            fn from_le_bytes_reduce(bytes: &[u8]) -> Self {
217                Self($field::from_le_bytes_reduce(bytes))
218            }
219
220            fn to_le_bytes(self) -> Vec<u8> {
221                self.0.to_le_bytes()
222            }
223
224            fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec<u8> {
225                self.0.fetch_nearest_bytes(num_bits)
226            }
227        }
228
229        impl From<bool> for $wrapper {
230            fn from(value: bool) -> Self {
231                Self($field::from(value))
232            }
233        }
234
235        impl From<u128> for $wrapper {
236            fn from(value: u128) -> Self {
237                Self($field::from(value))
238            }
239        }
240
241        impl From<u32> for $wrapper {
242            fn from(value: u32) -> Self {
243                Self($field::from(value))
244            }
245        }
246
247        impl From<usize> for $wrapper {
248            fn from(value: usize) -> Self {
249                Self($field::from(value))
250            }
251        }
252
253        impl std::ops::SubAssign<$wrapper> for $wrapper {
254            fn sub_assign(&mut self, rhs: $wrapper) {
255                self.0.sub_assign(rhs.0);
256            }
257        }
258
259        impl std::ops::AddAssign<$wrapper> for $wrapper {
260            fn add_assign(&mut self, rhs: $wrapper) {
261                self.0.add_assign(rhs.0);
262            }
263        }
264
265        impl std::ops::Add<$wrapper> for $wrapper {
266            type Output = Self;
267
268            fn add(self, rhs: $wrapper) -> Self::Output {
269                Self(self.0.add(rhs.0))
270            }
271        }
272
273        impl std::ops::Sub<$wrapper> for $wrapper {
274            type Output = Self;
275
276            fn sub(self, rhs: $wrapper) -> Self::Output {
277                Self(self.0.sub(rhs.0))
278            }
279        }
280
281        impl std::ops::Mul<$wrapper> for $wrapper {
282            type Output = Self;
283
284            fn mul(self, rhs: $wrapper) -> Self::Output {
285                Self(self.0.mul(rhs.0))
286            }
287        }
288
289        impl std::ops::Div<$wrapper> for $wrapper {
290            type Output = Self;
291
292            fn div(self, rhs: $wrapper) -> Self::Output {
293                Self(self.0.div(rhs.0))
294            }
295        }
296
297        impl std::ops::Neg for $wrapper {
298            type Output = Self;
299
300            fn neg(self) -> Self::Output {
301                Self(self.0.neg())
302            }
303        }
304
305        impl std::fmt::Display for $wrapper {
306            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
307                self.0.fmt(f)
308            }
309        }
310    };
311}