Skip to content

Commit abaf225

Browse files
committed
mul_by_xi optimizations
1 parent c5a4e46 commit abaf225

File tree

7 files changed

+79
-50
lines changed

7 files changed

+79
-50
lines changed

Diff for: src/bench.cairo

+15-15
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,29 @@
1717
// test bn::bench::fq02::sqru ... ok (gas usage est.: 56750)
1818
// test bn::bench::fq02::sub ... ok (gas usage est.: 10500)
1919
// test bn::bench::fq06::add ... ok (gas usage est.: 59460)
20-
// test bn::bench::fq06::inv ... ok (gas usage est.: 2087070)
21-
// test bn::bench::fq06::mul ... ok (gas usage est.: 1251820)
22-
// test bn::bench::fq06::mulu ... ok (gas usage est.: 1107880)
23-
// test bn::bench::fq06::sqr ... ok (gas usage est.: 966130)
24-
// test bn::bench::fq06::sqru ... ok (gas usage est.: 822190)
20+
// test bn::bench::fq06::inv ... ok (gas usage est.: 2081670)
21+
// test bn::bench::fq06::mul ... ok (gas usage est.: 1249220)
22+
// test bn::bench::fq06::mulu ... ok (gas usage est.: 1105280)
23+
// test bn::bench::fq06::sqr ... ok (gas usage est.: 963530)
24+
// test bn::bench::fq06::sqru ... ok (gas usage est.: 819590)
2525
// test bn::bench::fq06::sub ... ok (gas usage est.: 31500)
2626
// test bn::bench::fq12::add ... ok (gas usage est.: 128220)
27-
// test bn::bench::fq12::inv ... ok (gas usage est.: 6602290)
28-
// test bn::bench::fq12::kdcmp ... ok (gas usage est.: 1232580)
29-
// test bn::bench::fq12::ksqr ... ok (gas usage est.: 1281820)
30-
// test bn::bench::fq12::mul ... ok (gas usage est.: 4097360)
31-
// test bn::bench::fq12::sqr ... ok (gas usage est.: 3073140)
32-
// test bn::bench::fq12::sqrc ... ok (gas usage est.: 2254450)
27+
// test bn::bench::fq12::inv ... ok (gas usage est.: 6584690)
28+
// test bn::bench::fq12::kdcmp ... ok (gas usage est.: 1230780)
29+
// test bn::bench::fq12::ksqr ... ok (gas usage est.: 1276420)
30+
// test bn::bench::fq12::mul ... ok (gas usage est.: 4087960)
31+
// test bn::bench::fq12::sqr ... ok (gas usage est.: 3066340)
32+
// test bn::bench::fq12::sqrc ... ok (gas usage est.: 2247250)
3333
// test bn::bench::fq12::sub ... ok (gas usage est.: 74900)
34-
// test bn::bench::fq12::xp_t ... ok (gas usage est.: 163609970)
35-
// test bn::bench::fq12::z_esy ... ok (gas usage est.: 15899220)
36-
// test bn::bench::fq12::z_hrd ... ok (gas usage est.: 541911430)
34+
// test bn::bench::fq12::xp_t ... ok (gas usage est.: 163091970)
35+
// test bn::bench::fq12::z_esy ... ok (gas usage est.: 15862820)
36+
// test bn::bench::fq12::z_hrd ... ok (gas usage est.: 540241830)
3737
// test bn::bench::u512::add ... ok (gas usage est.: 7490)
3838
// test bn::bench::u512::add_bn ... ok (gas usage est.: 15390)
3939
// test bn::bench::u512::fq_add ... ok (gas usage est.: 5480)
4040
// test bn::bench::u512::fq_n2 ... ok (gas usage est.: 400)
4141
// test bn::bench::u512::fq_sub ... ok (gas usage est.: 5480)
42-
// test bn::bench::u512::mxi ... ok (gas usage est.: 96100)
42+
// test bn::bench::u512::mxi ... ok (gas usage est.: 95100)
4343
// test bn::bench::u512::sub ... ok (gas usage est.: 7490)
4444
// test bn::bench::u512::sub_bn ... ok (gas usage est.: 15390)
4545

Diff for: src/curve.cairo

+20-4
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ fn u512_reduce_bn(a: u512) -> u256 {
135135
}
136136

137137
#[inline(always)]
138-
fn u512_scl_9(a: u512) -> u512 {
138+
fn u512_scl_9(a: u512, field_nz: NonZero<u256>) -> u512 {
139139
let u512 { limb0, limb1, limb2: low, limb3: high, } = a;
140-
let u256 { low: limb2, high: limb3 } = reduce(u256 { high, low }, FIELD.try_into().unwrap());
140+
let u256 { low: limb2, high: limb3 } = reduce(u256 { high, low }, field_nz);
141141
let (result, overflow) = u512_scl(u512 { limb0, limb1, limb2, limb3, }, 9);
142142

143143
if (overflow == 0) {
@@ -149,9 +149,16 @@ fn u512_scl_9(a: u512) -> u512 {
149149

150150
// ξ = 9 + i
151151
fn mul_by_xi(t: (u512, u512)) -> (u512, u512) {
152+
let field_nz = FIELD.try_into().unwrap();
152153
let (t0, t1): (u512, u512) = t;
153-
(u512_scl_9(t0) - t1, //
154-
t0 + u512_scl_9(t1))
154+
(u512_scl_9(t0, field_nz) - t1, //
155+
t0 + u512_scl_9(t1, field_nz))
156+
}
157+
158+
fn mul_by_xi_nz(t: (u512, u512), field_nz: NonZero<u256>) -> (u512, u512) {
159+
let (t0, t1): (u512, u512) = t;
160+
(u512_scl_9(t0, field_nz) - t1, //
161+
t0 + u512_scl_9(t1, field_nz))
155162
}
156163

157164
#[inline(always)]
@@ -163,6 +170,15 @@ fn mul_by_v(
163170
(mul_by_xi(t2), t0, t1,)
164171
}
165172

173+
#[inline(always)]
174+
fn mul_by_v_nz(
175+
t: ((u512, u512), (u512, u512), (u512, u512)), field_nz: NonZero<u256>
176+
) -> ((u512, u512), (u512, u512), (u512, u512)) {
177+
// https://github.com/paritytech/bn/blob/master/src/fields/fq6.rs#L110
178+
let (t0, t1, t2) = t;
179+
(mul_by_xi_nz(t2, field_nz), t0, t1)
180+
}
181+
166182
#[inline(always)]
167183
fn mul(a: u256, b: u256) -> u256 {
168184
m::mul_nz(a, b, field_nz())

Diff for: src/fields/fq_12.cairo

+10-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use bn::fields::{Fq6, fq6, Fq6Utils, fq2, Fq6Frobenius, Fq6MulShort, Fq6Short};
77
use bn::fields::frobenius::fp12 as frob;
88
use bn::curve::{FIELD};
99
use bn::curve::{
10-
u512, U512BnAdd, Tuple2Add, Tuple3Add, U512BnSub, Tuple2Sub, Tuple3Sub, u512_reduce, mul_by_v
10+
u512, U512BnAdd, Tuple2Add, Tuple3Add, U512BnSub, Tuple2Sub, Tuple3Sub, u512_reduce, mul_by_v_nz
1111
};
1212
use debug::PrintTrait;
1313

@@ -174,16 +174,16 @@ impl Fq12Ops of FieldOps<Fq12> {
174174
fn mul(self: Fq12, rhs: Fq12) -> Fq12 {
175175
core::internal::revoke_ap_tracking();
176176
// Input: a = (a0 + a1i) and b = (b0 + b1i) ∈ Fp2 Output: c = a·b = (c0 +c1i) ∈ Fp2
177+
let field_nz = FIELD.try_into().unwrap();
178+
177179
let Fq12 { c0: a0, c1: a1 } = self;
178180
let Fq12 { c0: b0, c1: b1 } = rhs;
179181

180182
let U = a0.u_mul(b0);
181183
let V = a1.u_mul(b1);
182184

183-
let C0 = mul_by_v(V) + U;
185+
let C0 = mul_by_v_nz(V, field_nz) + U;
184186
let C1 = (a0 + a1).u_mul(b0 + b1) - U - V;
185-
186-
let field_nz = FIELD.try_into().unwrap();
187187
Fq12 { //
188188
c0: C0.to_fq(field_nz), //
189189
c1: C1.to_fq(field_nz), //
@@ -192,21 +192,24 @@ impl Fq12Ops of FieldOps<Fq12> {
192192

193193
fn sqr(self: Fq12) -> Fq12 {
194194
core::internal::revoke_ap_tracking();
195+
let field_nz = FIELD.try_into().unwrap();
196+
195197
let Fq12 { c0: a0, c1: a1 } = self;
196198

197199
// Complex squaring
198200
let V = a0.u_mul(a1);
199201
// (a0 + a1) * (a0 + βa1) - v - βv
200-
let C0 = (a0 + a1).u_mul(a0 + a1.mul_by_nonresidue()) - V - mul_by_v(V);
202+
let C0 = (a0 + a1).u_mul(a0 + a1.mul_by_nonresidue()) - V - mul_by_v_nz(V, field_nz);
201203
// 2v
202204
let C1 = V + V;
203-
let field_nz = FIELD.try_into().unwrap();
204205
Fq12 { c0: C0.to_fq(field_nz), c1: C1.to_fq(field_nz) }
205206
}
206207

207208
fn inv(self: Fq12, field_nz: NonZero<u256>) -> Fq12 {
208209
core::internal::revoke_ap_tracking();
209-
let t = (self.c0.u_sqr() - mul_by_v(self.c1.u_sqr())).to_fq(field_nz).inv(field_nz);
210+
let t = (self.c0.u_sqr() - mul_by_v_nz(self.c1.u_sqr(), field_nz))
211+
.to_fq(field_nz)
212+
.inv(field_nz);
210213

211214
Fq12 { c0: self.c0 * t, c1: -(self.c1 * t), }
212215
}

Diff for: src/fields/fq_12_expo.cairo

+18-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bn::traits::FieldShortcuts;
55
use bn::traits::FieldMulShortcuts;
66
use core::array::ArrayTrait;
77
use bn::curve::{t_naf, FIELD, FIELD_X2};
8-
use bn::curve::{u512, mul_by_xi, mul_by_v, U512BnAdd, U512BnSub, Tuple2Add, Tuple2Sub,};
8+
use bn::curve::{u512, mul_by_xi_nz, mul_by_v, U512BnAdd, U512BnSub, Tuple2Add, Tuple2Sub,};
99
use bn::curve::{u512_add, u512_sub, u512_high_add, u512_high_sub, U512Fq2Ops};
1010
use bn::fields::{FieldUtils, FieldOps, fq, Fq, Fq2, Fq6, Fq12, fq12, Fq12Frobenius};
1111
use bn::fields::{TFqAdd, TFqSub, TFqMul, TFqDiv, TFqNeg, TFqPartialEq,};
@@ -149,7 +149,7 @@ impl Fq12FinalExpo of FinalExponentiationTrait {
149149
Fq12 { c0: Fq6 { c0: g0, c1: g4, c2: g3 }, c1: Fq6 { c0: g2, c1: g1, c2: g5 } }
150150
} else {
151151
// g1 = (S5ξ + 3S4 - 2g3)/4g2
152-
let S5xi = mul_by_xi(g5.u_sqr());
152+
let S5xi = mul_by_xi_nz(g5.u_sqr(), field_nz);
153153
let S4 = g4.u_sqr();
154154
let Tmp = S4.u512_sub_fq(g3); // S4 - g3
155155
let g1: Fq2 = (S5xi + S4.u_add(Tmp.u_add(Tmp))).to_fq(field_nz); // (S5ξ + 3S4 - 2g3)
@@ -183,18 +183,18 @@ impl Fq12FinalExpo of FinalExponentiationTrait {
183183
let S2_3: (u512, u512) = (g2 + g3).u_sqr();
184184

185185
// h1 = 3 * g3² + 3 * nr * g2² - 2*g1
186-
let Tmp = S3 + mul_by_xi(S2); // g3² + nr * g2²
186+
let Tmp = S3 + mul_by_xi_nz(S2, field_nz); // g3² + nr * g2²
187187
let h1 = X2(Tmp.u512_sub_fq(g1)) + Tmp;
188188
let h1 = h1.to_fq(field_nz);
189189

190190
// h2 = 3 * nr * g5² + 3 * g1² - 2*g2
191-
let Tmp = mul_by_xi(S5) + S1; // nr * g5² + g1²
191+
let Tmp = mul_by_xi_nz(S5, field_nz) + S1; // nr * g5² + g1²
192192
let h2 = X2(Tmp.u512_sub_fq(g2)) + Tmp;
193193
let h2 = h2.to_fq(field_nz);
194194

195195
// 2 * g1 * g5 = (S1_5 - S1 - S5)
196196
// h3 = 6 * nr * g1 * g5 + 2*g3
197-
let Tmp = mul_by_xi(S1_5 - S1 - S5); // 2 * g1 * g5
197+
let Tmp = mul_by_xi_nz(S1_5 - S1 - S5, field_nz); // 2 * g1 * g5
198198
let h3 = X2(Tmp.u512_add_fq(g3)) + Tmp;
199199
let h3 = h3.to_fq(field_nz);
200200

@@ -226,17 +226,17 @@ impl Fq12FinalExpo of FinalExponentiationTrait {
226226
let S2_3: (u512, u512) = (g2 + g3).u_sqr();
227227

228228
// h2 = 3(S4_5 − S4 − S5)ξ + 2g2;
229-
let Tmp = mul_by_xi(S4_5 - S4.u_add(S5));
229+
let Tmp = mul_by_xi_nz(S4_5 - S4.u_add(S5), field_nz);
230230
let h2 = X2(Tmp.u512_add_fq(g2)) + Tmp;
231231
let h2 = h2.to_fq(field_nz);
232232

233233
// h3 = 3(S4 + S5ξ) - 2g3;
234-
let Tmp = S4 + mul_by_xi(S5);
234+
let Tmp = S4 + mul_by_xi_nz(S5, field_nz);
235235
let h3 = X2(Tmp.u512_sub_fq(g3)) + Tmp;
236236
let h3 = h3.to_fq(field_nz);
237237

238238
// h4 = 3(S2 + S3ξ) - 2g4;
239-
let Tmp = S2 + mul_by_xi(S3);
239+
let Tmp = S2 + mul_by_xi_nz(S3, field_nz);
240240
let h4 = X2(Tmp.u512_sub_fq(g4)) + Tmp;
241241
let h4 = h4.to_fq(field_nz);
242242

@@ -311,21 +311,27 @@ impl Fq12FinalExpo of FinalExponentiationTrait {
311311
// let tmp = z0 * z1;
312312
let Tmp = z0.u_mul(z1);
313313
// let t0 = (z0 + z1) * (z1.mul_by_nonresidue() + z0) - tmp - tmp.mul_by_nonresidue();
314-
let T0 = z0.u_add(z1).u_mul(z1.mul_by_nonresidue().u_add(z0)) - Tmp - mul_by_xi(Tmp);
314+
let T0 = z0.u_add(z1).u_mul(z1.mul_by_nonresidue().u_add(z0))
315+
- Tmp
316+
- mul_by_xi_nz(Tmp, field_nz);
315317
// let t1 = tmp + tmp;
316318
let T1 = Tmp + Tmp;
317319

318320
// let tmp = z2 * z3;
319321
let Tmp = z2.u_mul(z3);
320322
// let t2 = (z2 + z3) * (z3.mul_by_nonresidue() + z2) - tmp - tmp.mul_by_nonresidue();
321-
let T2 = z2.u_add(z3).u_mul(z3.mul_by_nonresidue().u_add(z2)) - Tmp - mul_by_xi(Tmp);
323+
let T2 = z2.u_add(z3).u_mul(z3.mul_by_nonresidue().u_add(z2))
324+
- Tmp
325+
- mul_by_xi_nz(Tmp, field_nz);
322326
// let t3 = tmp + tmp;
323327
let T3 = Tmp + Tmp;
324328

325329
// let tmp = z4 * z5;
326330
let Tmp = z4.u_mul(z5);
327331
// let t4 = (z4 + z5) * (z5.mul_by_nonresidue() + z4) - tmp - tmp.mul_by_nonresidue();
328-
let T4 = z4.u_add(z5).u_mul(z5.mul_by_nonresidue().u_add(z4)) - Tmp - mul_by_xi(Tmp);
332+
let T4 = z4.u_add(z5).u_mul(z5.mul_by_nonresidue().u_add(z4))
333+
- Tmp
334+
- mul_by_xi_nz(Tmp, field_nz);
329335
// let t5 = tmp + tmp;
330336
let T5 = Tmp + Tmp;
331337

@@ -337,7 +343,7 @@ impl Fq12FinalExpo of FinalExponentiationTrait {
337343
let Z1 = Z1 + Z1;
338344
let Z1 = Z1 + T1;
339345

340-
let Tmp = mul_by_xi(T5);
346+
let Tmp = mul_by_xi_nz(T5, field_nz);
341347
let Z2 = Tmp.u512_add_fq(z2);
342348
let Z2 = Z2 + Z2;
343349
let Z2 = Z2 + Tmp;

Diff for: src/fields/fq_2.cairo

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ impl Fq2Short of FieldShortcuts<Fq2> {
110110
}
111111
}
112112

113+
#[inline(always)]
113114
fn fix_mod(self: Fq2) -> Fq2 {
114115
// Operation without modding can only be done like 4 times
115116
Fq2 { //

Diff for: src/fields/fq_6.cairo

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use bn::curve::{FIELD};
22
use bn::curve::{
3-
U512Fq2Ops, u512, U512BnAdd, Tuple2Add, U512BnSub, Tuple2Sub, mul_by_xi, u512_reduce, u512_add,
4-
u512_sub
3+
U512Fq2Ops, u512, U512BnAdd, Tuple2Add, U512BnSub, Tuple2Sub, mul_by_xi, mul_by_xi_nz,
4+
u512_reduce, u512_add, u512_sub
55
};
66
use bn::fields::print::{FqPrintImpl, Fq2PrintImpl, Fq6PrintImpl, Fq12PrintImpl};
77
use bn::fields::{Fq2, Fq2Ops, fq2, Fq2Frobenius};
@@ -194,13 +194,15 @@ impl Fq6MulShort of FieldMulShortcuts<Fq6, SixU512> {
194194
// Output:c = a · b = (c0 + c1v + c2v2) ∈ Fp6
195195
let Fq6 { c0: a0, c1: a1, c2: a2 } = self;
196196
let Fq6 { c0: b0, c1: b1, c2: b2 } = rhs;
197+
let field_nz = FIELD.try_into().unwrap();
198+
197199
// v0 = a0b0, v1 = a1b1, v2 = a2b2
198200
let (V0, V1, V2,) = (a0.u_mul(b0), a1.u_mul(b1), a2.u_mul(b2),);
199201

200202
// c0 = v0 + ξ((a1 + a2)(b1 + b2) - v1 - v2)
201-
let C0 = V0 + mul_by_xi(a1.u_add(a2).u_mul(b1.u_add(b2)) - V1 - V2);
203+
let C0 = V0 + mul_by_xi_nz(a1.u_add(a2).u_mul(b1.u_add(b2)) - V1 - V2, field_nz);
202204
// c1 =(a0 + a1)(b0 + b1) - v0 - v1 + ξv2
203-
let C1 = a0.u_add(a1).u_mul(b0.u_add(b1)) - V0 - V1 + mul_by_xi(V2);
205+
let C1 = a0.u_add(a1).u_mul(b0.u_add(b1)) - V0 - V1 + mul_by_xi_nz(V2, field_nz);
204206
// c2 = (a0 + a2)(b0 + b2) - v0 + v1 - v2,
205207
let C2 = a0.u_add(a2).u_mul(b0.u_add(b2)) - V0 + V1 - V2;
206208

@@ -214,6 +216,7 @@ impl Fq6MulShort of FieldMulShortcuts<Fq6, SixU512> {
214216
fn u_sqr(self: Fq6) -> SixU512 {
215217
core::internal::revoke_ap_tracking();
216218
let Fq6 { c0, c1, c2 } = self;
219+
let field_nz = FIELD.try_into().unwrap();
217220

218221
// let s0 = c0.sqr();
219222
let S0 = c0.u_sqr();
@@ -231,9 +234,9 @@ impl Fq6MulShort of FieldMulShortcuts<Fq6, SixU512> {
231234
let S4 = c2.u_sqr();
232235

233236
// let c0 = s0 + s3.mul_by_nonresidue();
234-
let C0 = S0 + mul_by_xi(S3);
237+
let C0 = S0 + mul_by_xi_nz(S3, field_nz);
235238
// let c1 = s1 + s4.mul_by_nonresidue();
236-
let C1 = S1 + mul_by_xi(S4);
239+
let C1 = S1 + mul_by_xi_nz(S4, field_nz);
237240
// let c2 = s1 + s2 + s3 - s0 - s4;
238241
let C2 = S1 + S2 + S3 - S0 - S4;
239242
(C0, C1, C2)
@@ -292,16 +295,16 @@ impl Fq6Ops of FieldOps<Fq6> {
292295
let field_nz = FIELD.try_into().unwrap();
293296
let Fq6 { c0, c1, c2 } = self;
294297
// let c0 = self.c0.sqr() - self.c1 * self.c2.mul_by_nonresidue();
295-
let v0 = c0.u_sqr() - mul_by_xi(c1.u_mul(c2));
298+
let v0 = c0.u_sqr() - mul_by_xi_nz(c1.u_mul(c2), field_nz);
296299
let v0 = v0.to_fq(field_nz);
297300
// let c1 = self.c2.sqr().mul_by_nonresidue() - self.c0 * self.c1;
298-
let V1 = mul_by_xi(c2.u_sqr()) - c0.u_mul(c1);
301+
let V1 = mul_by_xi_nz(c2.u_sqr(), field_nz) - c0.u_mul(c1);
299302
let v1 = V1.to_fq(field_nz);
300303
// let c2 = self.c1.sqr() - self.c0 * self.c2;
301304
let V2 = c1.u_sqr() - c0.u_mul(c2);
302305
let v2 = V2.to_fq(field_nz);
303306
// let t = ((self.c2 * c1 + self.c1 * c2).mul_by_nonresidue() + self.c0 * c0).inv();
304-
let t = (mul_by_xi(c2.u_mul(v1) + c1.u_mul(v2)) + c0.u_mul(v0))
307+
let t = (mul_by_xi_nz(c2.u_mul(v1) + c1.u_mul(v2), field_nz) + c0.u_mul(v0))
305308
.to_fq(field_nz)
306309
.inv(field_nz);
307310
Fq6 { c0: t * v0, c1: t * v1, c2: t * v2, }

Diff for: src/fields/tests/fq12_expo.cairo

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bn::fields::{
99
use bn::curve::{
1010
FIELD, u512, Tuple2Add, Tuple2Sub, U512BnAdd, U512BnSub, u512_sub_u256, u512_add, u512_sub
1111
};
12-
use bn::fields::fq_12_expo::{x2, x3, x4, X2, mul_by_xi, Krbn2345};
12+
use bn::fields::fq_12_expo::{x2, x3, x4, X2, mul_by_xi_nz, Krbn2345};
1313
use bn::fields::fq_generics::{TFqAdd, TFqSub, TFqMul, TFqDiv, TFqNeg, TFqPartialEq,};
1414
use bn::fields::print::{Fq12Display, Fq2Display};
1515
use debug::PrintTrait;
@@ -52,7 +52,7 @@ fn sqr() -> Fq12 {
5252
// fn krbn_experiments() {
5353
// let Fq12 { c0: Fq6 { c0: _, c1: _, c2: g2 }, c1: Fq6 { c0: g3, c1: g4, c2: g5 } } =
5454
// a_cyc();
55-
// let _field_nz: NonZero<u256> = FIELD.try_into().unwrap();
55+
// let field_nz: NonZero<u256> = FIELD.try_into().unwrap();
5656
// let asq = sqr();
5757
// // Si,j = (gi + gj )^2 and Si = gi^2
5858
// // let S2: (u512, u512) = g2.u_sqr();
@@ -72,7 +72,7 @@ fn sqr() -> Fq12 {
7272
// // h₅ = 2g₅ + 3 ((g₂+g₃)²-g₂²-g₃²)
7373

7474
// // h2 = 3(S4_5 − S4 − S5)ξ + 2g2;
75-
// // let _h2: (u512, u512) = X3(mul_by_xi(S4_5 - S4 - S5)).u512_add_fq(g2.u_add(g2));
75+
// // let _h2: (u512, u512) = X3(mul_by_xi_nz(S4_5 - S4 - S5, field_nz)).u512_add_fq(g2.u_add(g2));
7676
// // let h2: Fq2 = _h2.to_fq(field_nz);
7777

7878
// // h₂ = 2g₂ + 3ξ((g₄+g₅)²-g₄²-g₅²)

0 commit comments

Comments
 (0)