openvm_pairing_guest/pairing/operations/
fp6.rs
1use openvm_algebra_guest::{field::FieldExtension, Field, IntMod};
2
3use super::fp2_invert_assign;
4
5pub(crate) fn fp6_invert_assign<
6 Fp: IntMod + Field,
7 Fp2: Field + FieldExtension<Fp, Coeffs = [Fp; 2]>,
8>(
9 c: &mut [Fp2; 3],
10 xi: &Fp2,
11) {
12 let mut c0 = c[2].clone();
13 c0 *= xi;
14 c0 *= &c[1];
15 c0 = c0.neg();
16 {
17 let mut c0s = c[0].clone();
18 <Fp2 as Field>::square_assign(&mut c0s);
19 c0 += &c0s;
20 }
21 let mut c1 = c[2].clone();
22 <Fp2 as Field>::square_assign(&mut c1);
23 c1 *= xi;
24 {
25 let mut c01 = c[0].clone();
26 c01 *= &c[1];
27 c1 -= &c01;
28 }
29 let mut c2 = c[1].clone();
30 <Fp2 as Field>::square_assign(&mut c2);
31 {
32 let mut c02 = c[0].clone();
33 c02 *= &c[2];
34 c2 -= &c02;
35 }
36
37 let mut tmp1 = c[2].clone();
38 tmp1 *= &c1;
39 let mut tmp2 = c[1].clone();
40 tmp2 *= &c2;
41 tmp1 += &tmp2;
42 tmp1 *= xi;
43 tmp2 = c[0].clone();
44 tmp2 *= &c0;
45 tmp1 += &tmp2;
46
47 let mut coeffs = tmp1.clone().to_coeffs();
48 fp2_invert_assign::<Fp>(&mut coeffs);
49 let tmp = Fp2::from_coeffs(coeffs);
50 let mut tmp = [tmp.clone(), tmp.clone(), tmp.clone()];
51 tmp[0] *= &c0;
52 tmp[1] *= &c1;
53 tmp[2] *= &c2;
54
55 *c = tmp;
56}
57
58pub(crate) fn fp6_mul_by_nonresidue_assign<
59 Fp: IntMod + Field,
60 Fp2: Field + FieldExtension<Fp, Coeffs = [Fp; 2]>,
61>(
62 c: &mut [Fp2; 3],
63 xi: &Fp2,
64) {
65 c.swap(0, 1);
67 c.swap(0, 2);
68 c[0] *= xi;
69}
70
71pub(crate) fn fp6_sub_assign<
72 Fp: IntMod + Field,
73 Fp2: Field + FieldExtension<Fp, Coeffs = [Fp; 2]>,
74>(
75 a: &mut [Fp2; 3],
76 b: &[Fp2; 3],
77) {
78 a.iter_mut().zip(b).for_each(|(a, b)| *a -= b);
79}
80
81pub(crate) fn fp6_square_assign<
83 Fp: IntMod + Field,
84 Fp2: Field + FieldExtension<Fp, Coeffs = [Fp; 2]>,
85>(
86 c: &mut [Fp2; 3],
87 xi: &Fp2,
88) {
89 let mut s0 = c[0].clone();
91 <Fp2 as Field>::square_assign(&mut s0);
92 let mut ab = c[0].clone();
94 ab *= &c[1];
95 let mut s1 = ab;
96 <Fp2 as Field>::double_assign(&mut s1);
97 let mut s2 = c[0].clone();
99 s2 -= &c[1];
100 s2 += &c[2];
101 <Fp2 as Field>::square_assign(&mut s2);
102 let mut bc = c[1].clone();
104 bc *= &c[2];
105 let mut s3 = bc;
107 <Fp2 as Field>::double_assign(&mut s3);
108 let mut s4 = c[2].clone();
110 <Fp2 as Field>::square_assign(&mut s4);
111
112 c[0] = s3.clone();
114 c[0] *= xi;
115 c[0] += &s0;
116
117 c[1] = s4.clone();
119 c[1] *= xi;
120 c[1] += &s1;
121
122 c[2] = s1;
124 c[2] += &s2;
125 c[2] += &s3;
126 c[2] -= &s0;
127 c[2] -= &s4;
128}
129
130pub(crate) fn fp6_mul_assign<
131 Fp: IntMod + Field,
132 Fp2: Field + FieldExtension<Fp, Coeffs = [Fp; 2]>,
133>(
134 a: &mut [Fp2; 3],
135 b: &[Fp2; 3],
136 xi: &Fp2,
137) {
138 let mut a_a = a[0].clone();
139 let mut b_b = a[1].clone();
140 let mut c_c = a[2].clone();
141
142 a_a *= &b[0];
143 b_b *= &b[1];
144 c_c *= &b[2];
145
146 let mut t1 = b[1].clone();
147 t1 += &b[2];
148 {
149 let mut tmp = a[1].clone();
150 tmp += &a[2];
151
152 t1 *= &tmp;
153 t1 -= &b_b;
154 t1 -= &c_c;
155 t1 *= xi;
156 t1 += &a_a;
157 }
158
159 let mut t3 = b[0].clone();
160 t3 += &b[2];
161 {
162 let mut tmp = a[0].clone();
163 tmp += &a[2];
164
165 t3 *= &tmp;
166 t3 -= &a_a;
167 t3 += &b_b;
168 t3 -= &c_c;
169 }
170
171 let mut t2 = b[0].clone();
172 t2 += &b[1];
173 {
174 let mut tmp = a[0].clone();
175 tmp += &a[1];
176
177 t2 *= &tmp;
178 t2 -= &a_a;
179 t2 -= &b_b;
180 c_c *= xi;
181 t2 += &c_c;
182 }
183
184 a[0] = t1;
185 a[1] = t2;
186 a[2] = t3;
187}