1use super::Fq;
2use ark_ff::{BigInt, Field, PrimeField, SqrtPrecomputation};
3use ark_ff::{BigInteger, FftField};
4use ark_serialize::{
5 CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
6 CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
7};
8use ark_std::iterable::Iterable;
9use ark_std::{rand, str::FromStr, string::ToString, One, Zero};
10use core::convert::TryInto;
11use core::{
12 fmt::{Display, Formatter},
13 iter,
14};
15
16impl PrimeField for Fq {
17 type BigInt = BigInt<4>;
19
20 const MODULUS: Self::BigInt = ark_ff::BigInt(Self::MODULUS_LIMBS);
22
23 const MODULUS_MINUS_ONE_DIV_TWO: Self::BigInt = BigInt(Self::MODULUS_MINUS_ONE_DIV_TWO_LIMBS);
25
26 const MODULUS_BIT_SIZE: u32 = Self::MODULUS_BIT_SIZE;
28
29 const TRACE: Self::BigInt = BigInt(Self::TRACE_LIMBS);
32
33 const TRACE_MINUS_ONE_DIV_TWO: Self::BigInt = BigInt(Self::TRACE_MINUS_ONE_DIV_TWO_LIMBS);
35
36 fn from_bigint(repr: Self::BigInt) -> Option<Self> {
37 if repr >= Fq::MODULUS {
38 None
39 } else {
40 Some(Self::from_le_limbs(repr.0))
42 }
43 }
44
45 fn into_bigint(self) -> Self::BigInt {
46 BigInt(self.to_le_limbs())
47 }
48
49 fn from_be_bytes_mod_order(bytes: &[u8]) -> Self {
50 let mut bytes_copy = bytes.to_vec();
51 bytes_copy.reverse();
52 Self::from_le_bytes_mod_order(&bytes_copy)
53 }
54
55 fn from_le_bytes_mod_order(bytes: &[u8]) -> Self {
56 Self::from_le_bytes_mod_order(bytes)
57 }
58}
59
60impl Field for Fq {
61 type BasePrimeField = Self;
62 type BasePrimeFieldIter = iter::Once<Self::BasePrimeField>;
63
64 const SQRT_PRECOMP: Option<SqrtPrecomputation<Self>> =
65 Some(SqrtPrecomputation::TonelliShanks {
66 two_adicity: Self::TWO_ADICITY,
67 quadratic_nonresidue_to_trace: Self::QUADRATIC_NON_RESIDUE_TO_TRACE,
68 trace_of_modulus_minus_one_div_two: &Self::TRACE_MINUS_ONE_DIV_TWO_LIMBS,
69 });
70
71 const ZERO: Self = Self::ZERO;
72
73 const ONE: Self = Self::ONE;
75
76 fn extension_degree() -> u64 {
77 1
78 }
79
80 fn to_base_prime_field_elements(&self) -> Self::BasePrimeFieldIter {
81 iter::once(*self)
82 }
83
84 fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option<Self> {
85 if elems.len() != (Self::extension_degree() as usize) {
86 return None;
87 }
88 Some(elems[0])
89 }
90
91 fn from_base_prime_field(elem: Self::BasePrimeField) -> Self {
92 elem
93 }
94
95 fn double(&self) -> Self {
96 self.add(self)
97 }
98
99 fn double_in_place(&mut self) -> &mut Self {
100 *self = self.add(self);
101 self
102 }
103
104 fn neg_in_place(&mut self) -> &mut Self {
105 *self = Self::ZERO.sub(self);
106 self
107 }
108
109 fn from_random_bytes_with_flags<F: ark_serialize::Flags>(bytes: &[u8]) -> Option<(Self, F)> {
110 Some((Self::from_le_bytes_mod_order(bytes), F::default()))
111 }
112
113 fn legendre(&self) -> ark_ff::LegendreSymbol {
114 use ark_ff::LegendreSymbol::*;
115
116 if self.is_zero() {
117 return Zero;
118 }
119 if self.pow(&Self::MODULUS_MINUS_ONE_DIV_TWO.0).is_one() {
120 return QuadraticResidue;
121 }
122 return QuadraticNonResidue;
123 }
124
125 fn square(&self) -> Self {
126 self.square()
127 }
128
129 fn square_in_place(&mut self) -> &mut Self {
130 *self = self.square();
131 self
132 }
133
134 fn inverse(&self) -> Option<Self> {
135 self.inverse()
136 }
137
138 fn inverse_in_place(&mut self) -> Option<&mut Self> {
139 if let Some(inverse) = self.inverse() {
140 *self = inverse;
141 Some(self)
142 } else {
143 None
144 }
145 }
146
147 fn frobenius_map_in_place(&mut self, _power: usize) {
148 }
151
152 fn characteristic() -> &'static [u64] {
153 &Self::MODULUS_LIMBS
154 }
155}
156
157impl FftField for Fq {
158 const GENERATOR: Self = Self::MULTIPLICATIVE_GENERATOR;
159 const TWO_ADICITY: u32 = Self::TWO_ADICITY;
160 const TWO_ADIC_ROOT_OF_UNITY: Self = Self::TWO_ADIC_ROOT_OF_UNITY;
161 const SMALL_SUBGROUP_BASE: Option<u32> = None;
162 const SMALL_SUBGROUP_BASE_ADICITY: Option<u32> = None;
163 const LARGE_SUBGROUP_ROOT_OF_UNITY: Option<Self> = None;
164}
165
166impl Zero for Fq {
167 #[inline]
168 fn zero() -> Self {
169 Fq::ZERO
170 }
171
172 #[inline]
173 fn is_zero(&self) -> bool {
174 *self == Fq::ZERO
175 }
176}
177
178impl One for Fq {
179 #[inline]
180 fn one() -> Self {
181 Fq::ONE
182 }
183
184 #[inline]
185 fn is_one(&self) -> bool {
186 *self == Fq::ONE
187 }
188}
189impl CanonicalDeserializeWithFlags for Fq {
190 fn deserialize_with_flags<R: ark_std::io::Read, F: Flags>(
191 mut reader: R,
192 ) -> Result<(Self, F), SerializationError> {
193 let mut bytes = [0u8; (Self::MODULUS_BIT_SIZE as usize + 7) / 8];
195
196 let expected_len = (Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE + 7) / 8;
197 reader.read_exact(&mut bytes[..expected_len])?;
198 let flags = F::from_u8_remove_flags(&mut bytes[bytes.len() - 1])
199 .ok_or(SerializationError::UnexpectedFlags)?;
200 let mut limbs = [0u64; 4];
203 for (limb, chunk) in limbs.iter_mut().zip(bytes[..32].chunks_exact(8)) {
204 *limb = u64::from_le_bytes(chunk.try_into().expect("chunk will have the right size"));
205 }
206 let out = Self::from_bigint(BigInt(limbs)).ok_or(SerializationError::InvalidData)?;
207 Ok((out, flags))
208 }
209}
210
211impl Valid for Fq {
212 fn check(&self) -> Result<(), SerializationError> {
213 Ok(())
214 }
215}
216
217impl CanonicalDeserialize for Fq {
218 fn deserialize_with_mode<R: ark_std::io::Read>(
219 reader: R,
220 _compress: Compress,
221 validate: Validate,
222 ) -> Result<Self, SerializationError> {
223 let (out, _) = Self::deserialize_with_flags::<R, EmptyFlags>(reader)?;
224 match validate {
225 Validate::Yes => out.check(),
226 Validate::No => Ok(()),
227 }?;
228 Ok(out)
229 }
230}
231
232impl CanonicalSerialize for Fq {
233 #[inline]
234 fn serialize_with_mode<W: ark_std::io::Write>(
235 &self,
236 writer: W,
237 _compress: Compress,
238 ) -> Result<(), SerializationError> {
239 self.serialize_with_flags(writer, EmptyFlags)
240 }
241
242 #[inline]
243 fn serialized_size(&self, _compress: Compress) -> usize {
244 self.serialized_size_with_flags::<EmptyFlags>()
245 }
246}
247
248impl CanonicalSerializeWithFlags for Fq {
249 fn serialize_with_flags<W: ark_std::io::Write, F: Flags>(
250 &self,
251 mut writer: W,
252 flags: F,
253 ) -> Result<(), SerializationError> {
254 if F::BIT_SIZE > 8 {
256 return Err(SerializationError::NotEnoughSpace);
257 }
258
259 let mut bytes = self.to_bytes_le();
261 if bytes.len() == self.serialized_size_with_flags::<F>() {
263 bytes[bytes.len() - 1] |= flags.u8_bitmask();
265 writer.write_all(&bytes)?;
266 } else {
267 writer.write_all(&bytes)?;
269 writer.write_all(&[flags.u8_bitmask()])?;
270 }
271 Ok(())
272 }
273
274 fn serialized_size_with_flags<F: Flags>(&self) -> usize {
275 (Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE + 7) / 8
276 }
277}
278
279impl ark_std::rand::distributions::Distribution<Fq> for ark_std::rand::distributions::Standard {
280 fn sample<R: rand::prelude::Rng + ?Sized>(&self, rng: &mut R) -> Fq {
281 loop {
282 let mut repr: [u64; 4] = rng.sample(ark_std::rand::distributions::Standard);
283 let shave_bits = 64 * 4 - (Fq::MODULUS_BIT_SIZE as usize);
284 let mask = if shave_bits == 64 {
286 0
287 } else {
288 u64::MAX >> shave_bits
289 };
290
291 if let Some(val) = repr.last_mut() {
292 *val &= mask
293 }
294
295 if let Some(small_enough) = Fq::from_bigint(BigInt(repr)) {
296 return small_enough;
297 }
298 }
299 }
300}
301
302impl Display for Fq {
303 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
304 let string = self.into_bigint().to_string();
305 write!(f, "{}", string.trim_start_matches('0'))
306 }
307}
308impl FromStr for Fq {
309 type Err = ();
310
311 fn from_str(s: &str) -> Result<Self, Self::Err> {
312 let mut acc = Self::zero();
314
315 let ten = Self::from(10u8);
316
317 for c in s.chars() {
318 match c.to_digit(10) {
319 Some(c) => {
320 acc = ten * acc + Self::from(u64::from(c));
321 }
322 None => {
323 return Err(());
324 }
325 }
326 }
327 Ok(acc)
328 }
329}
330
331impl From<num_bigint::BigUint> for Fq {
332 #[inline]
333 fn from(val: num_bigint::BigUint) -> Fq {
334 Fq::from_le_bytes_mod_order(&val.to_bytes_le())
335 }
336}
337
338impl From<Fq> for num_bigint::BigUint {
339 #[inline(always)]
340 fn from(other: Fq) -> Self {
341 other.into_bigint().into()
342 }
343}
344
345impl From<Fq> for BigInt<4> {
346 #[inline(always)]
347 fn from(fp: Fq) -> Self {
348 fp.into_bigint()
349 }
350}
351
352impl From<BigInt<4>> for Fq {
353 #[inline(always)]
355 fn from(int: BigInt<4>) -> Self {
356 Fq::from_le_bytes_mod_order(&int.to_bytes_le())
357 }
358}
359
360#[cfg(test)]
361mod tests {
362 use super::*;
363 extern crate alloc;
364 use alloc::{format, vec::Vec};
365 use ark_bls12_377::Fr as ArkFq;
366 use proptest::prelude::*;
367
368 prop_compose! {
369 fn arb_fp_limbs()(
372 z0 in 0..u64::MAX,
373 z1 in 0..u64::MAX,
374 z2 in 0..u64::MAX,
375 z3 in 0..1345280370688173398u64
376 ) -> [u64; 4] {
377 [z0, z1, z2, z3]
378 }
379 }
380
381 prop_compose! {
382 fn arb_fq()(a in arb_fp_limbs()) -> Fq {
383 Fq::from_bigint(BigInt(a)).unwrap_or(Fq::zero())
385 }
386 }
387
388 prop_compose! {
389 fn arb_nonzero_fq()(a in arb_fq()) -> Fq {
390 if a == Fq::zero() { Fq::one() } else { a }
391 }
392 }
393
394 proptest! {
395 #[test]
396 fn test_addition_commutative(a in arb_fq(), b in arb_fq()) {
397 assert_eq!(a + b, b + a);
398 }
399 }
400
401 proptest! {
402 #[test]
403 fn test_addition_associative(a in arb_fq(), b in arb_fq(), c in arb_fq()) {
404 assert_eq!(a + (b + c), (a + b) + c);
405 }
406 }
407
408 proptest! {
409 #[test]
410 fn test_add_zero_identity(a in arb_fq()) {
411 let zero = Fq::zero();
412
413 assert_eq!(a + zero, a);
414 assert_eq!(zero + a, a);
415 }
416 }
417
418 proptest! {
419 #[test]
420 fn test_subtract_self_is_zero(a in arb_fq()) {
421 let zero = Fq::zero();
422
423 assert_eq!(a - a, zero);
424 }
425 }
426
427 proptest! {
428 #[test]
429 fn test_doubling_is_just_addition(a in arb_fq()) {
430 let two = Fq::from(2u64);
431
432 assert_eq!(two * a, a + a);
433 assert_eq!(a.double(), a + a);
434 assert_eq!(*(a.clone().double_in_place()), a + a);
435 }
436 }
437
438 proptest! {
439 #[test]
440 fn test_adding_negation(a in arb_fq()) {
441 assert_eq!(a + -a, Fq::ZERO)
442 }
443 }
444
445 proptest! {
446 #[test]
447 fn test_multiplication_commutative(a in arb_fq(), b in arb_fq()) {
448 assert_eq!(a * b, b * a);
449 }
450 }
451
452 proptest! {
453 #[test]
454 fn test_multiplication_associative(a in arb_fq(), b in arb_fq(), c in arb_fq()) {
455 assert_eq!(a * (b * c), (a * b) * c);
456 }
457 }
458
459 proptest! {
460 #[test]
461 fn test_multiplication_distributive(a in arb_fq(), b in arb_fq(), c in arb_fq()) {
462 assert_eq!(a * (b + c), a * b + a * c);
463 }
464 }
465
466 proptest! {
467 #[test]
468 fn test_multiply_one_identity(a in arb_fq()) {
469 assert_eq!(a * Fq::ONE, a);
470 assert_eq!(Fq::ONE * a, a);
471 }
472 }
473
474 proptest! {
475 #[test]
476 fn test_multiply_minus_one_is_negation(a in arb_fq()) {
477 let minus_one = -Fq::ONE;
478
479 assert_eq!(a * minus_one, a.neg());
480 }
481 }
482
483 proptest! {
484 #[test]
485 fn test_square_is_multiply(a in arb_fq()) {
486 assert_eq!(a.square(), a * a);
487 assert_eq!(*(a.clone().square_in_place()), a * a);
488 }
489 }
490
491 proptest! {
492 #[test]
493 fn test_inverse(a in arb_nonzero_fq()) {
494 assert_eq!(a * a.inverse().unwrap(), Fq::ONE);
495 assert_eq!(a * *(a.clone().inverse_in_place().unwrap()), Fq::ONE);
496 }
497 }
498
499 fn naive_inverse(a: Fq) -> Fq {
500 a.pow(&(-Fq::from(2u64)).into_bigint().0)
501 }
502
503 proptest! {
504 #[test]
505 fn test_inverse_vs_naive_inverse(a in arb_nonzero_fq()) {
506 assert_eq!(a.inverse().unwrap(), naive_inverse(a));
507 }
508 }
509
510 proptest! {
511 #[test]
512 fn test_sqrt(a in arb_fq()) {
513 match a.sqrt() {
514 Some(x) => assert_eq!(x * x, a),
515 None => {}
516 }
517 }
518 }
519
520 proptest! {
521 #[test]
522 fn test_into_bigint_monomorphism(a in arb_fq()) {
523 let as_bigint = a.into_bigint();
524 let roundtrip = Fq::from_bigint(as_bigint);
525
526 assert_eq!(Some(a), roundtrip);
527 }
528 }
529
530 proptest! {
531 #[test]
532 fn test_conversion_to_bytes_via_bigint(a in arb_fq()) {
533 let way1 = a.to_bytes_le();
534 let way2 = a.into_bigint().to_bytes_le();
535 assert_eq!(way1.as_slice(), way2.as_slice());
536 }
537 }
538
539 proptest! {
540 #[test]
541 fn test_legendre_symbol(a in arb_nonzero_fq()) {
542 assert_eq!((a * a).legendre(), ark_ff::LegendreSymbol::QuadraticResidue);
543 }
544 }
545
546 proptest! {
547 #[test]
548 fn test_canonical_serialize_monomorphism(a in arb_fq()) {
549 let mut bytes: Vec<u8> = Vec::new();
550 let roundtrip = a.serialize_compressed(&mut bytes).and_then(|_| Fq::deserialize_compressed(&*bytes));
551 assert!(roundtrip.is_ok());
552 assert_eq!(*roundtrip.as_ref().clone().unwrap(), a);
553 }
554 }
555
556 proptest! {
557 #[test]
558 fn test_serialize_matches_arkworks(a in arb_fp_limbs()) {
559 let our_value: Fq = BigInt(a).into();
560 let their_value: ArkFq = BigInt(a).into();
561
562 let mut our_bytes: Vec<u8> = Vec::new();
563 assert!(our_value.serialize_compressed(&mut our_bytes).is_ok());
564
565 let mut their_bytes: Vec<u8> = Vec::new();
566 assert!(their_value.serialize_compressed(&mut their_bytes).is_ok());
567
568 assert_eq!(our_bytes, their_bytes);
569 }
570 }
571
572 fn naive_from_le_bytes_mod_order(bytes: &[u8]) -> Fq {
573 let mut acc = Fq::zero();
574 let mut insert = Fq::one();
575 for byte in bytes {
576 for i in 0..8 {
577 if (byte >> i) & 1 == 1 {
578 acc += insert;
579 }
580 insert.double_in_place();
581 }
582 }
583 acc
584 }
585
586 proptest! {
587 #[test]
588 fn test_from_le_bytes_mod_order_vs_naive(bytes in any::<[u8; 80]>()) {
589 let way1 = Fq::from_le_bytes_mod_order(&bytes);
590 let way2 = naive_from_le_bytes_mod_order(&bytes);
591 assert_eq!(way1, way2);
592 }
593 }
594
595 proptest! {
596 #[test]
597 fn test_from_str(a in arb_fq()) {
598 let x = <Fq as PrimeField>::BigInt::from(a);
599 assert_eq!(Ok(a), Fq::from_str(&format!("{}", x)));
600 }
601 }
602
603 #[test]
604 fn test_from_le_bytes_mod_order_examples() {
605 let p_plus_1_bytes: [u8; 32] = [
606 2, 0, 0, 0, 0, 128, 17, 10, 1, 0, 0, 208, 254, 118, 170, 89, 1, 176, 55, 92, 30, 77,
607 180, 96, 86, 165, 44, 154, 94, 101, 171, 18,
608 ];
609 let bytes_for_1 = {
610 let mut out = [0u8; 32];
611 out[0] = 1;
612 out
613 };
614
615 assert_eq!(Fq::from_le_bytes_mod_order(&p_plus_1_bytes), Fq::one());
616 assert_eq!(
617 Fq::from_le_bytes_mod_order(&p_plus_1_bytes).to_bytes_le(),
618 bytes_for_1
619 );
620 }
621
622 #[test]
623 fn test_addition_examples() {
624 let z1: Fq = BigInt([1, 1, 1, 1]).into();
625 let z2: Fq = BigInt([2, 2, 2, 2]).into();
626 let z3: Fq = BigInt([3, 3, 3, 3]).into();
627
628 assert_eq!(z3, z1 + z2);
629 }
630
631 #[test]
632 fn test_subtraction_examples() {
633 let mut z1: Fq = BigInt([1, 1, 1, 1]).into();
634 z1 -= z1;
635
636 assert_eq!(z1, Fq::ZERO);
637 }
638
639 #[test]
640 fn test_small_multiplication_examples() {
641 let z1: Fq = BigInt([1, 0, 0, 0]).into();
642 let z2: Fq = BigInt([2, 0, 0, 0]).into();
643 let z3: Fq = BigInt([3, 0, 0, 0]).into();
644
645 assert_eq!(z1 + z1, z1 * z2);
646 assert_eq!(z1 + z1 + z1, z1 * z3);
647 }
648
649 #[test]
650 fn test_2192_times_zero() {
651 let two192: Fq = BigInt([0, 0, 0, 1]).into();
652 assert_eq!(two192 * Fq::zero(), Fq::ZERO);
653 }
654
655 #[test]
656 fn test_minus_one_squared() {
657 let minus_one = Fq::zero() - Fq::one();
658 assert_eq!(minus_one.square(), Fq::ONE);
659 }
660
661 #[test]
662 fn test_modulus_from_le_bytes_mod_order() {
663 let modulus_minus_one: Fq = BigInt([
665 725501752471715840,
666 6461107452199829505,
667 6968279316240510977,
668 1345280370688173398,
669 ])
670 .into();
671
672 assert_eq!(modulus_minus_one, -Fq::one());
673 }
674}