Beispiel #1
0
        public FP4 ComPow(BIG e, BIG r)
        {
            FP12 g1 = new FP12(0);
            FP12 g2 = new FP12(0);
            FP2  f  = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
            BIG  q  = new BIG(ROM.Modulus);

            BIG m = new BIG(q);

            m.Mod(r);

            BIG a = new BIG(e);

            a.Mod(m);

            BIG b = new BIG(e);

            b.Div(m);

            g1.Copy(this);
            g2.Copy(this);

            FP4 c = g1.Trace();

            if (b.IsZilch())
            {
                c = c.Xtr_Pow(e);
                return(c);
            }

            g2.Frob(f);
            FP4 cp = g2.Trace();

            g1.Conj();
            g2.mul(g1);
            FP4 cpm1 = g2.Trace();

            g2.mul(g1);
            FP4 cpm2 = g2.Trace();

            c = c.Xtr_Pow2(cp, cpm1, cpm2, a, b);

            return(c);
        }
Beispiel #2
0
        /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
        public static FP12 FExp(FP12 m)
        {
            FP2  f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
            BIG  x = new BIG(ROM.CURVE_Bnx);
            FP12 r = new FP12(m);

            /* Easy part of final exp */
            FP12 lv = new FP12(r);

            lv.Inverse();
            r.Conj();

            r.mul(lv);
            lv.Copy(r);
            r.Frob(f);
            r.Frob(f);
            r.mul(lv);
            /* Hard part of final exp */
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                FP12 x0, x1, x2, x3, x4, x5;
                lv.Copy(r);
                lv.Frob(f);
                x0 = new FP12(lv);
                x0.Frob(f);
                lv.mul(r);
                x0.mul(lv);
                x0.Frob(f);
                x1 = new FP12(r);
                x1.Conj();
                x4 = r.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    x4.Conj();
                }

                x3 = new FP12(x4);
                x3.Frob(f);

                x2 = x4.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    x2.Conj();
                }

                x5 = new FP12(x2);
                x5.Conj();
                lv = x2.Pow(x);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    lv.Conj();
                }

                x2.Frob(f);
                r.Copy(x2);
                r.Conj();

                x4.mul(r);
                x2.Frob(f);

                r.Copy(lv);
                r.Frob(f);
                lv.mul(r);

                lv.USqr();
                lv.mul(x4);
                lv.mul(x5);
                r.Copy(x3);
                r.mul(x5);
                r.mul(lv);
                lv.mul(x2);
                r.USqr();
                r.mul(lv);
                r.USqr();
                lv.Copy(r);
                lv.mul(x1);
                r.mul(x0);
                lv.USqr();
                r.mul(lv);
                r.Reduce();
            }
            else
            {
                FP12 y0, y1, y2, y3;
                // Ghamman & Fouotsa Method
                y0 = new FP12(r);
                y0.USqr();
                y1 = y0.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y1.Conj();
                }

                x.FShr(1);
                y2 = y1.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                x.FShl(1);
                y3 = new FP12(r);
                y3.Conj();
                y1.mul(y3);

                y1.Conj();
                y1.mul(y2);

                y2 = y1.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                y3 = y2.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y3.Conj();
                }

                y1.Conj();
                y3.mul(y1);

                y1.Conj();
                y1.Frob(f);
                y1.Frob(f);
                y1.Frob(f);
                y2.Frob(f);
                y2.Frob(f);
                y1.mul(y2);

                y2 = y3.Pow(x);
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    y2.Conj();
                }

                y2.mul(y0);
                y2.mul(r);

                y1.mul(y2);
                y2.Copy(y3);
                y2.Frob(f);
                y1.mul(y2);
                r.Copy(y1);
                r.Reduce();
            }

            return(r);
        }
Beispiel #3
0
        /* p=q0^u0.q1^u1.q2^u2.q3^u3 */
        // Bos & Costello https://eprint.iacr.org/2013/458.pdf
        // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
        // Side channel attack secure

        public static FP12 Pow4(FP12[] q, BIG[] u)
        {
            int i, j, nb, pb;

            FP12[] g = new FP12[8];
            FP12   r = new FP12(1);
            FP12   p = new FP12(0);

            BIG[] t  = new BIG[4];
            BIG   mt = new BIG(0);

            sbyte[] w = new sbyte[BIG.NLEN * BIG.BASEBITS + 1];
            sbyte[] s = new sbyte[BIG.NLEN * BIG.BASEBITS + 1];

            for (i = 0; i < 4; i++)
            {
                t[i] = new BIG(u[i]);
                t[i].Norm();
            }
            g[0] = new FP12(q[0]);      // q[0]
            g[1] = new FP12(g[0]);
            g[1].mul(q[1]);             // q[0].q[1]
            g[2] = new FP12(g[0]);
            g[2].mul(q[2]);             // q[0].q[2]
            g[3] = new FP12(g[1]);
            g[3].mul(q[2]);             // q[0].q[1].q[2]
            g[4] = new FP12(q[0]);
            g[4].mul(q[3]);             // q[0].q[3]
            g[5] = new FP12(g[1]);
            g[5].mul(q[3]);             // q[0].q[1].q[3]
            g[6] = new FP12(g[2]);
            g[6].mul(q[3]);             // q[0].q[2].q[3]
            g[7] = new FP12(g[3]);
            g[7].mul(q[3]);             // q[0].q[1].q[2].q[3]

            // Make it odd
            pb = 1 - t[0].Parity();
            t[0].Inc(pb);
            t[0].Norm();

            // Number of bits
            mt.Zero();
            for (i = 0; i < 4; i++)
            {
                mt.Or(t[i]);
            }
            nb = 1 + mt.NBits();

            // Sign pivot
            s[nb - 1] = 1;
            for (i = 0; i < nb - 1; i++)
            {
                t[0].FShr(1);
                s[i] = (sbyte)(2 * t[0].Parity() - 1);
            }

            // Recoded exponent
            for (i = 0; i < nb; i++)
            {
                w[i] = 0;
                int k = 1;
                for (j = 1; j < 4; j++)
                {
                    sbyte bt = (sbyte)(s[i] * t[j].Parity());
                    t[j].FShr(1);
                    t[j].Dec((int)(bt) >> 1);
                    t[j].Norm();
                    w[i] += (sbyte)(bt * (sbyte)k);
                    k    *= 2;
                }
            }

            // Main loop
            p.Select(g, (int)(2 * w[nb - 1] + 1));
            for (i = nb - 2; i >= 0; i--)
            {
                p.USqr();
                r.Select(g, (int)(2 * w[i] + s[i]));
                p.mul(r);
            }

            // apply correction
            r.Copy(q[0]);
            r.Conj();
            r.mul(p);
            p.CMove(r, pb);

            p.Reduce();
            return(p);
        }