pub fn miller_naive(p: &G1Point, q: &G2Point) -> Fp12E {
    let mut t = q.clone();
    let mut f = Fp12E::one();
    let q_neg = &q.neg();
    MILLER_CONSTANT.iter().rev().skip(1).for_each(|m| {
        f = f.square() * line_naive(p, &t, &t);
        t = t.double();

        if *m == -1 {
            f *= line_naive(p, &t, q_neg);
            t = t.operate_with_affine(q_neg);
        } else if *m == 1 {
            f *= line_naive(p, &t, q);
            t = t.operate_with_affine(q);
        }
    });

    // q1 = ((x_q)^p, (y_q)^p, (z_q)^p)
    // See  https://hackmd.io/@Wimet/ry7z1Xj-2#The-Last-two-Lines
    let q1 = q.phi();
    f *= line_naive(p, &t, &q1);
    t = t.operate_with(&q1);

    // q2 = ((x_q1)^p, (y_q1)^p, (z_q1)^p)
    let q2 = q1.phi();
    f *= line_naive(p, &t, &q2.neg());

    f
}
Computes Miller loop using oprate_with(), operate_with_self() and line_naive().
See https://eprint.iacr.org/2010/354.pdf (Page 4, Algorithm 1).
crates/math/src/elliptic_curve/short_weierstrass/curves/bn_254/pairing.rs