private static Fp12 MillerLoop(Bn128Fp g1, Bn128Fp2 g2) { // convert to affine coordinates g1 = g1.ToAffine(); g2 = g2.ToAffine(); // calculate Ell coefficients List <EllCoeffs> coeffs = CalcEllCoeffs(g2); Fp12 f = Fp12.One; int idx = 0; // for each bit except most significant one for (int i = LoopCount.BitLength() - 2; i >= 0; i--) { EllCoeffs cInLoop = coeffs[idx++]; f = f.Squared(); f = f.MulBy024(cInLoop.Ell0, g1.Y.Mul(cInLoop.EllVw), g1.X.Mul(cInLoop.EllVv)); if (LoopCount.TestBit(i)) { cInLoop = coeffs[idx++]; f = f.MulBy024(cInLoop.Ell0, g1.Y.Mul(cInLoop.EllVw), g1.X.Mul(cInLoop.EllVv)); } } EllCoeffs 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); }
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.PairingFinalExponentZ); Fp12 b = a.CyclotomicSquare(); Fp12 c = b.CyclotomicSquare(); Fp12 d = c.Mul(b); Fp12 e = d.NegExp(Parameters.PairingFinalExponentZ); Fp12 f = e.CyclotomicSquare(); Fp12 g = f.NegExp(Parameters.PairingFinalExponentZ); 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() { for (int i = 0; i < _pairs.Count; i++) { Fp12 miller = _pairs[i].MillerLoop(); if (!miller.Equals(Fp12.One)) // run mul code only if necessary { _product = _product.Mul(miller); } } // finalize _product = FinalExponentiation(_product); }