halo2curves_axiom/derive/
field.rs

1#[macro_export]
2macro_rules! impl_from_u64 {
3    ($field:ident, $r2:ident) => {
4        impl From<u64> for $field {
5            fn from(val: u64) -> $field {
6                $field([val, 0, 0, 0]) * $r2
7            }
8        }
9    };
10}
11
12#[macro_export]
13macro_rules! field_common {
14    (
15        $field:ident,
16        $modulus:ident,
17        $inv:ident,
18        $modulus_str:ident,
19        $two_inv:ident,
20        $root_of_unity_inv:ident,
21        $delta:ident,
22        $zeta:ident,
23        $r:ident,
24        $r2:ident,
25        $r3:ident
26    ) => {
27        /// Bernstein-Yang modular multiplicative inverter created for the modulus equal to
28        /// the characteristic of the field to invert positive integers in the Montgomery form.
29        const BYINVERTOR: $crate::ff_ext::inverse::BYInverter<6> =
30            $crate::ff_ext::inverse::BYInverter::<6>::new(&$modulus.0, &$r2.0);
31
32        impl $field {
33            /// Returns zero, the additive identity.
34            #[inline]
35            pub const fn zero() -> $field {
36                $field([0, 0, 0, 0])
37            }
38
39            /// Returns one, the multiplicative identity.
40            #[inline]
41            pub const fn one() -> $field {
42                $r
43            }
44
45            /// Returns the multiplicative inverse of the
46            /// element. If it is zero, the method fails.
47            #[inline(always)]
48            pub fn invert(&self) -> CtOption<Self> {
49                if let Some(inverse) = BYINVERTOR.invert(&self.0) {
50                    CtOption::new(Self(inverse), Choice::from(1))
51                } else {
52                    CtOption::new(Self::zero(), Choice::from(0))
53                }
54            }
55
56            // Returns the Jacobi symbol, where the numerator and denominator
57            // are the element and the characteristic of the field, respectively.
58            // The Jacobi symbol is applicable to odd moduli
59            // while the Legendre symbol is applicable to prime moduli.
60            // They are equivalent for prime moduli.
61            #[inline(always)]
62            pub fn jacobi(&self) -> i64 {
63                $crate::ff_ext::jacobi::jacobi::<5>(&self.0, &$modulus.0)
64            }
65
66            const fn montgomery_form(val: [u64; 4], r: $field) -> $field {
67                // Converts a 4 64-bit limb value into its congruent field representation.
68                // If `val` representes a 256 bit value then `r` should be R^2,
69                // if `val` represents the 256 MSB of a 512 bit value, then `r` should be R^3.
70
71                #[cfg(feature = "asm")]
72                {
73                    let (r0, carry) = mac(0, val[0], r.0[0], 0);
74                    let (r1, carry) = mac(0, val[0], r.0[1], carry);
75                    let (r2, carry) = mac(0, val[0], r.0[2], carry);
76                    let (r3, r4) = mac(0, val[0], r.0[3], carry);
77
78                    let (r1, carry) = mac(r1, val[1], r.0[0], 0);
79                    let (r2, carry) = mac(r2, val[1], r.0[1], carry);
80                    let (r3, carry) = mac(r3, val[1], r.0[2], carry);
81                    let (r4, r5) = mac(r4, val[1], r.0[3], carry);
82
83                    let (r2, carry) = mac(r2, val[2], r.0[0], 0);
84                    let (r3, carry) = mac(r3, val[2], r.0[1], carry);
85                    let (r4, carry) = mac(r4, val[2], r.0[2], carry);
86                    let (r5, r6) = mac(r5, val[2], r.0[3], carry);
87
88                    let (r3, carry) = mac(r3, val[3], r.0[0], 0);
89                    let (r4, carry) = mac(r4, val[3], r.0[1], carry);
90                    let (r5, carry) = mac(r5, val[3], r.0[2], carry);
91                    let (r6, r7) = mac(r6, val[3], r.0[3], carry);
92
93                    // Montgomery reduction
94                    let k = r0.wrapping_mul($inv);
95                    let (_, carry) = mac(r0, k, $modulus.0[0], 0);
96                    let (r1, carry) = mac(r1, k, $modulus.0[1], carry);
97                    let (r2, carry) = mac(r2, k, $modulus.0[2], carry);
98                    let (r3, carry) = mac(r3, k, $modulus.0[3], carry);
99                    let (r4, carry2) = adc(r4, 0, carry);
100
101                    let k = r1.wrapping_mul($inv);
102                    let (_, carry) = mac(r1, k, $modulus.0[0], 0);
103                    let (r2, carry) = mac(r2, k, $modulus.0[1], carry);
104                    let (r3, carry) = mac(r3, k, $modulus.0[2], carry);
105                    let (r4, carry) = mac(r4, k, $modulus.0[3], carry);
106                    let (r5, carry2) = adc(r5, carry2, carry);
107
108                    let k = r2.wrapping_mul($inv);
109                    let (_, carry) = mac(r2, k, $modulus.0[0], 0);
110                    let (r3, carry) = mac(r3, k, $modulus.0[1], carry);
111                    let (r4, carry) = mac(r4, k, $modulus.0[2], carry);
112                    let (r5, carry) = mac(r5, k, $modulus.0[3], carry);
113                    let (r6, carry2) = adc(r6, carry2, carry);
114
115                    let k = r3.wrapping_mul($inv);
116                    let (_, carry) = mac(r3, k, $modulus.0[0], 0);
117                    let (r4, carry) = mac(r4, k, $modulus.0[1], carry);
118                    let (r5, carry) = mac(r5, k, $modulus.0[2], carry);
119                    let (r6, carry) = mac(r6, k, $modulus.0[3], carry);
120                    let (r7, carry2) = adc(r7, carry2, carry);
121
122                    // Result may be within MODULUS of the correct value
123                    let (d0, borrow) = sbb(r4, $modulus.0[0], 0);
124                    let (d1, borrow) = sbb(r5, $modulus.0[1], borrow);
125                    let (d2, borrow) = sbb(r6, $modulus.0[2], borrow);
126                    let (d3, borrow) = sbb(r7, $modulus.0[3], borrow);
127                    let (_, borrow) = sbb(carry2, 0, borrow);
128                    let (d0, carry) = adc(d0, $modulus.0[0] & borrow, 0);
129                    let (d1, carry) = adc(d1, $modulus.0[1] & borrow, carry);
130                    let (d2, carry) = adc(d2, $modulus.0[2] & borrow, carry);
131                    let (d3, _) = adc(d3, $modulus.0[3] & borrow, carry);
132
133                    $field([d0, d1, d2, d3])
134                }
135
136                #[cfg(not(feature = "asm"))]
137                {
138                    let mut val = val;
139                    if bigint_geq(&val, &$modulus.0) {
140                        let mut borrow = 0;
141                        (val[0], borrow) = sbb(val[0], $modulus.0[0], borrow);
142                        (val[1], borrow) = sbb(val[1], $modulus.0[1], borrow);
143                        (val[2], borrow) = sbb(val[2], $modulus.0[2], borrow);
144                        (val[3], _) = sbb(val[3], $modulus.0[3], borrow);
145                    }
146                    $field::mul(&$field(val), &r)
147                }
148            }
149
150            fn from_u512(limbs: [u64; 8]) -> $field {
151                // We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits
152                // with the higher bits multiplied by 2^256. Thus, we perform two reductions
153                //
154                // 1. the lower bits are multiplied by R^2, as normal
155                // 2. the upper bits are multiplied by R^2 * 2^256 = R^3
156                //
157                // and computing their sum in the field. It remains to see that arbitrary 256-bit
158                // numbers can be placed into Montgomery form safely using the reduction. The
159                // reduction works so long as the product is less than R=2^256 multiplied by
160                // the modulus. This holds because for any `c` smaller than the modulus, we have
161                // that (2^256 - 1)*c is an acceptable product for the reduction. Therefore, the
162                // reduction always works so long as `c` is in the field; in this case it is either the
163                // constant `R2` or `R3`.
164
165                let lower_256 = [limbs[0], limbs[1], limbs[2], limbs[3]];
166                let upper_256 = [limbs[4], limbs[5], limbs[6], limbs[7]];
167
168                Self::montgomery_form(lower_256, $r2) + Self::montgomery_form(upper_256, $r3)
169            }
170
171            /// Converts from an integer represented in little endian
172            /// into its (congruent) `$field` representation.
173            pub const fn from_raw(val: [u64; 4]) -> Self {
174                Self::montgomery_form(val, $r2)
175            }
176
177            /// Attempts to convert a little-endian byte representation of
178            /// a scalar into a `Fr`, failing if the input is not canonical.
179            pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<$field> {
180                <Self as ff::PrimeField>::from_repr(*bytes)
181            }
182
183            /// Converts an element of `Fr` into a byte representation in
184            /// little-endian byte order.
185            pub fn to_bytes(&self) -> [u8; 32] {
186                <Self as ff::PrimeField>::to_repr(self)
187            }
188
189            /// Lexicographic comparison of Montgomery forms.
190            #[inline(always)]
191            const fn is_less_than(x: &[u64; 4], y: &[u64; 4]) -> bool {
192                let (_, borrow) = sbb(x[0], y[0], 0);
193                let (_, borrow) = sbb(x[1], y[1], borrow);
194                let (_, borrow) = sbb(x[2], y[2], borrow);
195                let (_, borrow) = sbb(x[3], y[3], borrow);
196                borrow >> 63 == 1
197            }
198        }
199
200        impl fmt::Debug for $field {
201            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202                let tmp = self.to_repr();
203                write!(f, "0x")?;
204                for &b in tmp.iter().rev() {
205                    write!(f, "{:02x}", b)?;
206                }
207                Ok(())
208            }
209        }
210
211        impl Default for $field {
212            #[inline]
213            fn default() -> Self {
214                Self::zero()
215            }
216        }
217
218        impl From<bool> for $field {
219            fn from(bit: bool) -> $field {
220                if bit {
221                    $field::one()
222                } else {
223                    $field::zero()
224                }
225            }
226        }
227
228        impl ConstantTimeEq for $field {
229            fn ct_eq(&self, other: &Self) -> Choice {
230                self.0[0].ct_eq(&other.0[0])
231                    & self.0[1].ct_eq(&other.0[1])
232                    & self.0[2].ct_eq(&other.0[2])
233                    & self.0[3].ct_eq(&other.0[3])
234            }
235        }
236
237        impl core::cmp::Ord for $field {
238            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
239                let left = self.to_repr();
240                let right = other.to_repr();
241                left.iter()
242                    .zip(right.iter())
243                    .rev()
244                    .find_map(|(left_byte, right_byte)| match left_byte.cmp(right_byte) {
245                        core::cmp::Ordering::Equal => None,
246                        res => Some(res),
247                    })
248                    .unwrap_or(core::cmp::Ordering::Equal)
249            }
250        }
251
252        impl core::cmp::PartialOrd for $field {
253            fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
254                Some(self.cmp(other))
255            }
256        }
257
258        impl ConditionallySelectable for $field {
259            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
260                $field([
261                    u64::conditional_select(&a.0[0], &b.0[0], choice),
262                    u64::conditional_select(&a.0[1], &b.0[1], choice),
263                    u64::conditional_select(&a.0[2], &b.0[2], choice),
264                    u64::conditional_select(&a.0[3], &b.0[3], choice),
265                ])
266            }
267        }
268
269        impl<'a> Neg for &'a $field {
270            type Output = $field;
271
272            #[inline]
273            fn neg(self) -> $field {
274                self.neg()
275            }
276        }
277
278        impl Neg for $field {
279            type Output = $field;
280
281            #[inline]
282            fn neg(self) -> $field {
283                -&self
284            }
285        }
286
287        impl<'a, 'b> Sub<&'b $field> for &'a $field {
288            type Output = $field;
289
290            #[inline]
291            fn sub(self, rhs: &'b $field) -> $field {
292                self.sub(rhs)
293            }
294        }
295
296        impl<'a, 'b> Add<&'b $field> for &'a $field {
297            type Output = $field;
298
299            #[inline]
300            fn add(self, rhs: &'b $field) -> $field {
301                self.add(rhs)
302            }
303        }
304
305        impl<'a, 'b> Mul<&'b $field> for &'a $field {
306            type Output = $field;
307
308            #[inline]
309            fn mul(self, rhs: &'b $field) -> $field {
310                self.mul(rhs)
311            }
312        }
313
314        impl From<[u64; 4]> for $field {
315            fn from(digits: [u64; 4]) -> Self {
316                Self::from_raw(digits)
317            }
318        }
319
320        impl From<$field> for [u8; 32] {
321            fn from(value: $field) -> [u8; 32] {
322                value.to_repr()
323            }
324        }
325
326        impl<'a> From<&'a $field> for [u8; 32] {
327            fn from(value: &'a $field) -> [u8; 32] {
328                value.to_repr()
329            }
330        }
331
332        impl $crate::serde::SerdeObject for $field {
333            fn from_raw_bytes_unchecked(bytes: &[u8]) -> Self {
334                debug_assert_eq!(bytes.len(), 32);
335                let inner =
336                    [0, 8, 16, 24].map(|i| u64::from_le_bytes(bytes[i..i + 8].try_into().unwrap()));
337                Self(inner)
338            }
339            fn from_raw_bytes(bytes: &[u8]) -> Option<Self> {
340                if bytes.len() != 32 {
341                    return None;
342                }
343                let elt = Self::from_raw_bytes_unchecked(bytes);
344                Self::is_less_than(&elt.0, &$modulus.0).then(|| elt)
345            }
346            fn to_raw_bytes(&self) -> Vec<u8> {
347                let mut res = Vec::with_capacity(32);
348                for limb in self.0.iter() {
349                    res.extend_from_slice(&limb.to_le_bytes());
350                }
351                res
352            }
353            fn read_raw_unchecked<R: std::io::Read>(reader: &mut R) -> Self {
354                let inner = [(); 4].map(|_| {
355                    let mut buf = [0; 8];
356                    reader.read_exact(&mut buf).unwrap();
357                    u64::from_le_bytes(buf)
358                });
359                Self(inner)
360            }
361            fn read_raw<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
362                let mut inner = [0u64; 4];
363                for limb in inner.iter_mut() {
364                    let mut buf = [0; 8];
365                    reader.read_exact(&mut buf)?;
366                    *limb = u64::from_le_bytes(buf);
367                }
368                let elt = Self(inner);
369                Self::is_less_than(&elt.0, &$modulus.0)
370                    .then(|| elt)
371                    .ok_or_else(|| {
372                        std::io::Error::new(
373                            std::io::ErrorKind::InvalidData,
374                            "input number is not less than field modulus",
375                        )
376                    })
377            }
378            fn write_raw<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
379                for limb in self.0.iter() {
380                    writer.write_all(&limb.to_le_bytes())?;
381                }
382                Ok(())
383            }
384        }
385    };
386}
387
388#[macro_export]
389macro_rules! field_arithmetic {
390    ($field:ident, $modulus:ident, $inv:ident, $field_type:ident) => {
391        field_specific!($field, $modulus, $inv, $field_type);
392
393        impl $field {
394            /// Doubles this field element.
395            #[inline]
396            pub const fn double(&self) -> $field {
397                self.add(self)
398            }
399
400            /// Squares this element.
401            #[inline]
402            pub const fn square(&self) -> $field {
403                let (r1, carry) = mac(0, self.0[0], self.0[1], 0);
404                let (r2, carry) = mac(0, self.0[0], self.0[2], carry);
405                let (r3, r4) = mac(0, self.0[0], self.0[3], carry);
406
407                let (r3, carry) = mac(r3, self.0[1], self.0[2], 0);
408                let (r4, r5) = mac(r4, self.0[1], self.0[3], carry);
409
410                let (r5, r6) = mac(r5, self.0[2], self.0[3], 0);
411
412                let r7 = r6 >> 63;
413                let r6 = (r6 << 1) | (r5 >> 63);
414                let r5 = (r5 << 1) | (r4 >> 63);
415                let r4 = (r4 << 1) | (r3 >> 63);
416                let r3 = (r3 << 1) | (r2 >> 63);
417                let r2 = (r2 << 1) | (r1 >> 63);
418                let r1 = r1 << 1;
419
420                let (r0, carry) = mac(0, self.0[0], self.0[0], 0);
421                let (r1, carry) = adc(0, r1, carry);
422                let (r2, carry) = mac(r2, self.0[1], self.0[1], carry);
423                let (r3, carry) = adc(0, r3, carry);
424                let (r4, carry) = mac(r4, self.0[2], self.0[2], carry);
425                let (r5, carry) = adc(0, r5, carry);
426                let (r6, carry) = mac(r6, self.0[3], self.0[3], carry);
427                let (r7, _) = adc(0, r7, carry);
428
429                $field::montgomery_reduce(&[r0, r1, r2, r3, r4, r5, r6, r7])
430            }
431
432            /// Multiplies `rhs` by `self`, returning the result.
433            #[inline(always)]
434            #[unroll::unroll_for_loops]
435            #[allow(unused_assignments)]
436            pub const fn mul(&self, rhs: &Self) -> Self {
437                // Fast Coarsely Integrated Operand Scanning (CIOS) as described
438                // in Algorithm 2 of EdMSM: https://eprint.iacr.org/2022/1400.pdf
439                //
440                // Cannot use the fast version (algorithm 2) if
441                // modulus_high_word >= (WORD_SIZE - 1) / 2 - 1 = (2^64 - 1)/2 - 1
442
443                if $modulus.0[3] < (u64::MAX / 2) {
444                    const N: usize = 4;
445                    let mut t: [u64; N] = [0u64; N];
446                    let mut c_2: u64;
447                    for i in 0..4 {
448                        let mut c: u64 = 0u64;
449                        for j in 0..4 {
450                            (t[j], c) = mac(t[j], self.0[j], rhs.0[i], c);
451                        }
452                        c_2 = c;
453
454                        let m = t[0].wrapping_mul(INV);
455                        (_, c) = macx(t[0], m, $modulus.0[0]);
456
457                        for j in 1..4 {
458                            (t[j - 1], c) = mac(t[j], m, $modulus.0[j], c);
459                        }
460                        (t[N - 1], _) = adc(c_2, c, 0);
461                    }
462
463                    if bigint_geq(&t, &$modulus.0) {
464                        let mut borrow = 0;
465                        (t[0], borrow) = sbb(t[0], $modulus.0[0], borrow);
466                        (t[1], borrow) = sbb(t[1], $modulus.0[1], borrow);
467                        (t[2], borrow) = sbb(t[2], $modulus.0[2], borrow);
468                        (t[3], borrow) = sbb(t[3], $modulus.0[3], borrow);
469                    }
470                    $field(t)
471                } else {
472                    // Schoolbook multiplication
473
474                    let (r0, carry) = mac(0, self.0[0], rhs.0[0], 0);
475                    let (r1, carry) = mac(0, self.0[0], rhs.0[1], carry);
476                    let (r2, carry) = mac(0, self.0[0], rhs.0[2], carry);
477                    let (r3, r4) = mac(0, self.0[0], rhs.0[3], carry);
478
479                    let (r1, carry) = mac(r1, self.0[1], rhs.0[0], 0);
480                    let (r2, carry) = mac(r2, self.0[1], rhs.0[1], carry);
481                    let (r3, carry) = mac(r3, self.0[1], rhs.0[2], carry);
482                    let (r4, r5) = mac(r4, self.0[1], rhs.0[3], carry);
483
484                    let (r2, carry) = mac(r2, self.0[2], rhs.0[0], 0);
485                    let (r3, carry) = mac(r3, self.0[2], rhs.0[1], carry);
486                    let (r4, carry) = mac(r4, self.0[2], rhs.0[2], carry);
487                    let (r5, r6) = mac(r5, self.0[2], rhs.0[3], carry);
488
489                    let (r3, carry) = mac(r3, self.0[3], rhs.0[0], 0);
490                    let (r4, carry) = mac(r4, self.0[3], rhs.0[1], carry);
491                    let (r5, carry) = mac(r5, self.0[3], rhs.0[2], carry);
492                    let (r6, r7) = mac(r6, self.0[3], rhs.0[3], carry);
493
494                    $field::montgomery_reduce(&[r0, r1, r2, r3, r4, r5, r6, r7])
495                }
496            }
497
498            /// Subtracts `rhs` from `self`, returning the result.
499            #[inline]
500            pub const fn sub(&self, rhs: &Self) -> Self {
501                let (d0, borrow) = sbb(self.0[0], rhs.0[0], 0);
502                let (d1, borrow) = sbb(self.0[1], rhs.0[1], borrow);
503                let (d2, borrow) = sbb(self.0[2], rhs.0[2], borrow);
504                let (d3, borrow) = sbb(self.0[3], rhs.0[3], borrow);
505
506                // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
507                // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
508                let (d0, carry) = adc(d0, $modulus.0[0] & borrow, 0);
509                let (d1, carry) = adc(d1, $modulus.0[1] & borrow, carry);
510                let (d2, carry) = adc(d2, $modulus.0[2] & borrow, carry);
511                let (d3, _) = adc(d3, $modulus.0[3] & borrow, carry);
512
513                $field([d0, d1, d2, d3])
514            }
515
516            /// Negates `self`.
517            #[inline]
518            pub const fn neg(&self) -> Self {
519                // Subtract `self` from `MODULUS` to negate. Ignore the final
520                // borrow because it cannot underflow; self is guaranteed to
521                // be in the field.
522                let (d0, borrow) = sbb($modulus.0[0], self.0[0], 0);
523                let (d1, borrow) = sbb($modulus.0[1], self.0[1], borrow);
524                let (d2, borrow) = sbb($modulus.0[2], self.0[2], borrow);
525                let (d3, _) = sbb($modulus.0[3], self.0[3], borrow);
526
527                // `tmp` could be `MODULUS` if `self` was zero. Create a mask that is
528                // zero if `self` was zero, and `u64::max_value()` if self was nonzero.
529                let mask =
530                    (((self.0[0] | self.0[1] | self.0[2] | self.0[3]) == 0) as u64).wrapping_sub(1);
531
532                $field([d0 & mask, d1 & mask, d2 & mask, d3 & mask])
533            }
534
535            /// Montgomery reduce where last 4 registers are 0
536            #[inline(always)]
537            pub(crate) const fn montgomery_reduce_short(r: &[u64; 4]) -> $field {
538                // The Montgomery reduction here is based on Algorithm 14.32 in
539                // Handbook of Applied Cryptography
540                // <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
541
542                let k = r[0].wrapping_mul($inv);
543                let (_, r0) = macx(r[0], k, $modulus.0[0]);
544                let (r1, r0) = mac(r[1], k, $modulus.0[1], r0);
545                let (r2, r0) = mac(r[2], k, $modulus.0[2], r0);
546                let (r3, r0) = mac(r[3], k, $modulus.0[3], r0);
547
548                let k = r1.wrapping_mul($inv);
549                let (_, r1) = macx(r1, k, $modulus.0[0]);
550                let (r2, r1) = mac(r2, k, $modulus.0[1], r1);
551                let (r3, r1) = mac(r3, k, $modulus.0[2], r1);
552                let (r0, r1) = mac(r0, k, $modulus.0[3], r1);
553
554                let k = r2.wrapping_mul($inv);
555                let (_, r2) = macx(r2, k, $modulus.0[0]);
556                let (r3, r2) = mac(r3, k, $modulus.0[1], r2);
557                let (r0, r2) = mac(r0, k, $modulus.0[2], r2);
558                let (r1, r2) = mac(r1, k, $modulus.0[3], r2);
559
560                let k = r3.wrapping_mul($inv);
561                let (_, r3) = macx(r3, k, $modulus.0[0]);
562                let (r0, r3) = mac(r0, k, $modulus.0[1], r3);
563                let (r1, r3) = mac(r1, k, $modulus.0[2], r3);
564                let (r2, r3) = mac(r2, k, $modulus.0[3], r3);
565
566                // Result may be within MODULUS of the correct value
567                (&$field([r0, r1, r2, r3])).sub(&$modulus)
568            }
569        }
570
571        impl From<$field> for [u64; 4] {
572            fn from(elt: $field) -> [u64; 4] {
573                // Turn into canonical form by computing
574                // (a.R) / R = a
575                $field::montgomery_reduce_short(&elt.0).0
576            }
577        }
578    };
579}
580
581#[macro_export]
582macro_rules! field_specific {
583    ($field:ident, $modulus:ident, $inv:ident, sparse) => {
584        impl $field {
585            /// Adds `rhs` to `self`, returning the result.
586            #[inline]
587            pub const fn add(&self, rhs: &Self) -> Self {
588                let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
589                let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
590                let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
591                let (d3, _) = adc(self.0[3], rhs.0[3], carry);
592
593                // Attempt to subtract the modulus, to ensure the value
594                // is smaller than the modulus.
595                (&$field([d0, d1, d2, d3])).sub(&$modulus)
596            }
597
598            #[inline(always)]
599            pub(crate) const fn montgomery_reduce(r: &[u64; 8]) -> $field {
600                // The Montgomery reduction here is based on Algorithm 14.32 in
601                // Handbook of Applied Cryptography
602                // <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
603
604                let k = r[0].wrapping_mul($inv);
605                let (_, carry) = mac(r[0], k, $modulus.0[0], 0);
606                let (r1, carry) = mac(r[1], k, $modulus.0[1], carry);
607                let (r2, carry) = mac(r[2], k, $modulus.0[2], carry);
608                let (r3, carry) = mac(r[3], k, $modulus.0[3], carry);
609                let (r4, carry2) = adc(r[4], 0, carry);
610
611                let k = r1.wrapping_mul($inv);
612                let (_, carry) = mac(r1, k, $modulus.0[0], 0);
613                let (r2, carry) = mac(r2, k, $modulus.0[1], carry);
614                let (r3, carry) = mac(r3, k, $modulus.0[2], carry);
615                let (r4, carry) = mac(r4, k, $modulus.0[3], carry);
616                let (r5, carry2) = adc(r[5], carry2, carry);
617
618                let k = r2.wrapping_mul($inv);
619                let (_, carry) = mac(r2, k, $modulus.0[0], 0);
620                let (r3, carry) = mac(r3, k, $modulus.0[1], carry);
621                let (r4, carry) = mac(r4, k, $modulus.0[2], carry);
622                let (r5, carry) = mac(r5, k, $modulus.0[3], carry);
623                let (r6, carry2) = adc(r[6], carry2, carry);
624
625                let k = r3.wrapping_mul($inv);
626                let (_, carry) = mac(r3, k, $modulus.0[0], 0);
627                let (r4, carry) = mac(r4, k, $modulus.0[1], carry);
628                let (r5, carry) = mac(r5, k, $modulus.0[2], carry);
629                let (r6, carry) = mac(r6, k, $modulus.0[3], carry);
630                let (r7, _) = adc(r[7], carry2, carry);
631
632                // Result may be within MODULUS of the correct value
633                (&$field([r4, r5, r6, r7])).sub(&$modulus)
634            }
635        }
636    };
637    ($field:ident, $modulus:ident, $inv:ident, dense) => {
638        impl $field {
639            /// Adds `rhs` to `self`, returning the result.
640            #[inline]
641            pub const fn add(&self, rhs: &Self) -> Self {
642                let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
643                let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
644                let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
645                let (d3, carry) = adc(self.0[3], rhs.0[3], carry);
646
647                // Attempt to subtract the modulus, to ensure the value
648                // is smaller than the modulus.
649                let (d0, borrow) = sbb(d0, $modulus.0[0], 0);
650                let (d1, borrow) = sbb(d1, $modulus.0[1], borrow);
651                let (d2, borrow) = sbb(d2, $modulus.0[2], borrow);
652                let (d3, borrow) = sbb(d3, $modulus.0[3], borrow);
653                let (_, borrow) = sbb(carry, 0, borrow);
654
655                let (d0, carry) = adc(d0, $modulus.0[0] & borrow, 0);
656                let (d1, carry) = adc(d1, $modulus.0[1] & borrow, carry);
657                let (d2, carry) = adc(d2, $modulus.0[2] & borrow, carry);
658                let (d3, _) = adc(d3, $modulus.0[3] & borrow, carry);
659
660                $field([d0, d1, d2, d3])
661            }
662
663            #[inline(always)]
664            pub(crate) const fn montgomery_reduce(r: &[u64; 8]) -> Self {
665                // The Montgomery reduction here is based on Algorithm 14.32 in
666                // Handbook of Applied Cryptography
667                // <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
668
669                let k = r[0].wrapping_mul($inv);
670                let (_, carry) = mac(r[0], k, $modulus.0[0], 0);
671                let (r1, carry) = mac(r[1], k, $modulus.0[1], carry);
672                let (r2, carry) = mac(r[2], k, $modulus.0[2], carry);
673                let (r3, carry) = mac(r[3], k, $modulus.0[3], carry);
674                let (r4, carry2) = adc(r[4], 0, carry);
675
676                let k = r1.wrapping_mul($inv);
677                let (_, carry) = mac(r1, k, $modulus.0[0], 0);
678                let (r2, carry) = mac(r2, k, $modulus.0[1], carry);
679                let (r3, carry) = mac(r3, k, $modulus.0[2], carry);
680                let (r4, carry) = mac(r4, k, $modulus.0[3], carry);
681                let (r5, carry2) = adc(r[5], carry2, carry);
682
683                let k = r2.wrapping_mul($inv);
684                let (_, carry) = mac(r2, k, $modulus.0[0], 0);
685                let (r3, carry) = mac(r3, k, $modulus.0[1], carry);
686                let (r4, carry) = mac(r4, k, $modulus.0[2], carry);
687                let (r5, carry) = mac(r5, k, $modulus.0[3], carry);
688                let (r6, carry2) = adc(r[6], carry2, carry);
689
690                let k = r3.wrapping_mul($inv);
691                let (_, carry) = mac(r3, k, $modulus.0[0], 0);
692                let (r4, carry) = mac(r4, k, $modulus.0[1], carry);
693                let (r5, carry) = mac(r5, k, $modulus.0[2], carry);
694                let (r6, carry) = mac(r6, k, $modulus.0[3], carry);
695                let (r7, carry2) = adc(r[7], carry2, carry);
696
697                // Result may be within MODULUS of the correct value
698                let (d0, borrow) = sbb(r4, $modulus.0[0], 0);
699                let (d1, borrow) = sbb(r5, $modulus.0[1], borrow);
700                let (d2, borrow) = sbb(r6, $modulus.0[2], borrow);
701                let (d3, borrow) = sbb(r7, $modulus.0[3], borrow);
702                let (_, borrow) = sbb(carry2, 0, borrow);
703
704                let (d0, carry) = adc(d0, $modulus.0[0] & borrow, 0);
705                let (d1, carry) = adc(d1, $modulus.0[1] & borrow, carry);
706                let (d2, carry) = adc(d2, $modulus.0[2] & borrow, carry);
707                let (d3, _) = adc(d3, $modulus.0[3] & borrow, carry);
708
709                $field([d0, d1, d2, d3])
710            }
711        }
712    };
713}
714
715#[macro_export]
716macro_rules! field_bits {
717    // For #[cfg(target_pointer_width = "64")]
718    ($field:ident, $modulus:ident) => {
719        #[cfg(feature = "bits")]
720        #[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
721        impl ::ff::PrimeFieldBits for $field {
722            type ReprBits = [u64; 4];
723
724            fn to_le_bits(&self) -> ::ff::FieldBits<Self::ReprBits> {
725                let bytes = self.to_repr();
726
727                let limbs = [
728                    u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
729                    u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
730                    u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
731                    u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
732                ];
733
734                ::ff::FieldBits::new(limbs)
735            }
736
737            fn char_le_bits() -> ::ff::FieldBits<Self::ReprBits> {
738                ::ff::FieldBits::new($modulus.0)
739            }
740        }
741    };
742    // For #[cfg(not(target_pointer_width = "64"))]
743    ($field:ident, $modulus:ident, $modulus_limbs_32:ident) => {
744        #[cfg(feature = "bits")]
745        #[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
746        impl ::ff::PrimeFieldBits for $field {
747            type ReprBits = [u32; 8];
748
749            fn to_le_bits(&self) -> ::ff::FieldBits<Self::ReprBits> {
750                let bytes = self.to_repr();
751
752                let limbs = [
753                    u32::from_le_bytes(bytes[0..4].try_into().unwrap()),
754                    u32::from_le_bytes(bytes[4..8].try_into().unwrap()),
755                    u32::from_le_bytes(bytes[8..12].try_into().unwrap()),
756                    u32::from_le_bytes(bytes[12..16].try_into().unwrap()),
757                    u32::from_le_bytes(bytes[16..20].try_into().unwrap()),
758                    u32::from_le_bytes(bytes[20..24].try_into().unwrap()),
759                    u32::from_le_bytes(bytes[24..28].try_into().unwrap()),
760                    u32::from_le_bytes(bytes[28..32].try_into().unwrap()),
761                ];
762
763                ::ff::FieldBits::new(limbs)
764            }
765
766            fn char_le_bits() -> ::ff::FieldBits<Self::ReprBits> {
767                ::ff::FieldBits::new($modulus_limbs_32)
768            }
769        }
770    };
771}
772
773/// A macro to help define serialization and deserialization for prime field implementations
774/// that use 32-byte representations. This assumes the concerned type implements PrimeField
775/// (for from_repr, to_repr).
776#[macro_export]
777macro_rules! serialize_deserialize_32_byte_primefield {
778    ($type:ty) => {
779        impl ::serde::Serialize for $type {
780            fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
781                let bytes = &self.to_repr();
782                if serializer.is_human_readable() {
783                    hex::serde::serialize(bytes, serializer)
784                } else {
785                    bytes.serialize(serializer)
786                }
787            }
788        }
789
790        use ::serde::de::Error as _;
791        impl<'de> ::serde::Deserialize<'de> for $type {
792            fn deserialize<D: ::serde::Deserializer<'de>>(
793                deserializer: D,
794            ) -> Result<Self, D::Error> {
795                let bytes = if deserializer.is_human_readable() {
796                    ::hex::serde::deserialize(deserializer)?
797                } else {
798                    <[u8; 32]>::deserialize(deserializer)?
799                };
800                Option::from(Self::from_repr(bytes)).ok_or_else(|| {
801                    D::Error::custom("deserialized bytes don't encode a valid field element")
802                })
803            }
804        }
805    };
806}