airbender_crypto/bn254/curves/
g2.rs1#[cfg(not(any(
2 all(target_arch = "riscv32", feature = "bigint_ops"),
3 test,
4 feature = "proving"
5)))]
6use crate::ark_ff::MontFp;
7#[cfg(any(
8 all(target_arch = "riscv32", feature = "bigint_ops"),
9 test,
10 feature = "proving"
11))]
12use crate::ark_ff_delegation::MontFp;
13use ark_ec::AffineRepr;
14use ark_ec::{
15 models::{short_weierstrass::SWCurveConfig, CurveConfig},
16 scalar_mul::glv::GLVConfig,
17 short_weierstrass::{Affine, Projective},
18};
19use ark_ff::{AdditiveGroup, BigInt, Field, PrimeField, Zero};
20
21use crate::bn254::fields::{Fq, Fq2, Fr};
22pub type G2Affine = Affine<Config>;
23
24#[derive(Clone, Default, PartialEq, Eq)]
25pub struct Config;
26
27impl CurveConfig for Config {
28 type BaseField = Fq2;
29 type ScalarField = Fr;
30
31 #[rustfmt::skip]
34 const COFACTOR: &'static [u64] = &[
35 0x345f2299c0f9fa8d,
36 0x06ceecda572a2489,
37 0xb85045b68181585e,
38 0x30644e72e131a029,
39 ];
40
41 const COFACTOR_INV: Fr = ark_ff::MontFp!(
43 "10944121435919637613327163357776759465618812564592884533313067514031822496649"
44 );
45}
46
47impl SWCurveConfig for Config {
48 const COEFF_A: Fq2 = Fq2::ZERO;
50
51 const COEFF_B: Fq2 = Fq2::new(
54 MontFp!("19485874751759354771024239261021720505790618469301721065564631296452457478373"),
55 MontFp!("266929791119991161246907387137283842545076965332900288569378510910307636690"),
56 );
57
58 const GENERATOR: G2Affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
60
61 #[inline(always)]
62 fn mul_by_a(_: Self::BaseField) -> Self::BaseField {
63 Self::BaseField::zero()
64 }
65
66 fn is_in_correct_subgroup_assuming_on_curve(point: &G2Affine) -> bool {
67 let x_times_point = point.mul_bigint(SIX_X_SQUARED);
72 let p_times_point = p_power_endomorphism(point);
73 x_times_point.eq(&p_times_point)
74 }
75}
76
77impl GLVConfig for Config {
78 const ENDO_COEFFS: &'static [Self::BaseField] = &[Fq2::new(
79 MontFp!("21888242871839275220042445260109153167277707414472061641714758635765020556616"),
80 Fq::ZERO,
81 )];
82
83 const LAMBDA: Self::ScalarField =
84 ark_ff::MontFp!("4407920970296243842393367215006156084916469457145843978461");
85
86 const SCALAR_DECOMP_COEFFS: [(bool, <Self::ScalarField as PrimeField>::BigInt); 4] = [
87 (false, BigInt!("147946756881789319010696353538189108491")),
88 (false, BigInt!("9931322734385697763")),
89 (true, BigInt!("9931322734385697763")),
90 (false, BigInt!("147946756881789319000765030803803410728")),
91 ];
92
93 fn endomorphism(p: &Projective<Self>) -> Projective<Self> {
94 let mut res = (*p).clone();
95 res.x *= Self::ENDO_COEFFS[0];
96 res
97 }
98
99 fn endomorphism_affine(p: &Affine<Self>) -> Affine<Self> {
100 let mut res = (*p).clone();
101 res.x *= Self::ENDO_COEFFS[0];
102 res
103 }
104}
105
106pub const G2_GENERATOR_X: Fq2 = Fq2::new(G2_GENERATOR_X_C0, G2_GENERATOR_X_C1);
107pub const G2_GENERATOR_Y: Fq2 = Fq2::new(G2_GENERATOR_Y_C0, G2_GENERATOR_Y_C1);
108
109pub const G2_GENERATOR_X_C0: Fq =
112 MontFp!("10857046999023057135944570762232829481370756359578518086990519993285655852781");
113
114pub const G2_GENERATOR_X_C1: Fq =
117 MontFp!("11559732032986387107991004021392285783925812861821192530917403151452391805634");
118
119pub const G2_GENERATOR_Y_C0: Fq =
122 MontFp!("8495653923123431417604973247489272438418190587263600148770280649306958101930");
123
124pub const G2_GENERATOR_Y_C1: Fq =
127 MontFp!("4082367875863433681332203403145435568316851327593401208105741076214120093531");
128
129const P_POWER_ENDOMORPHISM_COEFF_0: Fq2 = Fq2::new(
131 MontFp!("21575463638280843010398324269430826099269044274347216827212613867836435027261"),
132 MontFp!("10307601595873709700152284273816112264069230130616436755625194854815875713954"),
133);
134
135const P_POWER_ENDOMORPHISM_COEFF_1: Fq2 = Fq2::new(
137 MontFp!("2821565182194536844548159561693502659359617185244120367078079554186484126554"),
138 MontFp!("3505843767911556378687030309984248845540243509899259641013678093033130930403"),
139);
140
141const SIX_X_SQUARED: [u64; 2] = [17887900258952609094, 8020209761171036667];
143
144fn p_power_endomorphism(p: &Affine<Config>) -> Affine<Config> {
146 let mut res = *p;
149 res.x.frobenius_map_in_place(1);
150 res.y.frobenius_map_in_place(1);
151
152 res.x *= P_POWER_ENDOMORPHISM_COEFF_0;
153 res.y *= P_POWER_ENDOMORPHISM_COEFF_1;
154
155 res
156}