Example #1
0
        /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */

        /*
         *      public static ECP2 mul4(ECP2[] Q,BIG[] u)
         *      {
         *              int i,j,nb;
         *              int[] a=new int[4];
         *              ECP2 T=new ECP2();
         *              ECP2 C=new ECP2();
         *              ECP2 P=new ECP2();
         *              ECP2[] W=new ECP2[8];
         *
         *              BIG mt=new BIG();
         *              BIG[] t=new BIG[4];
         *
         *              byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
         *
         *              for (i=0;i<4;i++)
         *              {
         *                      t[i]=new BIG(u[i]);
         *                      Q[i].affine();
         *              }
         *
         * // precompute table
         *
         *              W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
         *
         *              W[1]=new ECP2(); W[1].copy(W[0]);
         *              W[2]=new ECP2(); W[2].copy(W[0]);
         *              W[3]=new ECP2(); W[3].copy(W[0]);
         *              W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
         *              W[5]=new ECP2(); W[5].copy(W[4]);
         *              W[6]=new ECP2(); W[6].copy(W[4]);
         *              W[7]=new ECP2(); W[7].copy(W[4]);
         *              T.copy(Q[2]); T.sub(Q[3]);
         *              W[1].sub(T);
         *              W[2].add(T);
         *              W[5].sub(T);
         *              W[6].add(T);
         *              T.copy(Q[2]); T.add(Q[3]);
         *              W[0].sub(T);
         *              W[3].add(T);
         *              W[4].sub(T);
         *              W[7].add(T);
         *
         * // if multiplier is even add 1 to multiplier, and add P to correction
         *              mt.zero(); C.inf();
         *              for (i=0;i<4;i++)
         *              {
         *                      if (t[i].parity()==0)
         *                      {
         *                              t[i].inc(1); t[i].norm();
         *                              C.add(Q[i]);
         *                      }
         *                      mt.add(t[i]); mt.norm();
         *              }
         *
         *              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]=(byte)(t[i].lastbits(2)-2);
         *                              t[i].dec(a[i]); t[i].norm();
         *                              t[i].fshr(1);
         *                      }
         *                      w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
         *              }
         *              w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
         *
         *              P.copy(W[(w[nb]-1)/2]);
         *              for (i=nb-1;i>=0;i--)
         *              {
         *                      T.select(W,w[i]);
         *                      P.dbl();
         *                      P.add(T);
         *              }
         *              P.sub(C); // apply correction
         *
         *              P.affine();
         *              return P;
         *      }
         */

        /* needed for SOK */
        public static ECP2 MapIt(sbyte[] h)
        {
            BIG  q   = new BIG(ROM.Modulus);
            BIG  x   = BIG.FromBytes(h);
            BIG  one = new BIG(1);
            FP2  X;
            ECP2 Q;

            x.Mod(q);
            while (true)
            {
                X = new FP2(one, x);
                Q = new ECP2(X);
                if (!Q.IsInfinity())
                {
                    break;
                }
                x.Inc(1);
                x.Norm();
            }

            BIG Fra = new BIG(ROM.Fra);
            BIG Frb = new BIG(ROM.Frb);

            X = new FP2(Fra, Frb);

            if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
            {
                X.Inverse();
                X.Norm();
            }

            x = new BIG(ROM.CURVE_Bnx);

            /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */

            if (ECP.CURVE_PAIRING_TYPE == ECP.BN)
            {
                ECP2 T, K;

                T = new ECP2();
                T.Copy(Q);
                T = T.Mul(x);

                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    T.Neg();
                }
                K = new ECP2();
                K.Copy(T);
                K.Dbl();
                K.Add(T);                 //K.affine();

                K.Frob(X);
                Q.Frob(X);
                Q.Frob(X);
                Q.Frob(X);
                Q.Add(T);
                Q.Add(K);
                T.Frob(X);
                T.Frob(X);
                Q.Add(T);
            }

            /* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
            /* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */

            if (ECP.CURVE_PAIRING_TYPE == ECP.BLS)
            {
                //	ECP2 xQ,x2Q;
                //	xQ=new ECP2();
                //	x2Q=new ECP2();

                ECP2 xQ  = Q.Mul(x);
                ECP2 x2Q = xQ.Mul(x);

                if (ECP.SIGN_OF_X == ECP.NEGATIVEX)
                {
                    xQ.Neg();
                }

                x2Q.Sub(xQ);
                x2Q.Sub(Q);

                xQ.Sub(Q);
                xQ.Frob(X);

                Q.Dbl();
                Q.Frob(X);
                Q.Frob(X);

                Q.Add(x2Q);
                Q.Add(xQ);
            }
            Q.Affine();
            return(Q);
        }