示例#1
0
/* this=this^e */
    public FP12 pow(BIG e)
    {
        norm();
        e.norm();
        FP12 w = new FP12(this);
        BIG  z = new BIG(e);
        FP12 r = new FP12(1);

        while (true)
        {
            int bt = z.parity();
            z.fshr(1);
            if (bt == 1)
            {
                r.mul(w);
            }
            if (z.iszilch())
            {
                break;
            }
            w.usqr();
        }
        r.reduce();
        return(r);
    }
示例#2
0
/* Pollards kangaroos used to return PIN error */
    public static int KANGAROO(sbyte[] E, sbyte[] F)
    {
        FP12 ge = FP12.fromBytes(E);
        FP12 gf = FP12.fromBytes(F);

        int[] distance = new int[TS];
        FP12  t        = new FP12(gf);

        FP12[] table = new FP12[TS];
        int    i, j, m, s, dn, dm, res, steps;

        s = 1;
        for (m = 0; m < TS; m++)
        {
            distance[m] = s;
            table[m]    = new FP12(t);
            s          *= 2;
            t.usqr();
        }
        t.one();
        dn = 0;
        for (j = 0; j < TRAP; j++)
        {
            i = t.geta().geta().A.lastbits(8) % TS;
            t.mul(table[i]);
            dn += distance[i];
        }
        gf.copy(t);
        gf.conj();
        steps = 0;
        dm    = 0;
        res   = 0;
        while (dm - dn < MAXPIN)
        {
            steps++;
            if (steps > 4 * TRAP)
            {
                break;
            }
            i = ge.geta().geta().A.lastbits(8) % TS;
            ge.mul(table[i]);
            dm += distance[i];
            if (ge.Equals(t))
            {
                res = dm - dn;
                break;
            }
            if (ge.Equals(gf))
            {
                res = dn - dm;
                break;
            }
        }
        if (steps > 4 * TRAP || dm - dn >= MAXPIN)
        {
            res = 0;
        }         // Trap Failed  - probable invalid token
        return(res);
    }
示例#3
0
/* Optimal R-ate pairing */
    public static FP12 ate(ECP2 P, ECP Q)
    {
        FP2  f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));
        BIG  x = new BIG(ROM.CURVE_Bnx);
        BIG  n = new BIG(x);
        ECP2 K = new ECP2();
        FP12 lv;

        n.pmul(6);
        n.dec(2);
        n.norm();
        P.affine();
        Q.affine();
        FP Qx = new FP(Q.getx());
        FP Qy = new FP(Q.gety());

        ECP2 A = new ECP2();
        FP12 r = new FP12(1);

        A.copy(P);
        int nb = n.nbits();

        for (int i = nb - 2; i >= 1; i--)
        {
            lv = line(A, A, Qx, Qy);
            r.smul(lv);

            if (n.bit(i) == 1)
            {
                lv = line(A, P, Qx, Qy);

                r.smul(lv);
            }
            r.sqr();
        }

        lv = line(A, A, Qx, Qy);
        r.smul(lv);

/* R-ate fixup */

        r.conj();

        K.copy(P);
        K.frob(f);
        A.neg();
        lv = line(A, K, Qx, Qy);
        r.smul(lv);
        K.frob(f);
        K.neg();
        lv = line(A, K, Qx, Qy);
        r.smul(lv);

        return(r);
    }
示例#4
0
/* constant time powering by small integer of max length bts */
    public void pinpow(int e, int bts)
    {
        int i, b;

        FP12[] R = new FP12[2];
        R[0] = new FP12(1);
        R[1] = new FP12(this);
        for (i = bts - 1; i >= 0; i--)
        {
            b = (e >> i) & 1;
            R[1 - b].mul(R[b]);
            R[b].usqr();
        }
        this.copy(R[0]);
    }
示例#5
0
        /* this=this^e */
        /* Note this is simple square and multiply, so not side-channel safe */
        public FP12 Pow(BIG e)
        {
            Norm();
            e.Norm();
            BIG e3 = new BIG(e);

            e3.PMul(3);
            e3.Norm();

            FP12 w = new FP12(this);

            int nb = e3.NBits();

            for (int i = nb - 2; i >= 1; i--)
            {
                w.USqr();
                int bt = e3.Bit(i) - e.Bit(i);
                if (bt == 1)
                {
                    w.mul(this);
                }
                if (bt == -1)
                {
                    Conj();
                    w.mul(this);
                    Conj();
                }
            }
            w.Reduce();
            return(w);


            /*
             *              BIG z=new BIG(e);
             *              FP12 r=new FP12(1);
             *
             *              while (true)
             *              {
             *                      int bt=z.parity();
             *                      z.fshr(1);
             *                      if (bt==1) r.mul(w);
             *                      if (z.iszilch()) break;
             *                      w.usqr();
             *              }
             *              r.reduce();
             *              return r; */
        }
示例#6
0
        /* f=f^e */
        /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
        public static FP12 GTPow(FP12 d, BIG e)
        {
            FP12 r;

            if (USE_GS_GT)
            {
                FP12[] g = new FP12[4];
                FP2    f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
                BIG    q = new BIG(ROM.CURVE_Order);
                BIG    t = new BIG(0);
                int    i, np, nn;
                BIG[]  u = GS(e);

                g[0] = new FP12(d);
                for (i = 1; i < 4; i++)
                {
                    g[i] = new FP12(0);
                    g[i].Copy(g[i - 1]);
                    g[i].Frob(f);
                }

                for (i = 0; i < 4; i++)
                {
                    np = u[i].NBits();
                    t.Copy(BIG.ModNeg(u[i], q));
                    nn = t.NBits();
                    if (nn < np)
                    {
                        u[i].Copy(t);
                        g[i].Conj();
                    }

                    u[i].Norm();
                }

                r = FP12.Pow4(g, u);
            }
            else
            {
                r = d.Pow(e);
            }

            return(r);
        }
示例#7
0
/* test group membership */
/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
    public static bool GTmember(FP12 m)
    {
        if (m.isunity())
        {
            return(false);
        }
        FP12 r = new FP12(m);

        r.conj();
        r.mul(m);
        if (!r.isunity())
        {
            return(false);
        }

        FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));

        r.copy(m);
        r.frob(f);
        r.frob(f);
        FP12 w = new FP12(r);

        w.frob(f);
        w.frob(f);
        w.mul(m);
        if (!ROM.GT_STRONG)
        {
            if (!w.Equals(r))
            {
                return(false);
            }
            BIG x = new BIG(ROM.CURVE_Bnx);
            r.copy(m);
            w = r.pow(x);
            w = w.pow(x);
            r.copy(w);
            r.sqr();
            r.mul(w);
            r.sqr();
            w.copy(m);
            w.frob(f);
        }
        return(w.Equals(r));
    }
示例#8
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);
        }
示例#9
0
/* Special case of multiplication arises from special form of ATE pairing line function */
    public void smul(FP12 y)
    {
        FP4 z0 = new FP4(a);
        FP4 z2 = new FP4(b);
        FP4 z3 = new FP4(b);
        FP4 t0 = new FP4(0);
        FP4 t1 = new FP4(y.a);

        z0.mul(y.a);
        z2.pmul(y.b.real());
        b.add(a);
        t1.real().add(y.b.real());

        b.mul(t1);
        z3.add(c);
        z3.pmul(y.b.real());

        t0.copy(z0);
        t0.neg();
        t1.copy(z2);
        t1.neg();

        b.add(t0);
//		b.norm();

        b.add(t1);
        z3.add(t1);
        z2.add(t0);

        t0.copy(a);
        t0.add(c);
        t0.mul(y.a);
        c.copy(z2);
        c.add(t0);

        z3.times_i();
        a.copy(z0);
        a.add(z3);

        norm();
    }
示例#10
0
        /* Constant time select from pre-computed table */
        public void Select(FP12[] g, int b)
        {
            int m    = b >> 31;
            int babs = (b ^ m) - m;

            babs = (babs - 1) / 2;

            CMove(g[0], Teq(babs, 0));           // conditional move
            CMove(g[1], Teq(babs, 1));
            CMove(g[2], Teq(babs, 2));
            CMove(g[3], Teq(babs, 3));
            CMove(g[4], Teq(babs, 4));
            CMove(g[5], Teq(babs, 5));
            CMove(g[6], Teq(babs, 6));
            CMove(g[7], Teq(babs, 7));

            FP12 invf = new FP12(this);

            invf.Conj();
            CMove(invf, (int)(m & 1));
        }
示例#11
0
/* f=f^e */
/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
    public static FP12 GTpow(FP12 d, BIG e)
    {
        FP12 r;

        if (ROM.USE_GS_GT)
        {
            FP12[] g = new FP12[4];
            FP2    f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));
            BIG    q = new BIG(ROM.CURVE_Order);
            BIG    t = new BIG(0);
            int    i, np, nn;
            BIG[]  u = gs(e);

            g[0] = new FP12(d);
            for (i = 1; i < 4; i++)
            {
                g[i] = new FP12(0);
                g[i].copy(g[i - 1]);
                g[i].frob(f);
            }
            for (i = 0; i < 4; i++)
            {
                np = u[i].nbits();
                t.copy(BIG.modneg(u[i], q));
                nn = t.nbits();
                if (nn < np)
                {
                    u[i].copy(t);
                    g[i].conj();
                }
            }
            r = FP12.pow4(g, u);
        }
        else
        {
            r = d.pow(e);
        }
        return(r);
    }
示例#12
0
/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
/* Timing attack secure, but not cache attack secure */

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

        int[]  a = new int[4];
        FP12[] g = new FP12[8];
        FP12[] s = new FP12[2];
        FP12   c = new FP12(1);
        FP12   p = new FP12(0);

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

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

        for (i = 0; i < 4; i++)
        {
            t[i] = new BIG(u[i]);
        }

        s[0] = new FP12(0);
        s[1] = new FP12(0);

        g[0] = new FP12(q[0]);
        s[0].copy(q[1]);
        s[0].conj();
        g[0].mul(s[0]);
        g[1] = new FP12(g[0]);
        g[2] = new FP12(g[0]);
        g[3] = new FP12(g[0]);
        g[4] = new FP12(q[0]);
        g[4].mul(q[1]);
        g[5] = new FP12(g[4]);
        g[6] = new FP12(g[4]);
        g[7] = new FP12(g[4]);

        s[1].copy(q[2]);
        s[0].copy(q[3]);
        s[0].conj();
        s[1].mul(s[0]);
        s[0].copy(s[1]);
        s[0].conj();
        g[1].mul(s[0]);
        g[2].mul(s[1]);
        g[5].mul(s[0]);
        g[6].mul(s[1]);
        s[1].copy(q[2]);
        s[1].mul(q[3]);
        s[0].copy(s[1]);
        s[0].conj();
        g[0].mul(s[0]);
        g[3].mul(s[1]);
        g[4].mul(s[0]);
        g[7].mul(s[1]);

/* if power is even add 1 to power, and add q to correction */

        for (i = 0; i < 4; i++)
        {
            if (t[i].parity() == 0)
            {
                t[i].inc(1);
                t[i].norm();
                c.mul(q[i]);
            }
            mt.add(t[i]);
            mt.norm();
        }
        c.conj();
        nb = 1 + mt.nbits();

/* convert exponent to signed 1-bit window */
        for (j = 0; j < nb; j++)
        {
            for (i = 0; i < 4; i++)
            {
                a[i] = (t[i].lastbits(2) - 2);
                t[i].dec(a[i]);
                t[i].norm();
                t[i].fshr(1);
            }
            w[j] = (sbyte)(8 * a[0] + 4 * a[1] + 2 * a[2] + a[3]);
        }
        w[nb] = (sbyte)(8 * t[0].lastbits(2) + 4 * t[1].lastbits(2) + 2 * t[2].lastbits(2) + t[3].lastbits(2));
        p.copy(g[(w[nb] - 1) / 2]);

        for (i = nb - 1; i >= 0; i--)
        {
            m = w[i] >> 7;
            j = (w[i] ^ m) - m;             // j=abs(w[i])
            j = (j - 1) / 2;
            s[0].copy(g[j]);
            s[1].copy(g[j]);
            s[1].conj();
            p.usqr();
            p.mul(s[m & 1]);
        }
        p.mul(c);         // apply correction
        p.reduce();
        return(p);
    }
示例#13
0
/* calculate common key on client side */
/* wCID = w.(A+AT) */
    public static int CLIENT_KEY(sbyte[] G1, sbyte[] G2, int pin, sbyte[] R, sbyte[] X, sbyte[] wCID, sbyte[] CK)
    {
        HASH H = new HASH();

        sbyte[] t = new sbyte[EFS];

        FP12 g1 = FP12.fromBytes(G1);
        FP12 g2 = FP12.fromBytes(G2);
        BIG  z  = BIG.fromBytes(R);
        BIG  x  = BIG.fromBytes(X);

        ECP W = ECP.fromBytes(wCID);

        if (W.is_infinity())
        {
            return(INVALID_POINT);
        }

        W = PAIR.G1mul(W, x);

        FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb));
        BIG r = new BIG(ROM.CURVE_Order);
        BIG q = new BIG(ROM.Modulus);

        BIG m = new BIG(q);

        m.mod(r);

        BIG a = new BIG(z);

        a.mod(m);

        BIG b = new BIG(z);

        b.div(m);

        g2.pinpow(pin, PBLEN);
        g1.mul(g2);

        FP4 c = g1.trace();

        g2.copy(g1);
        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);

        c.geta().A.toBytes(t);
        H.process_array(t);
        c.geta().B.toBytes(t);
        H.process_array(t);
        c.getb().A.toBytes(t);
        H.process_array(t);
        c.getb().B.toBytes(t);
        H.process_array(t);

        W.X.toBytes(t);
        H.process_array(t);
        W.Y.toBytes(t);
        H.process_array(t);

        t = H.hash();
        for (int i = 0; i < PAS; i++)
        {
            CK[i] = t[i];
        }

        return(0);
    }
示例#14
0
/* return 1 if x==y, else 0 */
    public bool Equals(FP12 x)
    {
        return(a.Equals(x.a) && b.Equals(x.b) && c.Equals(x.c));
    }
示例#15
0
/* calculate common key on server side */
/* Z=r.A - no time permits involved */

    public static int SERVER_KEY(sbyte[] Z, sbyte[] SST, sbyte[] W, sbyte[] xID, sbyte[] xCID, sbyte[] SK)
    {
        HASH H = new HASH();

        sbyte[] t = new sbyte[EFS];

        ECP2 sQ = ECP2.fromBytes(SST);

        if (sQ.is_infinity())
        {
            return(INVALID_POINT);
        }
        ECP R = ECP.fromBytes(Z);

        if (R.is_infinity())
        {
            return(INVALID_POINT);
        }

        ECP U;

        if (xCID != null)
        {
            U = ECP.fromBytes(xCID);
        }
        else
        {
            U = ECP.fromBytes(xID);
        }
        if (U.is_infinity())
        {
            return(INVALID_POINT);
        }

        BIG w = BIG.fromBytes(W);

        U = PAIR.G1mul(U, w);
        FP12 g = PAIR.ate(sQ, R);

        g = PAIR.fexp(g);

        FP4 c = g.trace();

        c.geta().A.toBytes(t);
        H.process_array(t);
        c.geta().B.toBytes(t);
        H.process_array(t);
        c.getb().A.toBytes(t);
        H.process_array(t);
        c.getb().B.toBytes(t);
        H.process_array(t);

        U.X.toBytes(t);
        H.process_array(t);
        U.Y.toBytes(t);
        H.process_array(t);

        t = H.hash();
        for (int i = 0; i < PAS; i++)
        {
            SK[i] = t[i];
        }

        return(0);
    }
示例#16
0
 /* copy this=x */
 public void Copy(FP12 x)
 {
     a.Copy(x.a);
     b.Copy(x.b);
     c.Copy(x.c);
 }
示例#17
0
/* FP12 full multiplication this=this*y */
    public void mul(FP12 y)
    {
        FP4 z0 = new FP4(a);
        FP4 z1 = new FP4(0);
        FP4 z2 = new FP4(b);
        FP4 z3 = new FP4(0);
        FP4 t0 = new FP4(a);
        FP4 t1 = new FP4(y.a);

        z0.mul(y.a);
        z2.mul(y.b);

        t0.add(b);
        t1.add(y.b);

        z1.copy(t0);
        z1.mul(t1);
        t0.copy(b);
        t0.add(c);

        t1.copy(y.b);
        t1.add(y.c);
        z3.copy(t0);
        z3.mul(t1);

        t0.copy(z0);
        t0.neg();
        t1.copy(z2);
        t1.neg();

        z1.add(t0);
//		z1.norm();
        b.copy(z1);
        b.add(t1);

        z3.add(t1);
        z2.add(t0);

        t0.copy(a);
        t0.add(c);
        t1.copy(y.a);
        t1.add(y.c);
        t0.mul(t1);
        z2.add(t0);

        t0.copy(c);
        t0.mul(y.c);
        t1.copy(t0);
        t1.neg();

//		z2.norm();
//		z3.norm();
//		b.norm();

        c.copy(z2);
        c.add(t1);
        z3.add(t1);
        t0.times_i();
        b.add(t0);

        z3.times_i();
        a.copy(z0);
        a.add(z3);
        norm();
    }
示例#18
0
 public FP12(FP12 x)
 {
     a = new FP4(x.a);
     b = new FP4(x.b);
     c = new FP4(x.c);
 }
示例#19
0
        /* FP12 full multiplication this=this*y */
        public void mul(FP12 y)
        {
            //System.out.println("Into mul");
            FP4 z0 = new FP4(a);
            FP4 z1 = new FP4(0);
            FP4 z2 = new FP4(b);
            FP4 z3 = new FP4(0);
            FP4 t0 = new FP4(a);
            FP4 t1 = new FP4(y.a);

            z0.Mul(y.a);
            z2.Mul(y.b);

            t0.Add(b);
            t1.Add(y.b);

            t0.Norm();
            t1.Norm();

            z1.Copy(t0);
            z1.Mul(t1);
            t0.Copy(b);
            t0.Add(c);

            t1.Copy(y.b);
            t1.Add(y.c);

            t0.Norm();
            t1.Norm();

            z3.Copy(t0);
            z3.Mul(t1);

            t0.Copy(z0);
            t0.Neg();
            t1.Copy(z2);
            t1.Neg();

            z1.Add(t0);
            //z1.norm();
            b.Copy(z1);
            b.Add(t1);

            z3.Add(t1);
            z2.Add(t0);

            t0.Copy(a);
            t0.Add(c);
            t1.Copy(y.a);
            t1.Add(y.c);

            t0.Norm();
            t1.Norm();

            t0.Mul(t1);
            z2.Add(t0);

            t0.Copy(c);
            t0.Mul(y.c);
            t1.Copy(t0);
            t1.Neg();

            //		z2.norm();
            //		z3.norm();
            //		b.norm();

            c.Copy(z2);
            c.Add(t1);
            z3.Add(t1);
            t0.Times_I();
            b.Add(t0);
            z3.Norm();
            z3.Times_I();
            a.Copy(z0);
            a.Add(z3);
            Norm();
            //System.out.println("Out of mul");
        }
示例#20
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);
        }
示例#21
0
        /* Optimal R-ate double pairing e(P,Q).e(R,S) */
        public static FP12 Ate2(ECP2 P1, ECP Q1, ECP2 R1, ECP S1)
        {
            FP2  f;
            BIG  x = new BIG(ROM.CURVE_Bnx);
            BIG  n = new BIG(x);
            ECP2 K = new ECP2();
            FP12 lv;
            int  bt;

            ECP2 P = new ECP2(P1);
            ECP  Q = new ECP(Q1);

            P.Affine();
            Q.Affine();

            ECP2 R = new ECP2(R1);
            ECP  S = new ECP(S1);

            R.Affine();
            S.Affine();

            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb));
                if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
                {
                    f.Inverse();
                    f.Norm();
                }

                n.PMul(6);
                if (ECP.SIGN_OF_X == ECP.POSITIVEX)
                {
                    n.Inc(2);
                }
                else
                {
                    n.Dec(2);
                }
            }
            else
            {
                n.Copy(x);
            }

            n.Norm();

            BIG n3 = new BIG(n);

            n3.PMul(3);
            n3.Norm();

            FP Qx = new FP(Q.GetX());
            FP Qy = new FP(Q.GetY());
            FP Sx = new FP(S.GetX());
            FP Sy = new FP(S.GetY());

            ECP2 A = new ECP2();
            ECP2 B = new ECP2();
            FP12 r = new FP12(1);

            A.Copy(P);
            B.Copy(R);

            ECP2 MP = new ECP2();

            MP.Copy(P);
            MP.Neg();
            ECP2 MR = new ECP2();

            MR.Copy(R);
            MR.Neg();


            int nb = n3.NBits();

            for (int i = nb - 2; i >= 1; i--)
            {
                r.Sqr();
                lv = Line(A, A, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);

                lv = Line(B, B, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);

                bt = n3.Bit(i) - n.Bit(i); // bt=n.bit(i);
                if (bt == 1)
                {
                    lv = Line(A, P, Qx, Qy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    lv = Line(B, R, Sx, Sy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                }

                if (bt == -1)
                {
                    //P.neg();
                    lv = Line(A, MP, Qx, Qy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    //P.neg();
                    //R.neg();
                    lv = Line(B, MR, Sx, Sy);
                    r.SMul(lv, ECP.SEXTIC_TWIST);
                    //R.neg();
                }
            }

            if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
            {
                r.Conj();
            }

            /* R-ate fixup required for BN curves */
            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    //	r.conj();
                    A.Neg();
                    B.Neg();
                }

                K.Copy(P);
                K.Frob(f);

                lv = Line(A, K, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Frob(f);
                K.Neg();
                lv = Line(A, K, Qx, Qy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Copy(R);
                K.Frob(f);
                lv = Line(B, K, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
                K.Frob(f);
                K.Neg();
                lv = Line(B, K, Sx, Sy);
                r.SMul(lv, ECP.SEXTIC_TWIST);
            }

            return(r);
        }
示例#22
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);
        }
示例#23
0
/* copy this=x */
    public void copy(FP12 x)
    {
        a.copy(x.a);
        b.copy(x.b);
        c.copy(x.c);
    }
示例#24
0
        /* Special case of multiplication arises from special form of ATE pairing line function */
        public void SMul(FP12 y, int type)
        {
            //System.out.println("Into smul");

            if (type == ECP.D_TYPE)
            {
                FP4 z0 = new FP4(a);
                FP4 z2 = new FP4(b);
                FP4 z3 = new FP4(b);
                FP4 t0 = new FP4(0);
                FP4 t1 = new FP4(y.a);
                z0.Mul(y.a);
                z2.PMul(y.b.Real());
                b.Add(a);
                t1.Real().Add(y.b.Real());

                t1.Norm();
                b.Norm();
                b.Mul(t1);
                z3.Add(c);
                z3.Norm();
                z3.PMul(y.b.Real());

                t0.Copy(z0);
                t0.Neg();
                t1.Copy(z2);
                t1.Neg();

                b.Add(t0);

                b.Add(t1);
                z3.Add(t1);
                z2.Add(t0);

                t0.Copy(a);
                t0.Add(c);
                t0.Norm();
                z3.Norm();
                t0.Mul(y.a);
                c.Copy(z2);
                c.Add(t0);

                z3.Times_I();
                a.Copy(z0);
                a.Add(z3);
            }
            if (type == ECP.M_TYPE)
            {
                FP4 z0 = new FP4(a);
                FP4 z1 = new FP4(0);
                FP4 z2 = new FP4(0);
                FP4 z3 = new FP4(0);
                FP4 t0 = new FP4(a);
                FP4 t1 = new FP4(0);

                z0.Mul(y.a);
                t0.Add(b);
                t0.Norm();

                z1.Copy(t0);
                z1.Mul(y.a);
                t0.Copy(b);
                t0.Add(c);
                t0.Norm();

                z3.Copy(t0);                 //z3.mul(y.c);
                z3.PMul(y.c.GetB());
                z3.Times_I();

                t0.Copy(z0);
                t0.Neg();

                z1.Add(t0);
                b.Copy(z1);
                z2.Copy(t0);

                t0.Copy(a);
                t0.Add(c);
                t1.Copy(y.a);
                t1.Add(y.c);

                t0.Norm();
                t1.Norm();

                t0.Mul(t1);
                z2.Add(t0);

                t0.Copy(c);

                t0.PMul(y.c.GetB());
                t0.Times_I();

                t1.Copy(t0);
                t1.Neg();

                c.Copy(z2);
                c.Add(t1);
                z3.Add(t1);
                t0.Times_I();
                b.Add(t0);
                z3.Norm();
                z3.Times_I();
                a.Copy(z0);
                a.Add(z3);
            }
            Norm();
            //System.out.println("Out of smul");
        }
示例#25
0
 public void CMove(FP12 g, int d)
 {
     a.CMove(g.a, d);
     b.CMove(g.b, d);
     c.CMove(g.c, d);
 }
示例#26
0
        /**
         * Verify this signature
         *
         * @param disclosure      an array indicating which attributes it expects to be disclosed
         * @param ipk             the issuer public key
         * @param msg             the message that should be signed in this signature
         * @param attributeValues BIG array where attributeValues[i] contains the desired attribute value for the i-th attribute if its disclosed
         * @param rhIndex         index of the attribute that represents the revocation-handle
         * @param revPk           the long term public key used to authenticate CRIs
         * @param epoch           monotonically increasing counter representing a time window
         * @return true iff valid
         */
        // ReSharper disable once ParameterHidesMember
        public bool Verify(bool[] disclosure, IdemixIssuerPublicKey ipk, byte[] msg, BIG[] attributeValues, int rhIndex, KeyPair revPk, int epoch)
        {
            if (disclosure == null || ipk == null || msg == null || attributeValues == null || attributeValues.Length != ipk.AttributeNames.Length || disclosure.Length != ipk.AttributeNames.Length)
            {
                return(false);
            }

            for (int i = 0; i < ipk.AttributeNames.Length; i++)
            {
                if (disclosure[i] && attributeValues[i] == null)
                {
                    return(false);
                }
            }

            int[] hiddenIndices = HiddenIndices(disclosure);
            if (proofSAttrs.Length != hiddenIndices.Length)
            {
                return(false);
            }

            if (aPrime.IsInfinity())
            {
                return(false);
            }

            if (nonRevocationProof.RevocationAlg >= Enum.GetValues(typeof(RevocationAlgorithm)).Length)
            {
                throw new ArgumentException("CRI specifies unknown revocation algorithm");
            }

            RevocationAlgorithm revocationAlgorithm = (RevocationAlgorithm)nonRevocationProof.RevocationAlg;

            if (disclosure[rhIndex])
            {
                throw new ArgumentException("Attribute " + rhIndex + " is disclosed but also used a revocation handle attribute, which should remain hidden");
            }


            // Verify EpochPK
            if (!RevocationAuthority.VerifyEpochPK(revPk, revocationPk, revocationPKSig, epoch, revocationAlgorithm))
            {
                // Signature is based on an invalid revocation epoch public key
                return(false);
            }

            FP12 temp1 = PAIR.Ate(ipk.W, aPrime);
            FP12 temp2 = PAIR.Ate(IdemixUtils.GenG2, aBar);

            temp2.Inverse();
            temp1.mul(temp2);
            if (!PAIR.FExp(temp1).IsUnity())
            {
                return(false);
            }


            ECP t1   = aPrime.Mul2(proofSE, ipk.HRand, proofSR2);
            ECP temp = new ECP();

            temp.Copy(aBar);
            temp.Sub(bPrime);
            t1.Sub(PAIR.G1Mul(temp, proofC));

            ECP t2 = PAIR.G1Mul(ipk.HRand, proofSSPrime);

            t2.Add(bPrime.Mul2(proofSR3, ipk.Hsk, proofSSk));

            for (int i = 0; i < hiddenIndices.Length / 2; i++)
            {
                t2.Add(ipk.HAttrs[hiddenIndices[2 * i]].Mul2(proofSAttrs[2 * i], ipk.HAttrs[hiddenIndices[2 * i + 1]], proofSAttrs[2 * i + 1]));
            }

            if (hiddenIndices.Length % 2 != 0)
            {
                t2.Add(PAIR.G1Mul(ipk.HAttrs[hiddenIndices[hiddenIndices.Length - 1]], proofSAttrs[hiddenIndices.Length - 1]));
            }

            temp = new ECP();
            temp.Copy(IdemixUtils.GenG1);

            for (int i = 0; i < disclosure.Length; i++)
            {
                if (disclosure[i])
                {
                    temp.Add(PAIR.G1Mul(ipk.HAttrs[i], attributeValues[i]));
                }
            }

            t2.Add(PAIR.G1Mul(temp, proofC));

            ECP t3 = ipk.Hsk.Mul2(proofSSk, ipk.HRand, proofSRNym);

            t3.Sub(nym.Mul(proofC));

            // Check with non-revoked-verifier
            INonRevocationVerifier nonRevokedVerifier = NonRevocationVerifier.GetNonRevocationVerifier(revocationAlgorithm);
            int hiddenRHIndex = Array.IndexOf(hiddenIndices, rhIndex);

            if (hiddenRHIndex < 0)
            {
                // rhIndex is not present, set to last index position
                hiddenRHIndex = hiddenIndices.Length;
            }

            BIG proofSRh = proofSAttrs[hiddenRHIndex];

            byte[] nonRevokedProofBytes = nonRevokedVerifier.RecomputeFSContribution(nonRevocationProof, proofC, revocationPk.ToECP2(), proofSRh);
            if (nonRevokedProofBytes == null)
            {
                return(false);
            }


            // create proofData such that it can contain the sign label, 7 elements in G1 (each of size 2*FIELD_BYTES+1),
            // the ipk hash, the disclosure array, and the message
            byte[] proofData = new byte[0];
            proofData = proofData.Append(SIGN_LABEL.ToBytes());
            proofData = proofData.Append(t1.ToBytes());
            proofData = proofData.Append(t2.ToBytes());
            proofData = proofData.Append(t3.ToBytes());
            proofData = proofData.Append(aPrime.ToBytes());
            proofData = proofData.Append(aBar.ToBytes());
            proofData = proofData.Append(bPrime.ToBytes());
            proofData = proofData.Append(nym.ToBytes());
            proofData = proofData.Append(ipk.Hash);
            proofData = proofData.Append(disclosure);
            proofData = proofData.Append(msg);

            BIG cvalue = proofData.HashModOrder();

            byte[] finalProofData = new byte[0];
            finalProofData = finalProofData.Append(cvalue.ToBytes());
            finalProofData = finalProofData.Append(nonce.ToBytes());

            byte[] hashedProofData = finalProofData.HashModOrder().ToBytes();
            return(Enumerable.SequenceEqual(proofC.ToBytes(), hashedProofData));
        }
示例#27
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.CURVE_Fra), new BIG(ROM.CURVE_Frb));
        BIG  x = new BIG(ROM.CURVE_Bnx);
        FP12 r = new FP12(m);
        FP12 x0, x1, x2, x3, x4, x5;

/* 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 */
        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);

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

        x2 = x4.pow(x);

        x5 = new FP12(x2);
        x5.conj();
        lv = x2.pow(x);

        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();
        return(r);
    }