cryptix-bn254 0.1.0

A library for bn254 elliptic curve related algorithms
Documentation
use crate::{fp2, fp};

use self::fp2::Fp2Element;

pub mod fp2;
pub mod fp4;
pub mod fp12;
pub mod clotomic;

use cryptix_bigint::{BigUInt, bigint};
use cryptix_field::{Modular, PrimeModular, OddModular, Element};
use cryptix_field::field::primefield;
use cryptix_field::field::montgomery::Montgomery;

pub type U256 = BigUInt<u64, 4>;
pub type FpElement = primefield::FpElement<U256, BN254>;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct BN254;

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

/// # Safety
/// 
/// the modular P is indeed a prime number, this comes from [the parameter of ec BN254](https://neuromancer.sk/std/bn/bn254#)
impl PrimeModular<U256> for BN254 { }

/// # Safety
/// 
/// P is odd
impl OddModular<U256> for BN254 { }

impl Montgomery<U256> for BN254 {
    const R_P: FpElement = {
        primefield::FpElement(Element::new_unchecked(bigint!(U256, "212ba4f27ffffff5a2c62effffffffcdb939ffffffffff8a15ffffffffffff8e")))
    };

    const R_INV_P: FpElement = {
        primefield::FpElement(Element::new_unchecked(bigint!(U256, "1a7344bac91f117ea513ec0ed5682406b6c15140174d61b28b762ae9cf6d3b46")))
    };

    /*
     * # Safety
     * 
     * this is the pre-computed value of R * R mod P, must less than P
     */
    const RR_P: FpElement = {
        primefield::FpElement(Element::new_unchecked(bigint!(U256, "1B0A32FDF6403A3D281E3A1B7F86954F55EFBF6E8C1CC3F1B3E886745370473D")))
    };
    const NEG_P_INV_B: u64 =0x8435e50d79435e5;
    // const NEG_P_INV_B: u32 = 0xD79435E5_u32;
}

impl BN254 {
    pub(crate) const B_DIV_XI_MONT: Fp2Element = fp2!(
        "212ba4f27ffffff5a2c62effffffffcdb939ffffffffff8a15ffffffffffff8e",
        "03f7bf8fc000000c176e1e800000003aa7e70000000000899100000000000085"
    );
    
    pub(crate) const XI_MONT: [Fp2Element; 5] = [
        fp2!(
            "1830373ee92acf9fd5910ffed2c92f70144f87f9c79b1f6b2728380075e94f74",
            "0cf32d4356d53061e4a33d812d36d0984cd178063864e0a87fd7c7ff8a16b09f"
        ),
        fp2!(
            "0000000000000000000000000000000000000000000000000000000000000000",
            "22a87debbfffffefc0651cd3594d64661c92209138d7ba61056efc68e869fd55"
        ),
        fp2!(
            "1aa6d99b1d115e0a5f0116472cae2274c45a8b4e56d9569cfd55c5dc71674777",
            "1aa6d99b1d115e0a5f0116472cae2274c45a8b4e56d9569cfd55c5dc71674777"
        ),
        fp2!(
            "1eb0be5bffffffe3a8f6fe53594d642b74ab209138d7b9d7746efc68e869fcd0",
            "0000000000000000000000000000000000000000000000000000000000000000"
        ),
        fp2!(
            "0db3ac57c63c2da87a5dd8c5ff7751dc778913481e7475f47d7dfddce75096d8",
            "176fb82a79c3d2593fd674ba0088ae2be997ecb7e18b8a1f2982022318af693b"
        )
    ];
    
    pub(crate) const P2_FROB_MAP_VAL: [FpElement; 5] = [
        fp!("027ae69680000011f9cf30aca6b29ba2448edf6ec72845b2a1910397179602be"),
        fp!("0672a6264000001e113d4f2ca6b29bdcec75df6ec728463c3291039717960343"),
        fp!("03f7bf8fc000000c176e1e800000003aa7e70000000000899100000000000085"),
        fp!("22a87debbfffffefc0651cd3594d64661c92209138d7ba61056efc68e869fd55"),
        fp!("1eb0be5bffffffe3a8f6fe53594d642b74ab209138d7b9d7746efc68e869fcd0")
    ];    
}