예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }