1#![no_std]
3
4mod poseidon2;
5
6extern crate alloc;
7
8use alloc::vec::Vec;
9use core::fmt::{Debug, Display, Formatter};
10use core::hash::{Hash, Hasher};
11use core::iter::{Product, Sum};
12use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};
13use core::{array, fmt, stringify};
14
15pub use halo2curves::bn256::Fr as FFBn254Fr;
16use halo2curves::ff::{Field as FFField, PrimeField as FFPrimeField};
17use halo2curves::serde::SerdeObject;
18use num_bigint::BigUint;
19use p3_field::integers::QuotientMap;
20use p3_field::{
21 Field, InjectiveMonomial, Packable, PrimeCharacteristicRing, PrimeField, RawDataSerializable,
22 TwoAdicField, quotient_map_small_int,
23};
24pub use poseidon2::Poseidon2Bn254;
25use rand::Rng;
26use rand::distr::{Distribution, StandardUniform};
27use serde::{Deserialize, Deserializer, Serialize};
28
29#[derive(Copy, Clone, Default, Eq, PartialEq)]
31pub struct Bn254Fr {
32 pub(crate) value: FFBn254Fr,
33}
34
35impl Bn254Fr {
36 pub(crate) const fn new(value: FFBn254Fr) -> Self {
37 Self { value }
38 }
39}
40
41impl Serialize for Bn254Fr {
42 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
45 let bytes = self.value.to_raw_bytes();
46 serializer.serialize_bytes(&bytes)
47 }
48}
49
50impl<'de> Deserialize<'de> for Bn254Fr {
51 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
56 let bytes: Vec<u8> = Deserialize::deserialize(d)?;
57
58 FFBn254Fr::from_raw_bytes(&bytes)
59 .map(Self::new)
60 .ok_or_else(|| serde::de::Error::custom("Invalid field element"))
61 }
62}
63
64impl Packable for Bn254Fr {}
65
66impl Hash for Bn254Fr {
67 fn hash<H: Hasher>(&self, state: &mut H) {
68 for byte in self.value.to_repr().as_ref() {
69 state.write_u8(*byte);
70 }
71 }
72}
73
74impl Ord for Bn254Fr {
75 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
76 self.value.cmp(&other.value)
77 }
78}
79
80impl PartialOrd for Bn254Fr {
81 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
82 Some(self.cmp(other))
83 }
84}
85
86impl Display for Bn254Fr {
87 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
88 self.value.fmt(f)
89 }
90}
91
92impl Debug for Bn254Fr {
93 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
94 Debug::fmt(&self.value, f)
95 }
96}
97
98impl PrimeCharacteristicRing for Bn254Fr {
99 type PrimeSubfield = Self;
100
101 const ZERO: Self = Self::new(FFBn254Fr::ZERO);
102 const ONE: Self = Self::new(FFBn254Fr::ONE);
103 const TWO: Self = Self::new(FFBn254Fr::from_raw([2u64, 0, 0, 0]));
104
105 const NEG_ONE: Self = Self::new(FFBn254Fr::from_raw([
107 0x43e1f593f0000000,
108 0x2833e84879b97091,
109 0xb85045b68181585d,
110 0x30644e72e131a029,
111 ]));
112
113 #[inline]
114 fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
115 f
116 }
117}
118
119impl InjectiveMonomial<5> for Bn254Fr {}
123
124impl RawDataSerializable for Bn254Fr {
128 const NUM_BYTES: usize = 32;
129
130 #[allow(refining_impl_trait)]
131 #[inline]
132 fn into_bytes(self) -> [u8; 32] {
133 self.value.to_repr().into()
135 }
136
137 #[inline]
138 fn into_u32_stream(input: impl IntoIterator<Item = Self>) -> impl IntoIterator<Item = u32> {
139 input
144 .into_iter()
145 .flat_map(|x| x.as_canonical_biguint().to_u32_digits())
146 }
147
148 #[inline]
149 fn into_u64_stream(input: impl IntoIterator<Item = Self>) -> impl IntoIterator<Item = u64> {
150 input
151 .into_iter()
152 .flat_map(|x| x.as_canonical_biguint().to_u64_digits())
153 }
154
155 #[inline]
156 fn into_parallel_byte_streams<const N: usize>(
157 input: impl IntoIterator<Item = [Self; N]>,
158 ) -> impl IntoIterator<Item = [u8; N]> {
159 input.into_iter().flat_map(|vector| {
160 let bytes = vector.map(|elem| elem.into_bytes());
161 (0..Self::NUM_BYTES).map(move |i| array::from_fn(|j| bytes[j][i]))
162 })
163 }
164
165 #[inline]
166 fn into_parallel_u32_streams<const N: usize>(
167 input: impl IntoIterator<Item = [Self; N]>,
168 ) -> impl IntoIterator<Item = [u32; N]> {
169 input.into_iter().flat_map(|vector| {
170 let u32s = vector.map(|elem| elem.as_canonical_biguint().to_u32_digits());
171 (0..(Self::NUM_BYTES / 4)).map(move |i| array::from_fn(|j| u32s[j][i]))
172 })
173 }
174
175 #[inline]
176 fn into_parallel_u64_streams<const N: usize>(
177 input: impl IntoIterator<Item = [Self; N]>,
178 ) -> impl IntoIterator<Item = [u64; N]> {
179 input.into_iter().flat_map(|vector| {
180 let u64s = vector.map(|elem| elem.as_canonical_biguint().to_u64_digits());
181 (0..(Self::NUM_BYTES / 8)).map(move |i| array::from_fn(|j| u64s[j][i]))
182 })
183 }
184}
185
186impl Field for Bn254Fr {
187 type Packing = Self;
188
189 const GENERATOR: Self = Self::new(FFBn254Fr::from_raw([5u64, 0, 0, 0]));
191
192 fn is_zero(&self) -> bool {
193 self.value.is_zero().into()
194 }
195
196 fn try_inverse(&self) -> Option<Self> {
197 let inverse = self.value.invert();
198
199 if inverse.is_some().into() {
200 Some(Self::new(inverse.unwrap()))
201 } else {
202 None
203 }
204 }
205
206 fn order() -> BigUint {
208 BigUint::from_slice(&[
209 0xf0000001, 0x43e1f593, 0x79b97091, 0x2833e848, 0x8181585d, 0xb85045b6, 0xe131a029,
210 0x30644e72,
211 ])
212 }
213}
214
215quotient_map_small_int!(Bn254Fr, u128, [u8, u16, u32, u64]);
216quotient_map_small_int!(Bn254Fr, i128, [i8, i16, i32, i64]);
217
218impl QuotientMap<u128> for Bn254Fr {
219 #[inline]
221 fn from_int(int: u128) -> Self {
222 Self::new(FFBn254Fr::from_raw([int as u64, (int >> 64) as u64, 0, 0]))
223 }
224
225 #[inline]
227 fn from_canonical_checked(int: u128) -> Option<Self> {
228 Some(Self::from_int(int))
229 }
230
231 #[inline]
233 unsafe fn from_canonical_unchecked(int: u128) -> Self {
234 Self::from_int(int)
235 }
236}
237
238impl QuotientMap<i128> for Bn254Fr {
239 #[inline]
241 fn from_int(int: i128) -> Self {
242 if int >= 0 {
244 Self::from_int(int as u128)
245 } else {
246 -Self::from_int((-int) as u128)
247 }
248 }
249
250 #[inline]
252 fn from_canonical_checked(int: i128) -> Option<Self> {
253 Some(Self::from_int(int))
254 }
255
256 #[inline]
258 unsafe fn from_canonical_unchecked(int: i128) -> Self {
259 Self::from_int(int)
260 }
261}
262
263impl PrimeField for Bn254Fr {
264 fn as_canonical_biguint(&self) -> BigUint {
265 let repr = self.value.to_repr();
266 let le_bytes = repr.as_ref();
267 BigUint::from_bytes_le(le_bytes)
268 }
269}
270
271impl Add for Bn254Fr {
272 type Output = Self;
273
274 fn add(self, rhs: Self) -> Self {
275 Self::new(self.value + rhs.value)
276 }
277}
278
279impl AddAssign for Bn254Fr {
280 fn add_assign(&mut self, rhs: Self) {
281 self.value += rhs.value;
282 }
283}
284
285impl Sum for Bn254Fr {
286 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
287 iter.reduce(|x, y| x + y).unwrap_or(Self::ZERO)
288 }
289}
290
291impl Sub for Bn254Fr {
292 type Output = Self;
293
294 fn sub(self, rhs: Self) -> Self {
295 Self::new(self.value.sub(rhs.value))
296 }
297}
298
299impl SubAssign for Bn254Fr {
300 fn sub_assign(&mut self, rhs: Self) {
301 self.value -= rhs.value;
302 }
303}
304
305impl Neg for Bn254Fr {
306 type Output = Self;
307
308 fn neg(self) -> Self::Output {
309 self * Self::NEG_ONE
310 }
311}
312
313impl Mul for Bn254Fr {
314 type Output = Self;
315
316 fn mul(self, rhs: Self) -> Self {
317 Self::new(self.value * rhs.value)
318 }
319}
320
321impl MulAssign for Bn254Fr {
322 fn mul_assign(&mut self, rhs: Self) {
323 self.value *= rhs.value;
324 }
325}
326
327impl Product for Bn254Fr {
328 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
329 iter.reduce(|x, y| x * y).unwrap_or(Self::ONE)
330 }
331}
332
333impl Div for Bn254Fr {
334 type Output = Self;
335
336 #[allow(clippy::suspicious_arithmetic_impl)]
337 fn div(self, rhs: Self) -> Self {
338 self * rhs.inverse()
339 }
340}
341
342impl Distribution<Bn254Fr> for StandardUniform {
343 #[inline]
344 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Bn254Fr {
345 loop {
347 let mut trial_element: [u8; 32] = rng.random();
348
349 trial_element[31] &= (1_u8 << 6) - 1;
352
353 let x = FFBn254Fr::from_bytes(&trial_element);
354 if x.is_some().into() {
355 return Bn254Fr::new(x.unwrap());
357 }
358 }
359 }
360}
361
362impl TwoAdicField for Bn254Fr {
363 const TWO_ADICITY: usize = FFBn254Fr::S as usize;
364
365 fn two_adic_generator(bits: usize) -> Self {
366 let mut omega = FFBn254Fr::ROOT_OF_UNITY;
367 for _ in bits..Self::TWO_ADICITY {
368 omega = omega.square();
369 }
370 Self::new(omega)
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use p3_field_testing::{test_field, test_prime_field};
377
378 use super::*;
379
380 type F = Bn254Fr;
381
382 #[test]
383 fn test_bn254fr() {
384 let f = F::new(FFBn254Fr::from_u128(100));
385 assert_eq!(f.as_canonical_biguint(), BigUint::from(100u32));
386
387 let f = F::new(FFBn254Fr::from_str_vartime(&F::order().to_str_radix(10)).unwrap());
388 assert!(f.is_zero());
389
390 let expected_multiplicative_group_generator = F::new(FFBn254Fr::from_u128(5));
392 assert_eq!(F::GENERATOR, expected_multiplicative_group_generator);
393 assert_eq!(F::GENERATOR.as_canonical_biguint(), BigUint::from(5u32));
394
395 let f_1 = F::ONE;
396 let f_2 = F::TWO;
397 let f_r_minus_1 = F::NEG_ONE;
398 let f_r_minus_2 = F::NEG_ONE + F::NEG_ONE;
399
400 let f_serialized = serde_json::to_string(&f).unwrap();
401 let f_deserialized: F = serde_json::from_str(&f_serialized).unwrap();
402 assert_eq!(f, f_deserialized);
403
404 let f_1_serialized = serde_json::to_string(&f_1).unwrap();
405 let f_1_deserialized: F = serde_json::from_str(&f_1_serialized).unwrap();
406 let f_1_serialized_again = serde_json::to_string(&f_1_deserialized).unwrap();
407 let f_1_deserialized_again: F = serde_json::from_str(&f_1_serialized_again).unwrap();
408 assert_eq!(f_1, f_1_deserialized);
409 assert_eq!(f_1, f_1_deserialized_again);
410
411 let f_2_serialized = serde_json::to_string(&f_2).unwrap();
412 let f_2_deserialized: F = serde_json::from_str(&f_2_serialized).unwrap();
413 assert_eq!(f_2, f_2_deserialized);
414
415 let f_r_minus_1_serialized = serde_json::to_string(&f_r_minus_1).unwrap();
416 let f_r_minus_1_deserialized: F = serde_json::from_str(&f_r_minus_1_serialized).unwrap();
417 assert_eq!(f_r_minus_1, f_r_minus_1_deserialized);
418
419 let f_r_minus_2_serialized = serde_json::to_string(&f_r_minus_2).unwrap();
420 let f_r_minus_2_deserialized: F = serde_json::from_str(&f_r_minus_2_serialized).unwrap();
421 assert_eq!(f_r_minus_2, f_r_minus_2_deserialized);
422 }
423
424 const ZERO: Bn254Fr = Bn254Fr::ZERO;
425 const ONE: Bn254Fr = Bn254Fr::ONE;
426
427 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 10] {
430 [
431 (BigUint::from(2u8), 28),
432 (BigUint::from(3u8), 2),
433 (BigUint::from(13u8), 1),
434 (BigUint::from(29u8), 1),
435 (BigUint::from(983u16), 1),
436 (BigUint::from(11003u16), 1),
437 (BigUint::from(237073u32), 1),
438 (BigUint::from(405928799u32), 1),
439 (BigUint::from(1670836401704629u64), 1),
440 (BigUint::from(13818364434197438864469338081u128), 1),
441 ]
442 }
443 test_field!(
444 crate::Bn254Fr,
445 &[super::ZERO],
446 &[super::ONE],
447 &super::multiplicative_group_prime_factorization()
448 );
449
450 test_prime_field!(crate::Bn254Fr);
451}