sp1_curves/weierstrass/
bn254.rs

1use generic_array::GenericArray;
2use num::{BigUint, Num, Zero};
3use serde::{Deserialize, Serialize};
4use typenum::{U32, U62};
5
6use super::{FieldType, FpOpField, SwCurve, WeierstrassParameters};
7use crate::{
8    params::{FieldParameters, NumLimbs},
9    CurveType, EllipticCurveParameters,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
13/// Bn254 curve parameter
14pub struct Bn254Parameters;
15
16pub type Bn254 = SwCurve<Bn254Parameters>;
17
18#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
19/// Bn254 base field parameter
20pub struct Bn254BaseField;
21
22impl FieldParameters for Bn254BaseField {
23    const MODULUS: &'static [u8] = &[
24        71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129,
25        129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48,
26    ];
27
28    // A rough witness-offset estimate given the size of the limbs and the size of the field.
29    const WITNESS_OFFSET: usize = 1usize << 14;
30
31    // The modulus has been taken from py_ecc python library by Ethereum Foundation.
32    // https://github.com/ethereum/py_pairing/blob/5f609da/py_ecc/bn128/bn128_field_elements.py#L10-L11
33    fn modulus() -> BigUint {
34        BigUint::from_str_radix(
35            "21888242871839275222246405745257275088696311157297823662689037894645226208583",
36            10,
37        )
38        .unwrap()
39    }
40}
41
42impl FpOpField for Bn254BaseField {
43    const FIELD_TYPE: FieldType = FieldType::Bn254;
44}
45
46impl NumLimbs for Bn254BaseField {
47    type Limbs = U32;
48    type Witness = U62;
49}
50
51impl EllipticCurveParameters for Bn254Parameters {
52    type BaseField = Bn254BaseField;
53
54    const CURVE_TYPE: CurveType = CurveType::Bn254;
55}
56
57impl WeierstrassParameters for Bn254Parameters {
58    // The values have been taken from py_ecc python library by Ethereum Foundation.
59    // https://github.com/ethereum/py_pairing/blob/5f609da/py_ecc/bn128/bn128_field_elements.py
60    const A: GenericArray<u8, U32> = GenericArray::from_array([
61        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, 0,
62        0, 0,
63    ]);
64
65    const B: GenericArray<u8, U32> = GenericArray::from_array([
66        3, 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,
67        0, 0,
68    ]);
69    fn generator() -> (BigUint, BigUint) {
70        let x = BigUint::from(1u32);
71        let y = BigUint::from(2u32);
72        (x, y)
73    }
74
75    fn prime_group_order() -> num::BigUint {
76        BigUint::from_str_radix(
77            "21888242871839275222246405745257275088548364400416034343698204186575808495617",
78            10,
79        )
80        .unwrap()
81    }
82
83    fn a_int() -> BigUint {
84        BigUint::zero()
85    }
86
87    fn b_int() -> BigUint {
88        BigUint::from(3u32)
89    }
90}
91
92#[cfg(test)]
93mod tests {
94
95    use super::*;
96    use crate::utils::biguint_from_limbs;
97
98    #[test]
99    fn test_weierstrass_biguint_scalar_mul() {
100        assert_eq!(biguint_from_limbs(Bn254BaseField::MODULUS), Bn254BaseField::modulus());
101    }
102}