1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use cryptix_bigint::bigint;
use cryptix_field::{Modular, PrimeModular, field::{montgomery::Montgomery, primefield::FpElement}, OddModular, Element};
use cryptix_bn254::galoisfield::U256;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Fr;
pub type FrElement = FpElement<U256, Fr>;

impl Modular<U256> for Fr {
    const P: U256 = bigint!(U256, "2523648240000001BA344D8000000007FF9F800000000010A10000000000000D");
}

impl PrimeModular<U256> for Fr { }
impl OddModular<U256> for Fr { }

impl Montgomery<U256> for Fr {
    // 0x3b13b13b
    const NEG_P_INV_B: <U256 as cryptix_bigint::property::IsBigInt>::Dig = 0xea3b13b13b13b13b;
    const R_P: FpElement<U256, Self> = FpElement(Element::new_unchecked(bigint!(U256, "212ba4f27ffffff5a2c62effffffffd00242ffffffffff9c39ffffffffffffb2")));

    const R_INV_P: FpElement<U256, Self> = FpElement(Element::new_unchecked(bigint!(U256, "235f846d22752e25720e909a9e82a1b4ad47e882341d8fca46c142d23fa9bc45")));

    /*
     * # Safety
     * 
     * this is the pre-computed value of R * R mod P, must less than P
     */
    const RR_P: FpElement<U256, Self> = {
        FpElement(Element::new_unchecked(bigint!(U256, "24e8b3bc325f9035c300765b575d5a78e0885092e2231ec3df8596b6f40aa7a1")))
    };
}