jubjub/
fr.rs

1//! This module provides an implementation of the Jubjub scalar field $\mathbb{F}_r$
2//! where `r = 0x0e7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7`
3
4use core::convert::TryInto;
5use core::fmt;
6use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8use ff::{Field, PrimeField};
9use rand_core::RngCore;
10use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
11
12#[cfg(feature = "bits")]
13use ff::{FieldBits, PrimeFieldBits};
14
15use crate::util::{adc, mac, sbb};
16
17/// Represents an element of the scalar field $\mathbb{F}_r$ of the Jubjub elliptic
18/// curve construction.
19// The internal representation of this type is four 64-bit unsigned
20// integers in little-endian order. Elements of Fr are always in
21// Montgomery form; i.e., Fr(a) = aR mod r, with R = 2^256.
22#[derive(Clone, Copy, Eq)]
23pub struct Fr(pub(crate) [u64; 4]);
24
25impl fmt::Debug for Fr {
26    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27        let tmp = self.to_bytes();
28        write!(f, "0x")?;
29        for &b in tmp.iter().rev() {
30            write!(f, "{:02x}", b)?;
31        }
32        Ok(())
33    }
34}
35
36impl fmt::Display for Fr {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        write!(f, "{:?}", self)
39    }
40}
41
42impl From<u64> for Fr {
43    fn from(val: u64) -> Fr {
44        Fr([val, 0, 0, 0]) * R2
45    }
46}
47
48impl ConstantTimeEq for Fr {
49    fn ct_eq(&self, other: &Self) -> Choice {
50        self.0[0].ct_eq(&other.0[0])
51            & self.0[1].ct_eq(&other.0[1])
52            & self.0[2].ct_eq(&other.0[2])
53            & self.0[3].ct_eq(&other.0[3])
54    }
55}
56
57impl PartialEq for Fr {
58    #[inline]
59    fn eq(&self, other: &Self) -> bool {
60        bool::from(self.ct_eq(other))
61    }
62}
63
64impl ConditionallySelectable for Fr {
65    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
66        Fr([
67            u64::conditional_select(&a.0[0], &b.0[0], choice),
68            u64::conditional_select(&a.0[1], &b.0[1], choice),
69            u64::conditional_select(&a.0[2], &b.0[2], choice),
70            u64::conditional_select(&a.0[3], &b.0[3], choice),
71        ])
72    }
73}
74
75/// Constant representing the modulus
76/// r = 0x0e7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7
77pub const MODULUS: Fr = Fr([
78    0xd097_0e5e_d6f7_2cb7,
79    0xa668_2093_ccc8_1082,
80    0x0667_3b01_0134_3b00,
81    0x0e7d_b4ea_6533_afa9,
82]);
83
84/// The modulus as u32 limbs.
85#[cfg(not(target_pointer_width = "64"))]
86const MODULUS_LIMBS_32: [u32; 8] = [
87    0xd6f7_2cb7,
88    0xd097_0e5e,
89    0xccc8_1082,
90    0xa668_2093,
91    0x0134_3b00,
92    0x0667_3b01,
93    0x6533_afa9,
94    0x0e7d_b4ea,
95];
96
97// The number of bits needed to represent the modulus.
98const MODULUS_BITS: u32 = 252;
99
100// GENERATOR = 6 (multiplicative generator of r-1 order, that is also quadratic nonresidue)
101const GENERATOR: Fr = Fr([
102    0x720b_1b19_d49e_a8f1,
103    0xbf4a_a361_01f1_3a58,
104    0x5fa8_cc96_8193_ccbb,
105    0x0e70_cbdc_7dcc_f3ac,
106]);
107
108// 2^S * t = MODULUS - 1 with t odd
109const S: u32 = 1;
110
111// 2^S root of unity computed by GENERATOR^t
112const ROOT_OF_UNITY: Fr = Fr([
113    0xaa9f_02ab_1d61_24de,
114    0xb352_4a64_6611_2932,
115    0x7342_2612_15ac_260b,
116    0x04d6_b87b_1da2_59e2,
117]);
118
119impl<'a> Neg for &'a Fr {
120    type Output = Fr;
121
122    #[inline]
123    fn neg(self) -> Fr {
124        self.neg()
125    }
126}
127
128impl Neg for Fr {
129    type Output = Fr;
130
131    #[inline]
132    fn neg(self) -> Fr {
133        -&self
134    }
135}
136
137impl<'a, 'b> Sub<&'b Fr> for &'a Fr {
138    type Output = Fr;
139
140    #[inline]
141    fn sub(self, rhs: &'b Fr) -> Fr {
142        self.sub(rhs)
143    }
144}
145
146impl<'a, 'b> Add<&'b Fr> for &'a Fr {
147    type Output = Fr;
148
149    #[inline]
150    fn add(self, rhs: &'b Fr) -> Fr {
151        self.add(rhs)
152    }
153}
154
155impl<'a, 'b> Mul<&'b Fr> for &'a Fr {
156    type Output = Fr;
157
158    #[inline]
159    fn mul(self, rhs: &'b Fr) -> Fr {
160        // Schoolbook multiplication
161
162        self.mul(rhs)
163    }
164}
165
166impl_binops_additive!(Fr, Fr);
167impl_binops_multiplicative!(Fr, Fr);
168
169/// INV = -(r^{-1} mod 2^64) mod 2^64
170const INV: u64 = 0x1ba3_a358_ef78_8ef9;
171
172/// R = 2^256 mod r
173const R: Fr = Fr([
174    0x25f8_0bb3_b996_07d9,
175    0xf315_d62f_66b6_e750,
176    0x9325_14ee_eb88_14f4,
177    0x09a6_fc6f_4791_55c6,
178]);
179
180/// R^2 = 2^512 mod r
181const R2: Fr = Fr([
182    0x6771_9aa4_95e5_7731,
183    0x51b0_cef0_9ce3_fc26,
184    0x69da_b7fa_c026_e9a5,
185    0x04f6_547b_8d12_7688,
186]);
187
188/// R^3 = 2^768 mod r
189const R3: Fr = Fr([
190    0xe0d6_c656_3d83_0544,
191    0x323e_3883_598d_0f85,
192    0xf0fe_a300_4c2e_2ba8,
193    0x0587_4f84_9467_37ec,
194]);
195
196impl Default for Fr {
197    fn default() -> Self {
198        Self::zero()
199    }
200}
201
202impl Fr {
203    /// Returns zero, the additive identity.
204    #[inline]
205    pub const fn zero() -> Fr {
206        Fr([0, 0, 0, 0])
207    }
208
209    /// Returns one, the multiplicative identity.
210    #[inline]
211    pub const fn one() -> Fr {
212        R
213    }
214
215    /// Doubles this field element.
216    #[inline]
217    pub const fn double(&self) -> Fr {
218        self.add(self)
219    }
220
221    /// Attempts to convert a little-endian byte representation of
222    /// a field element into an element of `Fr`, failing if the input
223    /// is not canonical (is not smaller than r).
224    pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Fr> {
225        let mut tmp = Fr([0, 0, 0, 0]);
226
227        tmp.0[0] = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
228        tmp.0[1] = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
229        tmp.0[2] = u64::from_le_bytes(bytes[16..24].try_into().unwrap());
230        tmp.0[3] = u64::from_le_bytes(bytes[24..32].try_into().unwrap());
231
232        // Try to subtract the modulus
233        let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
234        let (_, borrow) = sbb(tmp.0[1], MODULUS.0[1], borrow);
235        let (_, borrow) = sbb(tmp.0[2], MODULUS.0[2], borrow);
236        let (_, borrow) = sbb(tmp.0[3], MODULUS.0[3], borrow);
237
238        // If the element is smaller than MODULUS then the
239        // subtraction will underflow, producing a borrow value
240        // of 0xffff...ffff. Otherwise, it'll be zero.
241        let is_some = (borrow as u8) & 1;
242
243        // Convert to Montgomery form by computing
244        // (a.R^0 * R^2) / R = a.R
245        tmp *= &R2;
246
247        CtOption::new(tmp, Choice::from(is_some))
248    }
249
250    /// Converts an element of `Fr` into a byte representation in
251    /// little-endian byte order.
252    pub fn to_bytes(&self) -> [u8; 32] {
253        // Turn into canonical form by computing
254        // (a.R) / R = a
255        let tmp = Fr::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
256
257        let mut res = [0; 32];
258        res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
259        res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
260        res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
261        res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
262
263        res
264    }
265
266    /// Converts a 512-bit little endian integer into
267    /// an element of Fr by reducing modulo r.
268    pub fn from_bytes_wide(bytes: &[u8; 64]) -> Fr {
269        Fr::from_u512([
270            u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
271            u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
272            u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
273            u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
274            u64::from_le_bytes(bytes[32..40].try_into().unwrap()),
275            u64::from_le_bytes(bytes[40..48].try_into().unwrap()),
276            u64::from_le_bytes(bytes[48..56].try_into().unwrap()),
277            u64::from_le_bytes(bytes[56..64].try_into().unwrap()),
278        ])
279    }
280
281    fn from_u512(limbs: [u64; 8]) -> Fr {
282        // We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits
283        // with the higher bits multiplied by 2^256. Thus, we perform two reductions
284        //
285        // 1. the lower bits are multiplied by R^2, as normal
286        // 2. the upper bits are multiplied by R^2 * 2^256 = R^3
287        //
288        // and computing their sum in the field. It remains to see that arbitrary 256-bit
289        // numbers can be placed into Montgomery form safely using the reduction. The
290        // reduction works so long as the product is less than R=2^256 multiplied by
291        // the modulus. This holds because for any `c` smaller than the modulus, we have
292        // that (2^256 - 1)*c is an acceptable product for the reduction. Therefore, the
293        // reduction always works so long as `c` is in the field; in this case it is either the
294        // constant `R2` or `R3`.
295        let d0 = Fr([limbs[0], limbs[1], limbs[2], limbs[3]]);
296        let d1 = Fr([limbs[4], limbs[5], limbs[6], limbs[7]]);
297        // Convert to Montgomery form
298        d0 * R2 + d1 * R3
299    }
300
301    /// Converts from an integer represented in little endian
302    /// into its (congruent) `Fr` representation.
303    pub const fn from_raw(val: [u64; 4]) -> Self {
304        (&Fr(val)).mul(&R2)
305    }
306
307    /// Squares this element.
308    #[inline]
309    pub const fn square(&self) -> Fr {
310        let (r1, carry) = mac(0, self.0[0], self.0[1], 0);
311        let (r2, carry) = mac(0, self.0[0], self.0[2], carry);
312        let (r3, r4) = mac(0, self.0[0], self.0[3], carry);
313
314        let (r3, carry) = mac(r3, self.0[1], self.0[2], 0);
315        let (r4, r5) = mac(r4, self.0[1], self.0[3], carry);
316
317        let (r5, r6) = mac(r5, self.0[2], self.0[3], 0);
318
319        let r7 = r6 >> 63;
320        let r6 = (r6 << 1) | (r5 >> 63);
321        let r5 = (r5 << 1) | (r4 >> 63);
322        let r4 = (r4 << 1) | (r3 >> 63);
323        let r3 = (r3 << 1) | (r2 >> 63);
324        let r2 = (r2 << 1) | (r1 >> 63);
325        let r1 = r1 << 1;
326
327        let (r0, carry) = mac(0, self.0[0], self.0[0], 0);
328        let (r1, carry) = adc(0, r1, carry);
329        let (r2, carry) = mac(r2, self.0[1], self.0[1], carry);
330        let (r3, carry) = adc(0, r3, carry);
331        let (r4, carry) = mac(r4, self.0[2], self.0[2], carry);
332        let (r5, carry) = adc(0, r5, carry);
333        let (r6, carry) = mac(r6, self.0[3], self.0[3], carry);
334        let (r7, _) = adc(0, r7, carry);
335
336        Fr::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
337    }
338
339    /// Computes the square root of this element, if it exists.
340    pub fn sqrt(&self) -> CtOption<Self> {
341        // Because r = 3 (mod 4)
342        // sqrt can be done with only one exponentiation,
343        // via the computation of  self^((r + 1) // 4) (mod r)
344        let sqrt = self.pow_vartime(&[
345            0xb425_c397_b5bd_cb2e,
346            0x299a_0824_f332_0420,
347            0x4199_cec0_404d_0ec0,
348            0x039f_6d3a_994c_ebea,
349        ]);
350
351        CtOption::new(
352            sqrt,
353            (sqrt * sqrt).ct_eq(self), // Only return Some if it's the square root.
354        )
355    }
356
357    /// Exponentiates `self` by `by`, where `by` is a
358    /// little-endian order integer exponent.
359    pub fn pow(&self, by: &[u64; 4]) -> Self {
360        let mut res = Self::one();
361        for e in by.iter().rev() {
362            for i in (0..64).rev() {
363                res = res.square();
364                let mut tmp = res;
365                tmp.mul_assign(self);
366                res.conditional_assign(&tmp, (((*e >> i) & 0x1) as u8).into());
367            }
368        }
369        res
370    }
371
372    /// Exponentiates `self` by `by`, where `by` is a
373    /// little-endian order integer exponent.
374    ///
375    /// **This operation is variable time with respect
376    /// to the exponent.** If the exponent is fixed,
377    /// this operation is effectively constant time.
378    pub fn pow_vartime(&self, by: &[u64; 4]) -> Self {
379        let mut res = Self::one();
380        for e in by.iter().rev() {
381            for i in (0..64).rev() {
382                res = res.square();
383
384                if ((*e >> i) & 1) == 1 {
385                    res.mul_assign(self);
386                }
387            }
388        }
389        res
390    }
391
392    /// Computes the multiplicative inverse of this element,
393    /// failing if the element is zero.
394    pub fn invert(&self) -> CtOption<Self> {
395        #[inline(always)]
396        fn square_assign_multi(n: &mut Fr, num_times: usize) {
397            for _ in 0..num_times {
398                *n = n.square();
399            }
400        }
401        // found using https://github.com/kwantam/addchain
402        let mut t1 = self.square();
403        let mut t0 = t1.square();
404        let mut t3 = t0 * t1;
405        let t6 = t3 * self;
406        let t7 = t6 * t1;
407        let t12 = t7 * t3;
408        let t13 = t12 * t0;
409        let t16 = t12 * t3;
410        let t2 = t13 * t3;
411        let t15 = t16 * t3;
412        let t19 = t2 * t0;
413        let t9 = t15 * t3;
414        let t18 = t9 * t3;
415        let t14 = t18 * t1;
416        let t4 = t18 * t0;
417        let t8 = t18 * t3;
418        let t17 = t14 * t3;
419        let t11 = t8 * t3;
420        t1 = t17 * t3;
421        let t5 = t11 * t3;
422        t3 = t5 * t0;
423        t0 = t5.square();
424        square_assign_multi(&mut t0, 5);
425        t0.mul_assign(&t3);
426        square_assign_multi(&mut t0, 6);
427        t0.mul_assign(&t8);
428        square_assign_multi(&mut t0, 7);
429        t0.mul_assign(&t19);
430        square_assign_multi(&mut t0, 6);
431        t0.mul_assign(&t13);
432        square_assign_multi(&mut t0, 8);
433        t0.mul_assign(&t14);
434        square_assign_multi(&mut t0, 6);
435        t0.mul_assign(&t18);
436        square_assign_multi(&mut t0, 7);
437        t0.mul_assign(&t17);
438        square_assign_multi(&mut t0, 5);
439        t0.mul_assign(&t16);
440        square_assign_multi(&mut t0, 3);
441        t0.mul_assign(self);
442        square_assign_multi(&mut t0, 11);
443        t0.mul_assign(&t11);
444        square_assign_multi(&mut t0, 8);
445        t0.mul_assign(&t5);
446        square_assign_multi(&mut t0, 5);
447        t0.mul_assign(&t15);
448        square_assign_multi(&mut t0, 8);
449        t0.mul_assign(self);
450        square_assign_multi(&mut t0, 12);
451        t0.mul_assign(&t13);
452        square_assign_multi(&mut t0, 7);
453        t0.mul_assign(&t9);
454        square_assign_multi(&mut t0, 5);
455        t0.mul_assign(&t15);
456        square_assign_multi(&mut t0, 14);
457        t0.mul_assign(&t14);
458        square_assign_multi(&mut t0, 5);
459        t0.mul_assign(&t13);
460        square_assign_multi(&mut t0, 2);
461        t0.mul_assign(self);
462        square_assign_multi(&mut t0, 6);
463        t0.mul_assign(self);
464        square_assign_multi(&mut t0, 9);
465        t0.mul_assign(&t7);
466        square_assign_multi(&mut t0, 6);
467        t0.mul_assign(&t12);
468        square_assign_multi(&mut t0, 8);
469        t0.mul_assign(&t11);
470        square_assign_multi(&mut t0, 3);
471        t0.mul_assign(self);
472        square_assign_multi(&mut t0, 12);
473        t0.mul_assign(&t9);
474        square_assign_multi(&mut t0, 11);
475        t0.mul_assign(&t8);
476        square_assign_multi(&mut t0, 8);
477        t0.mul_assign(&t7);
478        square_assign_multi(&mut t0, 4);
479        t0.mul_assign(&t6);
480        square_assign_multi(&mut t0, 10);
481        t0.mul_assign(&t5);
482        square_assign_multi(&mut t0, 7);
483        t0.mul_assign(&t3);
484        square_assign_multi(&mut t0, 6);
485        t0.mul_assign(&t4);
486        square_assign_multi(&mut t0, 7);
487        t0.mul_assign(&t3);
488        square_assign_multi(&mut t0, 5);
489        t0.mul_assign(&t2);
490        square_assign_multi(&mut t0, 6);
491        t0.mul_assign(&t2);
492        square_assign_multi(&mut t0, 7);
493        t0.mul_assign(&t1);
494
495        CtOption::new(t0, !self.ct_eq(&Self::zero()))
496    }
497
498    #[inline]
499    #[allow(clippy::too_many_arguments)]
500    const fn montgomery_reduce(
501        r0: u64,
502        r1: u64,
503        r2: u64,
504        r3: u64,
505        r4: u64,
506        r5: u64,
507        r6: u64,
508        r7: u64,
509    ) -> Self {
510        // The Montgomery reduction here is based on Algorithm 14.32 in
511        // Handbook of Applied Cryptography
512        // <http://cacr.uwaterloo.ca/hac/about/chap14.pdf>.
513
514        let k = r0.wrapping_mul(INV);
515        let (_, carry) = mac(r0, k, MODULUS.0[0], 0);
516        let (r1, carry) = mac(r1, k, MODULUS.0[1], carry);
517        let (r2, carry) = mac(r2, k, MODULUS.0[2], carry);
518        let (r3, carry) = mac(r3, k, MODULUS.0[3], carry);
519        let (r4, carry2) = adc(r4, 0, carry);
520
521        let k = r1.wrapping_mul(INV);
522        let (_, carry) = mac(r1, k, MODULUS.0[0], 0);
523        let (r2, carry) = mac(r2, k, MODULUS.0[1], carry);
524        let (r3, carry) = mac(r3, k, MODULUS.0[2], carry);
525        let (r4, carry) = mac(r4, k, MODULUS.0[3], carry);
526        let (r5, carry2) = adc(r5, carry2, carry);
527
528        let k = r2.wrapping_mul(INV);
529        let (_, carry) = mac(r2, k, MODULUS.0[0], 0);
530        let (r3, carry) = mac(r3, k, MODULUS.0[1], carry);
531        let (r4, carry) = mac(r4, k, MODULUS.0[2], carry);
532        let (r5, carry) = mac(r5, k, MODULUS.0[3], carry);
533        let (r6, carry2) = adc(r6, carry2, carry);
534
535        let k = r3.wrapping_mul(INV);
536        let (_, carry) = mac(r3, k, MODULUS.0[0], 0);
537        let (r4, carry) = mac(r4, k, MODULUS.0[1], carry);
538        let (r5, carry) = mac(r5, k, MODULUS.0[2], carry);
539        let (r6, carry) = mac(r6, k, MODULUS.0[3], carry);
540        let (r7, _) = adc(r7, carry2, carry);
541
542        // Result may be within MODULUS of the correct value
543        (&Fr([r4, r5, r6, r7])).sub(&MODULUS)
544    }
545
546    /// Multiplies this element by another element
547    #[inline]
548    pub const fn mul(&self, rhs: &Self) -> Self {
549        // Schoolbook multiplication
550
551        let (r0, carry) = mac(0, self.0[0], rhs.0[0], 0);
552        let (r1, carry) = mac(0, self.0[0], rhs.0[1], carry);
553        let (r2, carry) = mac(0, self.0[0], rhs.0[2], carry);
554        let (r3, r4) = mac(0, self.0[0], rhs.0[3], carry);
555
556        let (r1, carry) = mac(r1, self.0[1], rhs.0[0], 0);
557        let (r2, carry) = mac(r2, self.0[1], rhs.0[1], carry);
558        let (r3, carry) = mac(r3, self.0[1], rhs.0[2], carry);
559        let (r4, r5) = mac(r4, self.0[1], rhs.0[3], carry);
560
561        let (r2, carry) = mac(r2, self.0[2], rhs.0[0], 0);
562        let (r3, carry) = mac(r3, self.0[2], rhs.0[1], carry);
563        let (r4, carry) = mac(r4, self.0[2], rhs.0[2], carry);
564        let (r5, r6) = mac(r5, self.0[2], rhs.0[3], carry);
565
566        let (r3, carry) = mac(r3, self.0[3], rhs.0[0], 0);
567        let (r4, carry) = mac(r4, self.0[3], rhs.0[1], carry);
568        let (r5, carry) = mac(r5, self.0[3], rhs.0[2], carry);
569        let (r6, r7) = mac(r6, self.0[3], rhs.0[3], carry);
570
571        Fr::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
572    }
573
574    /// Subtracts another element from this element.
575    #[inline]
576    pub const fn sub(&self, rhs: &Self) -> Self {
577        let (d0, borrow) = sbb(self.0[0], rhs.0[0], 0);
578        let (d1, borrow) = sbb(self.0[1], rhs.0[1], borrow);
579        let (d2, borrow) = sbb(self.0[2], rhs.0[2], borrow);
580        let (d3, borrow) = sbb(self.0[3], rhs.0[3], borrow);
581
582        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
583        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
584        let (d0, carry) = adc(d0, MODULUS.0[0] & borrow, 0);
585        let (d1, carry) = adc(d1, MODULUS.0[1] & borrow, carry);
586        let (d2, carry) = adc(d2, MODULUS.0[2] & borrow, carry);
587        let (d3, _) = adc(d3, MODULUS.0[3] & borrow, carry);
588
589        Fr([d0, d1, d2, d3])
590    }
591
592    /// Adds this element to another element.
593    #[inline]
594    pub const fn add(&self, rhs: &Self) -> Self {
595        let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
596        let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
597        let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
598        let (d3, _) = adc(self.0[3], rhs.0[3], carry);
599
600        // Attempt to subtract the modulus, to ensure the value
601        // is smaller than the modulus.
602        (&Fr([d0, d1, d2, d3])).sub(&MODULUS)
603    }
604
605    /// Negates this element.
606    #[inline]
607    pub const fn neg(&self) -> Self {
608        // Subtract `self` from `MODULUS` to negate. Ignore the final
609        // borrow because it cannot underflow; self is guaranteed to
610        // be in the field.
611        let (d0, borrow) = sbb(MODULUS.0[0], self.0[0], 0);
612        let (d1, borrow) = sbb(MODULUS.0[1], self.0[1], borrow);
613        let (d2, borrow) = sbb(MODULUS.0[2], self.0[2], borrow);
614        let (d3, _) = sbb(MODULUS.0[3], self.0[3], borrow);
615
616        // `tmp` could be `MODULUS` if `self` was zero. Create a mask that is
617        // zero if `self` was zero, and `u64::max_value()` if self was nonzero.
618        let mask = (((self.0[0] | self.0[1] | self.0[2] | self.0[3]) == 0) as u64).wrapping_sub(1);
619
620        Fr([d0 & mask, d1 & mask, d2 & mask, d3 & mask])
621    }
622}
623
624impl From<Fr> for [u8; 32] {
625    fn from(value: Fr) -> [u8; 32] {
626        value.to_bytes()
627    }
628}
629
630impl<'a> From<&'a Fr> for [u8; 32] {
631    fn from(value: &'a Fr) -> [u8; 32] {
632        value.to_bytes()
633    }
634}
635
636impl Field for Fr {
637    fn random(mut rng: impl RngCore) -> Self {
638        let mut buf = [0; 64];
639        rng.fill_bytes(&mut buf);
640        Self::from_bytes_wide(&buf)
641    }
642
643    fn zero() -> Self {
644        Self::zero()
645    }
646
647    fn one() -> Self {
648        Self::one()
649    }
650
651    #[must_use]
652    fn square(&self) -> Self {
653        self.square()
654    }
655
656    #[must_use]
657    fn double(&self) -> Self {
658        self.double()
659    }
660
661    fn invert(&self) -> CtOption<Self> {
662        self.invert()
663    }
664
665    fn sqrt(&self) -> CtOption<Self> {
666        self.sqrt()
667    }
668}
669
670impl PrimeField for Fr {
671    type Repr = [u8; 32];
672
673    fn from_repr(r: Self::Repr) -> CtOption<Self> {
674        Self::from_bytes(&r)
675    }
676
677    fn to_repr(&self) -> Self::Repr {
678        self.to_bytes()
679    }
680
681    fn is_odd(&self) -> Choice {
682        Choice::from(self.to_bytes()[0] & 1)
683    }
684
685    const NUM_BITS: u32 = MODULUS_BITS;
686    const CAPACITY: u32 = Self::NUM_BITS - 1;
687
688    fn multiplicative_generator() -> Self {
689        GENERATOR
690    }
691
692    const S: u32 = S;
693
694    fn root_of_unity() -> Self {
695        ROOT_OF_UNITY
696    }
697}
698
699#[cfg(all(feature = "bits", not(target_pointer_width = "64")))]
700type ReprBits = [u32; 8];
701
702#[cfg(all(feature = "bits", target_pointer_width = "64"))]
703type ReprBits = [u64; 4];
704
705#[cfg(feature = "bits")]
706impl PrimeFieldBits for Fr {
707    type ReprBits = ReprBits;
708
709    fn to_le_bits(&self) -> FieldBits<Self::ReprBits> {
710        let bytes = self.to_bytes();
711
712        #[cfg(not(target_pointer_width = "64"))]
713        let limbs = [
714            u32::from_le_bytes(bytes[0..4].try_into().unwrap()),
715            u32::from_le_bytes(bytes[4..8].try_into().unwrap()),
716            u32::from_le_bytes(bytes[8..12].try_into().unwrap()),
717            u32::from_le_bytes(bytes[12..16].try_into().unwrap()),
718            u32::from_le_bytes(bytes[16..20].try_into().unwrap()),
719            u32::from_le_bytes(bytes[20..24].try_into().unwrap()),
720            u32::from_le_bytes(bytes[24..28].try_into().unwrap()),
721            u32::from_le_bytes(bytes[28..32].try_into().unwrap()),
722        ];
723
724        #[cfg(target_pointer_width = "64")]
725        let limbs = [
726            u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
727            u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
728            u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
729            u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
730        ];
731
732        FieldBits::new(limbs)
733    }
734
735    fn char_le_bits() -> FieldBits<Self::ReprBits> {
736        #[cfg(not(target_pointer_width = "64"))]
737        {
738            FieldBits::new(MODULUS_LIMBS_32)
739        }
740
741        #[cfg(target_pointer_width = "64")]
742        FieldBits::new(MODULUS.0)
743    }
744}
745
746#[test]
747fn test_inv() {
748    // Compute -(r^{-1} mod 2^64) mod 2^64 by exponentiating
749    // by totient(2**64) - 1
750
751    let mut inv = 1u64;
752    for _ in 0..63 {
753        inv = inv.wrapping_mul(inv);
754        inv = inv.wrapping_mul(MODULUS.0[0]);
755    }
756    inv = inv.wrapping_neg();
757
758    assert_eq!(inv, INV);
759}
760
761#[test]
762fn test_debug() {
763    assert_eq!(
764        format!("{:?}", Fr::zero()),
765        "0x0000000000000000000000000000000000000000000000000000000000000000"
766    );
767    assert_eq!(
768        format!("{:?}", Fr::one()),
769        "0x0000000000000000000000000000000000000000000000000000000000000001"
770    );
771    assert_eq!(
772        format!("{:?}", R2),
773        "0x09a6fc6f479155c6932514eeeb8814f4f315d62f66b6e75025f80bb3b99607d9"
774    );
775}
776
777#[test]
778fn test_equality() {
779    assert_eq!(Fr::zero(), Fr::zero());
780    assert_eq!(Fr::one(), Fr::one());
781    assert_eq!(R2, R2);
782
783    assert!(Fr::zero() != Fr::one());
784    assert!(Fr::one() != R2);
785}
786
787#[test]
788fn test_to_bytes() {
789    assert_eq!(
790        Fr::zero().to_bytes(),
791        [
792            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
793            0, 0, 0
794        ]
795    );
796
797    assert_eq!(
798        Fr::one().to_bytes(),
799        [
800            1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
801            0, 0, 0
802        ]
803    );
804
805    assert_eq!(
806        R2.to_bytes(),
807        [
808            217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
809            235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9
810        ]
811    );
812
813    assert_eq!(
814        (-&Fr::one()).to_bytes(),
815        [
816            182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
817            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
818        ]
819    );
820}
821
822#[test]
823fn test_from_bytes() {
824    assert_eq!(
825        Fr::from_bytes(&[
826            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
827            0, 0, 0
828        ])
829        .unwrap(),
830        Fr::zero()
831    );
832
833    assert_eq!(
834        Fr::from_bytes(&[
835            1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836            0, 0, 0
837        ])
838        .unwrap(),
839        Fr::one()
840    );
841
842    assert_eq!(
843        Fr::from_bytes(&[
844            217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
845            235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9
846        ])
847        .unwrap(),
848        R2
849    );
850
851    // -1 should work
852    assert!(bool::from(
853        Fr::from_bytes(&[
854            182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
855            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
856        ])
857        .is_some()
858    ));
859
860    // modulus is invalid
861    assert!(bool::from(
862        Fr::from_bytes(&[
863            183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
864            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
865        ])
866        .is_none()
867    ));
868
869    // Anything larger than the modulus is invalid
870    assert!(bool::from(
871        Fr::from_bytes(&[
872            184, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
873            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
874        ])
875        .is_none()
876    ));
877
878    assert!(bool::from(
879        Fr::from_bytes(&[
880            183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
881            1, 1, 59, 104, 6, 169, 175, 51, 101, 234, 180, 125, 14
882        ])
883        .is_none()
884    ));
885
886    assert!(bool::from(
887        Fr::from_bytes(&[
888            183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
889            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 15
890        ])
891        .is_none()
892    ));
893}
894
895#[test]
896fn test_from_u512_zero() {
897    assert_eq!(
898        Fr::zero(),
899        Fr::from_u512([
900            MODULUS.0[0],
901            MODULUS.0[1],
902            MODULUS.0[2],
903            MODULUS.0[3],
904            0,
905            0,
906            0,
907            0
908        ])
909    );
910}
911
912#[test]
913fn test_from_u512_r() {
914    assert_eq!(R, Fr::from_u512([1, 0, 0, 0, 0, 0, 0, 0]));
915}
916
917#[test]
918fn test_from_u512_r2() {
919    assert_eq!(R2, Fr::from_u512([0, 0, 0, 0, 1, 0, 0, 0]));
920}
921
922#[test]
923fn test_from_u512_max() {
924    let max_u64 = 0xffff_ffff_ffff_ffff;
925    assert_eq!(
926        R3 - R,
927        Fr::from_u512([max_u64, max_u64, max_u64, max_u64, max_u64, max_u64, max_u64, max_u64])
928    );
929}
930
931#[test]
932fn test_from_bytes_wide_r2() {
933    assert_eq!(
934        R2,
935        Fr::from_bytes_wide(&[
936            217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
937            235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
938            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
939        ])
940    );
941}
942
943#[test]
944fn test_from_bytes_wide_negative_one() {
945    assert_eq!(
946        -&Fr::one(),
947        Fr::from_bytes_wide(&[
948            182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
949            1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951        ])
952    );
953}
954
955#[test]
956fn test_from_bytes_wide_maximum() {
957    assert_eq!(
958        Fr([
959            0x8b75_c901_5ae4_2a22,
960            0xe590_82e7_bf9e_38b8,
961            0x6440_c912_61da_51b3,
962            0x0a5e_07ff_b209_91cf,
963        ]),
964        Fr::from_bytes_wide(&[0xff; 64])
965    );
966}
967
968#[test]
969fn test_zero() {
970    assert_eq!(Fr::zero(), -&Fr::zero());
971    assert_eq!(Fr::zero(), Fr::zero() + Fr::zero());
972    assert_eq!(Fr::zero(), Fr::zero() - Fr::zero());
973    assert_eq!(Fr::zero(), Fr::zero() * Fr::zero());
974}
975
976#[cfg(test)]
977const LARGEST: Fr = Fr([
978    0xd097_0e5e_d6f7_2cb6,
979    0xa668_2093_ccc8_1082,
980    0x0667_3b01_0134_3b00,
981    0x0e7d_b4ea_6533_afa9,
982]);
983
984#[test]
985fn test_addition() {
986    let mut tmp = LARGEST;
987    tmp += &LARGEST;
988
989    assert_eq!(
990        tmp,
991        Fr([
992            0xd097_0e5e_d6f7_2cb5,
993            0xa668_2093_ccc8_1082,
994            0x0667_3b01_0134_3b00,
995            0x0e7d_b4ea_6533_afa9
996        ])
997    );
998
999    let mut tmp = LARGEST;
1000    tmp += &Fr([1, 0, 0, 0]);
1001
1002    assert_eq!(tmp, Fr::zero());
1003}
1004
1005#[test]
1006fn test_negation() {
1007    let tmp = -&LARGEST;
1008
1009    assert_eq!(tmp, Fr([1, 0, 0, 0]));
1010
1011    let tmp = -&Fr::zero();
1012    assert_eq!(tmp, Fr::zero());
1013    let tmp = -&Fr([1, 0, 0, 0]);
1014    assert_eq!(tmp, LARGEST);
1015}
1016
1017#[test]
1018fn test_subtraction() {
1019    let mut tmp = LARGEST;
1020    tmp -= &LARGEST;
1021
1022    assert_eq!(tmp, Fr::zero());
1023
1024    let mut tmp = Fr::zero();
1025    tmp -= &LARGEST;
1026
1027    let mut tmp2 = MODULUS;
1028    tmp2 -= &LARGEST;
1029
1030    assert_eq!(tmp, tmp2);
1031}
1032
1033#[test]
1034fn test_multiplication() {
1035    let mut cur = LARGEST;
1036
1037    for _ in 0..100 {
1038        let mut tmp = cur;
1039        tmp *= &cur;
1040
1041        let mut tmp2 = Fr::zero();
1042        for b in cur
1043            .to_bytes()
1044            .iter()
1045            .rev()
1046            .flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1u8) == 1u8))
1047        {
1048            let tmp3 = tmp2;
1049            tmp2.add_assign(&tmp3);
1050
1051            if b {
1052                tmp2.add_assign(&cur);
1053            }
1054        }
1055
1056        assert_eq!(tmp, tmp2);
1057
1058        cur.add_assign(&LARGEST);
1059    }
1060}
1061
1062#[test]
1063fn test_squaring() {
1064    let mut cur = LARGEST;
1065
1066    for _ in 0..100 {
1067        let mut tmp = cur;
1068        tmp = tmp.square();
1069
1070        let mut tmp2 = Fr::zero();
1071        for b in cur
1072            .to_bytes()
1073            .iter()
1074            .rev()
1075            .flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1u8) == 1u8))
1076        {
1077            let tmp3 = tmp2;
1078            tmp2.add_assign(&tmp3);
1079
1080            if b {
1081                tmp2.add_assign(&cur);
1082            }
1083        }
1084
1085        assert_eq!(tmp, tmp2);
1086
1087        cur.add_assign(&LARGEST);
1088    }
1089}
1090
1091#[test]
1092fn test_inversion() {
1093    assert!(bool::from(Fr::zero().invert().is_none()));
1094    assert_eq!(Fr::one().invert().unwrap(), Fr::one());
1095    assert_eq!((-&Fr::one()).invert().unwrap(), -&Fr::one());
1096
1097    let mut tmp = R2;
1098
1099    for _ in 0..100 {
1100        let mut tmp2 = tmp.invert().unwrap();
1101        tmp2.mul_assign(&tmp);
1102
1103        assert_eq!(tmp2, Fr::one());
1104
1105        tmp.add_assign(&R2);
1106    }
1107}
1108
1109#[test]
1110fn test_invert_is_pow() {
1111    let r_minus_2 = [
1112        0xd097_0e5e_d6f7_2cb5,
1113        0xa668_2093_ccc8_1082,
1114        0x0667_3b01_0134_3b00,
1115        0x0e7d_b4ea_6533_afa9,
1116    ];
1117
1118    let mut r1 = R;
1119    let mut r2 = R;
1120    let mut r3 = R;
1121
1122    for _ in 0..100 {
1123        r1 = r1.invert().unwrap();
1124        r2 = r2.pow_vartime(&r_minus_2);
1125        r3 = r3.pow(&r_minus_2);
1126
1127        assert_eq!(r1, r2);
1128        assert_eq!(r2, r3);
1129        // Add R so we check something different next time around
1130        r1.add_assign(&R);
1131        r2 = r1;
1132        r3 = r1;
1133    }
1134}
1135
1136#[test]
1137fn test_sqrt() {
1138    let mut square = Fr([
1139        // r - 2
1140        0xd097_0e5e_d6f7_2cb5,
1141        0xa668_2093_ccc8_1082,
1142        0x0667_3b01_0134_3b00,
1143        0x0e7d_b4ea_6533_afa9,
1144    ]);
1145
1146    let mut none_count = 0;
1147
1148    for _ in 0..100 {
1149        let square_root = square.sqrt();
1150        if bool::from(square_root.is_none()) {
1151            none_count += 1;
1152        } else {
1153            assert_eq!(square_root.unwrap() * square_root.unwrap(), square);
1154        }
1155        square -= Fr::one();
1156    }
1157
1158    assert_eq!(47, none_count);
1159}
1160
1161#[test]
1162fn test_from_raw() {
1163    assert_eq!(
1164        Fr::from_raw([
1165            0x25f8_0bb3_b996_07d8,
1166            0xf315_d62f_66b6_e750,
1167            0x9325_14ee_eb88_14f4,
1168            0x09a6_fc6f_4791_55c6,
1169        ]),
1170        Fr::from_raw([0xffff_ffff_ffff_ffff; 4])
1171    );
1172
1173    assert_eq!(Fr::from_raw(MODULUS.0), Fr::zero());
1174
1175    assert_eq!(Fr::from_raw([1, 0, 0, 0]), R);
1176}