예제 #1
0
/* this+=this */
    public int dbl()
    {
        if (INF)
        {
            return(-1);
        }
        if (y.iszilch())
        {
            inf();
            return(-1);
        }

        FP2 w1 = new FP2(x);
        FP2 w2 = new FP2(0);
        FP2 w3 = new FP2(x);
        FP2 w8 = new FP2(x);

        w1.sqr();
        w8.copy(w1);
        w8.imul(3);

        w2.copy(y);
        w2.sqr();
        w3.copy(x);
        w3.mul(w2);
        w3.imul(4);
        w1.copy(w3);
        w1.neg();
        //	w1.norm();

        x.copy(w8);
        x.sqr();
        x.add(w1);
        x.add(w1);
        x.norm();

        z.mul(y);
        z.add(z);

        w2.add(w2);
        w2.sqr();
        w2.add(w2);
        w3.sub(x);
        y.copy(w8);
        y.mul(w3);
        //	w2.norm();
        y.sub(w2);

        y.norm();
        z.norm();

        return(1);
    }
예제 #2
0
/* Calculate RHS of twisted curve equation x^3+B/i */
    public static FP2 RHS(FP2 x)
    {
        x.norm();
        FP2 r = new FP2(x);

        r.sqr();
        FP2 b = new FP2(new BIG(ROM.CURVE_B));

        b.div_ip();
        r.mul(x);
        r.add(b);

        r.reduce();
        return(r);
    }
예제 #3
0
/* this=this^p using Frobenius */
    public void frob(FP2 f)
    {
        FP2 f2 = new FP2(f);
        FP2 f3 = new FP2(f);

        f2.sqr();
        f3.mul(f2);

        a.frob(f3);
        b.frob(f3);
        c.frob(f3);

        b.pmul(f);
        c.pmul(f2);
    }
예제 #4
0
/* this=1/this */
    public void inverse()
    {
        norm();

        FP2 t1 = new FP2(a);
        FP2 t2 = new FP2(b);

        t1.sqr();
        t2.sqr();
        t2.mul_ip();
        t1.sub(t2);
        t1.inverse();
        a.mul(t1);
        t1.neg();
        b.mul(t1);
    }
예제 #5
0
/* normalises m-array of ECP2 points. Requires work vector of m FP2s */

    public static void multiaffine(int m, ECP2[] P)
    {
        int i;
        FP2 t1 = new FP2(0);
        FP2 t2 = new FP2(0);

        FP2[] work = new FP2[m];
        work[0] = new FP2(1);
        work[1] = new FP2(P[0].z);
        for (i = 2; i < m; i++)
        {
            work[i] = new FP2(work[i - 1]);
            work[i].mul(P[i - 1].z);
        }

        t1.copy(work[m - 1]);
        t1.mul(P[m - 1].z);

        t1.inverse();

        t2.copy(P[m - 1].z);
        work[m - 1].mul(t1);

        for (i = m - 2;; i--)
        {
            if (i == 0)
            {
                work[0].copy(t1);
                work[0].mul(t2);
                break;
            }
            work[i].mul(t2);
            work[i].mul(t1);
            t2.mul(P[i].z);
        }
/* now work[] contains inverses of all Z coordinates */

        for (i = 0; i < m; i++)
        {
            P[i].z.one();
            t1.copy(work[i]);
            t1.sqr();
            P[i].x.mul(t1);
            t1.mul(work[i]);
            P[i].y.mul(t1);
        }
    }
예제 #6
0
/* set this*=q, where q is Modulus, using Frobenius */
    public void frob(FP2 X)
    {
        if (INF)
        {
            return;
        }
        FP2 X2 = new FP2(X);

        X2.sqr();
        x.conj();
        y.conj();
        z.conj();
        z.reduce();
        x.mul(X2);
        y.mul(X2);
        y.mul(X);
    }
예제 #7
0
/* construct this from (x,y) - but set to O if not on curve */
    public ECP2(FP2 ix, FP2 iy)
    {
        x = new FP2(ix);
        y = new FP2(iy);
        z = new FP2(1);
        FP2 rhs = RHS(x);
        FP2 y2  = new FP2(y);

        y2.sqr();
        if (y2.Equals(rhs))
        {
            INF = false;
        }
        else
        {
            x.zero();
            INF = true;
        }
    }
예제 #8
0
/* Test if P == Q */
    public bool Equals(ECP2 Q)
    {
        if (is_infinity() && Q.is_infinity())
        {
            return(true);
        }
        if (is_infinity() || Q.is_infinity())
        {
            return(false);
        }

        FP2 zs2 = new FP2(z);

        zs2.sqr();
        FP2 zo2 = new FP2(Q.z);

        zo2.sqr();
        FP2 zs3 = new FP2(zs2);

        zs3.mul(z);
        FP2 zo3 = new FP2(zo2);

        zo3.mul(Q.z);
        zs2.mul(Q.x);
        zo2.mul(x);
        if (!zs2.Equals(zo2))
        {
            return(false);
        }
        zs3.mul(Q.y);
        zo3.mul(y);
        if (!zs3.Equals(zo3))
        {
            return(false);
        }

        return(true);
    }
예제 #9
0
/* set to Affine - (x,y,z) to (x,y) */
    public void affine()
    {
        if (is_infinity())
        {
            return;
        }
        FP2 one = new FP2(1);

        if (z.Equals(one))
        {
            return;
        }
        z.inverse();

        FP2 z2 = new FP2(z);

        z2.sqr();
        x.mul(z2);
        x.reduce();
        y.mul(z2);
        y.mul(z);
        y.reduce();
        z.copy(one);
    }
예제 #10
0
/* this+=Q - return 0 for add, 1 for double, -1 for O */
    public int add(ECP2 Q)
    {
        if (INF)
        {
            copy(Q);
            return(-1);
        }
        if (Q.INF)
        {
            return(-1);
        }

        bool aff = false;

        if (Q.z.isunity())
        {
            aff = true;
        }

        FP2 A, C;
        FP2 B = new FP2(z);
        FP2 D = new FP2(z);

        if (!aff)
        {
            A = new FP2(Q.z);
            C = new FP2(Q.z);

            A.sqr();
            B.sqr();
            C.mul(A);
            D.mul(B);

            A.mul(x);
            C.mul(y);
        }
        else
        {
            A = new FP2(x);
            C = new FP2(y);

            B.sqr();
            D.mul(B);
        }

        B.mul(Q.x);
        B.sub(A);
        D.mul(Q.y);
        D.sub(C);

        if (B.iszilch())
        {
            if (D.iszilch())
            {
                dbl();
                return(1);
            }
            else
            {
                INF = true;
                return(-1);
            }
        }

        if (!aff)
        {
            z.mul(Q.z);
        }
        z.mul(B);

        FP2 e = new FP2(B);

        e.sqr();
        B.mul(e);
        A.mul(e);

        e.copy(A);
        e.add(A);
        e.add(B);
        x.copy(D);
        x.sqr();
        x.sub(e);

        A.sub(x);
        y.copy(A);
        y.mul(D);
        C.mul(B);
        y.sub(C);

        x.norm();
        y.norm();
        z.norm();

        return(0);
    }
예제 #11
0
/* Line function */
    public static FP12 line(ECP2 A, ECP2 B, FP Qx, FP Qy)
    {
        ECP2 P = new ECP2();

        FP4 a, b, c;

        P.copy(A);
        FP2 ZZ = new FP2(P.getz());

        ZZ.sqr();
        int D;

        if (A == B)
        {
            D = A.dbl();             // Check this return value in amcl_ec2.c
        }
        else
        {
            D = A.add(B);
        }
        if (D < 0)
        {
            return(new FP12(1));
        }
        FP2 Z3 = new FP2(A.getz());

        c = new FP4(0);
        if (D == 0)
        {         // Addition
            FP2 X = new FP2(B.getx());
            FP2 Y = new FP2(B.gety());
            FP2 T = new FP2(P.getz());
            T.mul(Y);
            ZZ.mul(T);

            FP2 NY = new FP2(P.gety());
            NY.neg();
            ZZ.add(NY);
            Z3.pmul(Qy);
            T.mul(P.getx());
            X.mul(NY);
            T.add(X);
            a = new FP4(Z3, T);
            ZZ.neg();
            ZZ.pmul(Qx);
            b = new FP4(ZZ);
        }
        else
        {         // Doubling
            FP2 X = new FP2(P.getx());
            FP2 Y = new FP2(P.gety());
            FP2 T = new FP2(P.getx());
            T.sqr();
            T.imul(3);

            Y.sqr();
            Y.add(Y);
            Z3.mul(ZZ);
            Z3.pmul(Qy);

            X.mul(T);
            X.sub(Y);
            a = new FP4(Z3, X);
            T.neg();
            ZZ.mul(T);
            ZZ.pmul(Qx);
            b = new FP4(ZZ);
        }
        return(new FP12(a, b, c));
    }