arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
ark-curves-cherry-picked/bw6_761/src/curves/mod.rs
bw6_761/src/curves/mod.rsRaw
  1use ark_ec::{
  2    bw6,
  3    bw6::{BW6Config, TwistType, BW6},
  4};
  5use ark_ff::{
  6    biginteger::BigInteger768 as BigInteger, fp6_2over3::Fp6, BigInt, CyclotomicMultSubgroup, Field,
  7};
  8
  9use crate::*;
 10
 11pub mod g1;
 12pub mod g2;
 13
 14#[cfg(test)]
 15mod tests;
 16
 17#[derive(PartialEq, Eq)]
 18pub struct Config;
 19
 20impl BW6Config for Config {
 21    const X: BigInteger = BigInt::new([
 22        0x8508c00000000001,
 23        0x0,
 24        0x0,
 25        0x0,
 26        0x0,
 27        0x0,
 28        0x0,
 29        0x0,
 30        0x0,
 31        0x0,
 32        0x0,
 33        0x0,
 34    ]);
 35    /// `x` is positive.
 36    const X_IS_NEGATIVE: bool = false;
 37    // (X-1)/3
 38    const X_MINUS_1_DIV_3: BigInteger = BigInt::new([
 39        0x2c58400000000000,
 40        0x0,
 41        0x0,
 42        0x0,
 43        0x0,
 44        0x0,
 45        0x0,
 46        0x0,
 47        0x0,
 48        0x0,
 49        0x0,
 50        0x0,
 51    ]);
 52    // X+1
 53    const ATE_LOOP_COUNT_1: &'static [u64] = &[0x8508c00000000002];
 54    const ATE_LOOP_COUNT_1_IS_NEGATIVE: bool = false;
 55    // X^3-X^2-X
 56    const ATE_LOOP_COUNT_2: &'static [i8] = &[
 57        -1, 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,
 58        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,
 59        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,
 60        0, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
 61        0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, 0,
 62        1, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 1, 0, 1, 0, 0, 0, 1,
 63        0, -1, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
 64    ];
 65    const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool = false;
 66    const TWIST_TYPE: TwistType = TwistType::M;
 67    const H_T: i64 = 13;
 68    const H_Y: i64 = 9;
 69    const T_MOD_R_IS_ZERO: bool = false;
 70    type Fp = Fq;
 71    type Fp3Config = Fq3Config;
 72    type Fp6Config = Fq6Config;
 73    type G1Config = g1::Config;
 74    type G2Config = g2::Config;
 75
 76    fn final_exponentiation_hard_part(f: &Fp6<Self::Fp6Config>) -> Fp6<Self::Fp6Config> {
 77        // hard_part
 78        // From https://eprint.iacr.org/2020/351.pdf, Alg.6
 79
 80        #[rustfmt::skip]
 81        // R0(x) := (-103*x^7 + 70*x^6 + 269*x^5 - 197*x^4 - 314*x^3 - 73*x^2 - 263*x - 220)
 82        // R1(x) := (103*x^9 - 276*x^8 + 77*x^7 + 492*x^6 - 445*x^5 - 65*x^4 + 452*x^3 - 181*x^2 + 34*x + 229)
 83        // f ^ R0(u) * (f ^ q) ^ R1(u) in a 2-NAF multi-exp fashion.
 84
 85        // steps 1,2,3
 86        let f0 = *f;
 87        let mut f0p = f0;
 88        f0p.frobenius_map_in_place(1);
 89        let f1 = Self::exp_by_x(&f0);
 90        let mut f1p = f1;
 91        f1p.frobenius_map_in_place(1);
 92        let f2 = Self::exp_by_x(&f1);
 93        let mut f2p = f2;
 94        f2p.frobenius_map_in_place(1);
 95        let f3 = Self::exp_by_x(&f2);
 96        let mut f3p = f3;
 97        f3p.frobenius_map_in_place(1);
 98        let f4 = Self::exp_by_x(&f3);
 99        let mut f4p = f4;
100        f4p.frobenius_map_in_place(1);
101        let f5 = Self::exp_by_x(&f4);
102        let mut f5p = f5;
103        f5p.frobenius_map_in_place(1);
104        let f6 = Self::exp_by_x(&f5);
105        let mut f6p = f6;
106        f6p.frobenius_map_in_place(1);
107        let f7 = Self::exp_by_x(&f6);
108        let mut f7p = f7;
109        f7p.frobenius_map_in_place(1);
110
111        // step 4
112        let f8p = Self::exp_by_x(&f7p);
113        let f9p = Self::exp_by_x(&f8p);
114
115        // step 5
116        let mut f5p_p3 = f5p;
117        f5p_p3.cyclotomic_inverse_in_place();
118        let result1 = f3p * &f6p * &f5p_p3;
119
120        // step 6
121        let result2 = result1.square();
122        let f4_2p = f4 * &f2p;
123        let mut tmp1_p3 = f0 * &f1 * &f3 * &f4_2p * &f8p;
124        tmp1_p3.cyclotomic_inverse_in_place();
125        let result3 = result2 * &f5 * &f0p * &tmp1_p3;
126
127        // step 7
128        let result4 = result3.square();
129        let mut f7_p3 = f7;
130        f7_p3.cyclotomic_inverse_in_place();
131        let result5 = result4 * &f9p * &f7_p3;
132
133        // step 8
134        let result6 = result5.square();
135        let f2_4p = f2 * &f4p;
136        let f4_2p_5p = f4_2p * &f5p;
137        let mut tmp2_p3 = f2_4p * &f3 * &f3p;
138        tmp2_p3.cyclotomic_inverse_in_place();
139        let result7 = result6 * &f4_2p_5p * &f6 * &f7p * &tmp2_p3;
140
141        // step 9
142        let result8 = result7.square();
143        let mut tmp3_p3 = f0p * &f9p;
144        tmp3_p3.cyclotomic_inverse_in_place();
145        let result9 = result8 * &f0 * &f7 * &f1p * &tmp3_p3;
146
147        // step 10
148        let result10 = result9.square();
149        let f6p_8p = f6p * &f8p;
150        let f5_7p = f5 * &f7p;
151        let mut tmp4_p3 = f6p_8p;
152        tmp4_p3.cyclotomic_inverse_in_place();
153        let result11 = result10 * &f5_7p * &f2p * &tmp4_p3;
154
155        // step 11
156        let result12 = result11.square();
157        let f3_6 = f3 * &f6;
158        let f1_7 = f1 * &f7;
159        let mut tmp5_p3 = f1_7 * &f2;
160        tmp5_p3.cyclotomic_inverse_in_place();
161        let result13 = result12 * &f3_6 * &f9p * &tmp5_p3;
162
163        // step 12
164        let result14 = result13.square();
165        let mut tmp6_p3 = f4_2p * &f5_7p * &f6p_8p;
166        tmp6_p3.cyclotomic_inverse_in_place();
167        let result15 = result14 * &f0 * &f0p * &f3p * &f5p * &tmp6_p3;
168
169        // step 13
170        let result16 = result15.square();
171        let mut tmp7_p3 = f3_6;
172        tmp7_p3.cyclotomic_inverse_in_place();
173        let result17 = result16 * &f1p * &tmp7_p3;
174
175        // step 14
176        let result18 = result17.square();
177        let mut tmp8_p3 = f2_4p * &f4_2p_5p * &f9p;
178        tmp8_p3.cyclotomic_inverse_in_place();
179        let result19 = result18 * &f1_7 * &f5_7p * &f0p * &tmp8_p3;
180
181        result19
182    }
183}
184
185pub type BW6_761 = BW6<Config>;
186
187pub type G1Affine = bw6::G1Affine<Config>;
188pub type G1Projective = bw6::G1Projective<Config>;
189pub type G2Affine = bw6::G2Affine<Config>;
190pub type G2Projective = bw6::G2Projective<Config>;