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