public static Fp12 FinalExponentiation(Fp12 el) { // first chunk Fp12 w = new Fp12(el.a, el.b.Negate()); // el.b = -el.b Fp12 x = el.Inverse(); Fp12 y = w.Mul(x); Fp12 z = y.FrobeniusMap(2); Fp12 pre = z.Mul(y); // last chunk Fp12 a = pre.NegExp(Parameters.PAIRING_FINAL_EXPONENT_Z); Fp12 b = a.CyclotomicSquared(); Fp12 c = b.CyclotomicSquared(); Fp12 d = c.Mul(b); Fp12 e = d.NegExp(Parameters.PAIRING_FINAL_EXPONENT_Z); Fp12 f = e.CyclotomicSquared(); Fp12 g = f.NegExp(Parameters.PAIRING_FINAL_EXPONENT_Z); Fp12 h = d.UnitaryInverse(); Fp12 i = g.UnitaryInverse(); Fp12 j = i.Mul(e); Fp12 k = j.Mul(h); Fp12 l = k.Mul(b); Fp12 m = k.Mul(e); Fp12 n = m.Mul(pre); Fp12 o = l.FrobeniusMap(1); Fp12 p = o.Mul(n); Fp12 q = k.FrobeniusMap(2); Fp12 r = q.Mul(p); Fp12 s = pre.UnitaryInverse(); Fp12 t = s.Mul(l); Fp12 u = t.FrobeniusMap(3); Fp12 v = u.Mul(r); return(v); }
public void Run() { foreach (Pair pair in pairs) { Fp12 miller = pair.MillerLoop(); if (!miller.Equals(Fp12._1)) // run mul code only if necessary { product = product.Mul(miller); } } // finalize product = FinalExponentiation(product); }
private static Fp12 MillerLoop(BN128G1 g1, BN128G2 g2) { // convert to affine coordinates g1 = g1.ToAffineBN128G1(); g2 = g2.ToAffineBN128G2(); // calculate Ell coefficients List <EllCoeffs> coeffs = CalcEllCoeffs(g2); Fp12 f = Fp12._1; int idx = 0; EllCoeffs c; // for each bit except most significant one for (int i = LOOP_COUNT.BitLength - 2; i >= 0; i--) { c = coeffs[idx++]; f = f.Squared(); f = f.MulBy024(c.ell0, g1.y.Mul(c.ellVW), g1.x.Mul(c.ellVV)); if (LOOP_COUNT.TestBit(i)) { c = coeffs[idx++]; f = f.MulBy024(c.ell0, g1.y.Mul(c.ellVW), g1.x.Mul(c.ellVV)); } } c = coeffs[idx++]; f = f.MulBy024(c.ell0, g1.y.Mul(c.ellVW), g1.x.Mul(c.ellVV)); c = coeffs[idx]; f = f.MulBy024(c.ell0, g1.y.Mul(c.ellVW), g1.x.Mul(c.ellVV)); return(f); }