decaf377/fields/
fr.rs

1use cfg_if::cfg_if;
2use rand_core::CryptoRngCore;
3
4use crate::EncodingError;
5
6#[cfg(feature = "arkworks")]
7pub mod arkworks;
8mod ops;
9pub mod u32;
10
11// The u64 backend requires arkworks
12#[cfg(feature = "arkworks")]
13pub mod u64;
14
15cfg_if! {
16    if #[cfg(feature = "arkworks")] {
17        pub type Fr = u64::Fr;
18    } else {
19        pub type Fr = u32::Fr;
20    }
21}
22
23const B: usize = 251;
24const N_8: usize = (B + 7) / 8;
25const N_32: usize = (B + 31) / 32;
26const N_64: usize = (B + 63) / 64;
27
28impl Fr {
29    pub const MODULUS_LIMBS: [u64; N_64] = [
30        13356249993388743167,
31        5950279507993463550,
32        10965441865914903552,
33        336320092672043349,
34    ];
35
36    pub const MODULUS_MINUS_ONE_DIV_TWO_LIMBS: [u64; N_64] = [
37        6678124996694371583,
38        2975139753996731775,
39        14706092969812227584,
40        168160046336021674,
41    ];
42
43    pub const MODULUS_BIT_SIZE: u32 = 0xfb;
44
45    pub const TRACE_LIMBS: [u64; N_64] = [
46        4478124994494371583,
47        2975139753994731775,
48        14704092949812227584,
49        148140044334021474,
50    ];
51
52    pub const TRACE_MINUS_ONE_DIV_TWO_LIMBS: [u64; N_64] = [
53        12542434535201941599,
54        1487549874998345887,
55        7353044484904113792,
56        84080023148010837,
57    ];
58
59    pub const TWO_ADICITY: u32 = 0x1;
60
61    pub const MULTIPLICATIVE_GENERATOR: Self = Self::from_montgomery_limbs([
62        11289572479485143824,
63        11383437349941080925,
64        2288212753973340071,
65        82014974407880291,
66    ]);
67
68    pub const TWO_ADIC_ROOT_OF_UNITY: Self = Self::from_montgomery_limbs([
69        15170730741708341141,
70        13470723484578117817,
71        12803492244414043445,
72        50841023252832411,
73    ]);
74
75    pub const FIELD_SIZE_POWER_OF_TWO: Self = Self::from_montgomery_limbs([
76        3987543627614508126,
77        17742427666091596403,
78        14557327917022607905,
79        322810149704226881,
80    ]);
81
82    pub fn from_le_bytes_mod_order(bytes: &[u8]) -> Self {
83        bytes
84            .chunks(N_8)
85            .map(|x| {
86                let mut padded = [0u8; N_8];
87                padded[..x.len()].copy_from_slice(x);
88                Self::from_raw_bytes(&padded)
89            }) // [X, 2^(256) * X, ...]
90            .rev()
91            .fold(Self::ZERO, |acc, x| {
92                acc * (Self::FIELD_SIZE_POWER_OF_TWO) + x
93            }) // let acc =
94    }
95
96    /// Convert bytes into an Fr element, returning None if these bytes are not already reduced.
97    ///
98    /// This means that values that cannot be produced by encoding a field element will return
99    /// None, enforcing canonical serialization.
100    pub fn from_bytes_checked(bytes: &[u8; N_8]) -> Result<Self, EncodingError> {
101        let reduced = Self::from_raw_bytes(bytes);
102        if reduced.to_bytes_le() == *bytes {
103            Ok(reduced)
104        } else {
105            Err(EncodingError::InvalidEncoding)
106        }
107    }
108
109    pub fn to_bytes(&self) -> [u8; N_8] {
110        self.to_bytes_le()
111    }
112
113    /// Sample a random field element uniformly.
114    pub fn rand<R: CryptoRngCore>(rng: &mut R) -> Self {
115        // Sample wide, reduce
116        let bytes = {
117            let mut out = [0u8; N_8 + 16];
118            rng.fill_bytes(&mut out);
119            out
120        };
121        Self::from_le_bytes_mod_order(&bytes)
122    }
123}
124
125#[cfg(test)]
126mod test {
127    use super::*;
128
129    #[test]
130    fn test_from_bytes_checked() {
131        assert_eq!(Fr::from_bytes_checked(&[0; N_8]), Ok(Fr::ZERO));
132        assert!(Fr::from_bytes_checked(&[0xFF; N_8]).is_err());
133    }
134}