in src/compression/pairing.c [49:153]
void Tate3_pairings(point_full_proj_t *Qj, f2elm_t* f)
{
felm_t *x, *y, *l1, *l2, *n1, *n2, *x2, *x23, *x2p3;
f2elm_t xQ2s[t_points], finv[2*t_points], one = {0};
f2elm_t t0, t1, t2, t3, t4, t5, g, h, tf;
fpcopy((digit_t*)&Montgomery_one, one[0]);
for (int j = 0; j < t_points; j++) {
fp2copy(one, f[j]);
fp2copy(one, f[j+t_points]);
fp2sqr_mont(Qj[j]->X, xQ2s[j]);
}
for (int k = 0; k < OBOB_EXPON - 1; k++) {
l1 = (felm_t*)T_tate3 + 6*k + 0;
l2 = (felm_t*)T_tate3 + 6*k + 1;
n1 = (felm_t*)T_tate3 + 6*k + 2;
n2 = (felm_t*)T_tate3 + 6*k + 3;
x23 = (felm_t*)T_tate3 + 6*k + 4;
x2p3 = (felm_t*)T_tate3 + 6*k + 5;
for (int j = 0; j < t_points; j++) {
fpmul_mont(Qj[j]->X[0], *l1, t0[0]);
fpmul_mont(Qj[j]->X[1], *l1, t0[1]);
fpmul_mont(Qj[j]->X[0], *l2, t2[0]);
fpmul_mont(Qj[j]->X[1], *l2, t2[1]);
fpadd(xQ2s[j][0], *x23, t4[0]);
fpcopy(xQ2s[j][1], t4[1]);
fpmul_mont(Qj[j]->X[0], *x2p3, t5[0]);
fpmul_mont(Qj[j]->X[1], *x2p3, t5[1]);
fp2sub(t0, Qj[j]->Y, t1);
fpadd(t1[0], *n1, t1[0]);
fp2sub(t2, Qj[j]->Y, t3);
fpadd(t3[0], *n2, t3[0]);
fp2mul_mont(t1, t3, g);
fp2sub(t4, t5, h);
fp2_conj(h, h);
fp2mul_mont(g, h, g);
fp2sqr_mont(f[j], tf);
fp2mul_mont(f[j], tf, f[j]);
fp2mul_mont(f[j], g, f[j]);
fpsub(t0[1], Qj[j]->Y[0], t1[0]);
fpadd(t0[0], Qj[j]->Y[1], t1[1]);
fpneg(t1[1]);
fpadd(t1[1], *n1, t1[1]);
fpsub(t2[1], Qj[j]->Y[0], t3[0]);
fpadd(t2[0], Qj[j]->Y[1], t3[1]);
fpneg(t3[1]);
fpadd(t3[1], *n2, t3[1]);
fp2mul_mont(t1, t3, g);
fp2add(t4, t5, h);
fp2_conj(h, h);
fp2mul_mont(g, h, g);
fp2sqr_mont(f[j+t_points], tf);
fp2mul_mont(f[j+t_points], tf, f[j+t_points]);
fp2mul_mont(f[j+t_points], g, f[j+t_points]);
}
}
for (int j = 0; j < t_points; j++) {
x = (felm_t*)T_tate3 + 6*(OBOB_EXPON-1) + 0;
y = (felm_t*)T_tate3 + 6*(OBOB_EXPON-1) + 1;
l1 = (felm_t*)T_tate3 + 6*(OBOB_EXPON-1) + 2;
x2 = (felm_t*)T_tate3 + 6*(OBOB_EXPON-1) + 3;
fpsub(Qj[j]->X[0], *x, t0[0]);
fpcopy(Qj[j]->X[1], t0[1]);
fpmul_mont(*l1, t0[0], t1[0]);
fpmul_mont(*l1, t0[1], t1[1]);
fp2sub(t1, Qj[j]->Y, t2);
fpadd(t2[0], *y, t2[0]);
fp2mul_mont(t0, t2, g);
fpsub(Qj[j]->X[0], *x2, h[0]);
fpcopy(Qj[j]->X[1], h[1]);
fpneg(h[1]);
fp2mul_mont(g, h, g);
fp2sqr_mont(f[j], tf);
fp2mul_mont(f[j], tf, f[j]);
fp2mul_mont(f[j], g, f[j]);
fpadd(Qj[j]->X[0], *x, t0[0]);
fpmul_mont(*l1, t0[0], t1[0]);
fpsub(Qj[j]->Y[0], t1[1], t2[0]);
fpadd(Qj[j]->Y[1], t1[0], t2[1]);
fpsub(t2[1], *y, t2[1]);
fp2mul_mont(t0, t2, g);
fpadd(Qj[j]->X[0], *x2, h[0]);
fp2mul_mont(g, h, g);
fp2sqr_mont(f[j+t_points], tf);
fp2mul_mont(f[j+t_points], tf, f[j+t_points]);
fp2mul_mont(f[j+t_points], g, f[j+t_points]);
}
// Final exponentiation:
mont_n_way_inv(f, 2*t_points, finv);
for (int j = 0; j < 2*t_points; j++) {
final_exponentiation_3_torsion(f[j], finv[j], f[j]);
}
}