/* this*=this */ public void Sqr() { // norm(); FP2 t1 = new FP2(a); FP2 t2 = new FP2(b); FP2 t3 = new FP2(a); t3.Mul(b); t1.Add(b); t2.Mul_Ip(); t2.Add(a); t1.Norm(); t2.Norm(); a.Copy(t1); a.Mul(t2); t2.Copy(t3); t2.Mul_Ip(); t2.Add(t3); t2.Norm(); t2.Neg(); a.Add(t2); b.Copy(t3); b.Add(t3); Norm(); }
/* Multiply P by e in group G2 */ public static ECP2 G2Mul(ECP2 P, BIG e) { ECP2 R; if (USE_GS_G2) { ECP2[] Q = new ECP2[4]; FP2 f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb)); if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { f.Inverse(); f.Norm(); } BIG q = new BIG(ROM.CURVE_Order); BIG[] u = GS(e); BIG t = new BIG(0); int i, np, nn; //P.affine(); Q[0] = new ECP2(); Q[0].Copy(P); for (i = 1; i < 4; i++) { Q[i] = new ECP2(); Q[i].Copy(Q[i - 1]); Q[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); Q[i].Neg(); } u[i].Norm(); //Q[i].affine(); } R = ECP2.Mul4(Q, u); } else { R = P.Mul(e); } return(R); }
/* this*=y */ public void Mul(FP4 y) { // norm(); FP2 t1 = new FP2(a); FP2 t2 = new FP2(b); FP2 t3 = new FP2(0); FP2 t4 = new FP2(b); t1.Mul(y.a); t2.Mul(y.b); t3.Copy(y.b); t3.Add(y.a); t4.Add(a); t3.Norm(); t4.Norm(); t4.Mul(t3); t3.Copy(t1); t3.Neg(); t4.Add(t3); t4.Norm(); // t4.sub(t1); // t4.norm(); t3.Copy(t2); t3.Neg(); b.Copy(t4); b.Add(t3); // b.copy(t4); // b.sub(t2); t2.Mul_Ip(); a.Copy(t2); a.Add(t1); Norm(); }
public void Div_2I() { FP2 u = new FP2(a); FP2 v = new FP2(b); u.Div_Ip2(); v.Add(v); v.Norm(); a.Copy(v); b.Copy(u); }
/* this=1/this */ public void Inverse() { // norm(); FP2 t1 = new FP2(a); FP2 t2 = new FP2(b); t1.Sqr(); t2.Sqr(); t2.Mul_Ip(); t2.Norm(); t1.Sub(t2); t1.Inverse(); a.Mul(t1); t1.Neg(); t1.Norm(); b.Mul(t1); }
/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ /* returns true if this is QR */ public bool Sqrt() { if (IsZilch()) { return(true); } FP2 wa = new FP2(a); FP2 ws = new FP2(b); FP2 wt = new FP2(a); if (ws.IsZilch()) { if (wt.Sqrt()) { a.Copy(wt); b.Zero(); } else { wt.Div_Ip(); wt.Sqrt(); b.Copy(wt); a.Zero(); } return(true); } ws.Sqr(); wa.Sqr(); ws.Mul_Ip(); ws.Norm(); wa.Sub(ws); ws.Copy(wa); if (!ws.Sqrt()) { return(false); } wa.Copy(wt); wa.Add(ws); wa.Norm(); wa.Div2(); if (!wa.Sqrt()) { wa.Copy(wt); wa.Sub(ws); wa.Norm(); wa.Div2(); if (!wa.Sqrt()) { return(false); } } wt.Copy(b); ws.Copy(wa); ws.Add(wa); ws.Inverse(); wt.Mul(ws); a.Copy(wa); b.Copy(wt); return(true); }
/* normalise all components of this mod Modulus */ public void Norm() { a.Norm(); b.Norm(); }
/* Line function */ public static FP12 Line(ECP2 A, ECP2 B, FP Qx, FP Qy) { //System.out.println("Into line"); FP4 a, b, c; // Edits here // c=new FP4(0); if (A == B) { // Doubling FP2 XX = new FP2(A.GetX()); //X FP2 YY = new FP2(A.GetY()); //Y FP2 ZZ = new FP2(A.GetZ()); //Z FP2 YZ = new FP2(YY); //Y YZ.Mul(ZZ); //YZ XX.Sqr(); //X^2 YY.Sqr(); //Y^2 ZZ.Sqr(); //Z^2 YZ.IMul(4); YZ.Neg(); YZ.Norm(); //-2YZ YZ.PMul(Qy); //-2YZ.Ys XX.IMul(6); //3X^2 XX.PMul(Qx); //3X^2.Xs int sb = 3 * ROM.CURVE_B_I; ZZ.IMul(sb); if (ECP.SEXTIC_TWIST == ECP.D_TYPE) { ZZ.Div_Ip2(); } if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { ZZ.Mul_Ip(); ZZ.Add(ZZ); YZ.Mul_Ip(); YZ.Norm(); } ZZ.Norm(); // 3b.Z^2 YY.Add(YY); ZZ.Sub(YY); ZZ.Norm(); // 3b.Z^2-Y^2 a = new FP4(YZ, ZZ); // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs if (ECP.SEXTIC_TWIST == ECP.D_TYPE) { b = new FP4(XX); // L(0,1) | L(0,0) | L(1,0) c = new FP4(0); } if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { b = new FP4(0); c = new FP4(XX); c.Times_I(); } A.Dbl(); } else { // Addition - assume B is affine FP2 X1 = new FP2(A.GetX()); // X1 FP2 Y1 = new FP2(A.GetY()); // Y1 FP2 T1 = new FP2(A.GetZ()); // Z1 FP2 T2 = new FP2(A.GetZ()); // Z1 T1.Mul(B.GetY()); // T1=Z1.Y2 T2.Mul(B.GetX()); // T2=Z1.X2 X1.Sub(T2); X1.Norm(); // X1=X1-Z1.X2 Y1.Sub(T1); Y1.Norm(); // Y1=Y1-Z1.Y2 T1.Copy(X1); // T1=X1-Z1.X2 X1.PMul(Qy); // X1=(X1-Z1.X2).Ys if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { X1.Mul_Ip(); X1.Norm(); } T1.Mul(B.GetY()); // T1=(X1-Z1.X2).Y2 T2.Copy(Y1); // T2=Y1-Z1.Y2 T2.Mul(B.GetX()); // T2=(Y1-Z1.Y2).X2 T2.Sub(T1); T2.Norm(); // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 Y1.PMul(Qx); Y1.Neg(); Y1.Norm(); // Y1=-(Y1-Z1.Y2).Xs a = new FP4(X1, T2); // (X1-Z1.X2).Ys | (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 | - (Y1-Z1.Y2).Xs if (ECP.SEXTIC_TWIST == ECP.D_TYPE) { b = new FP4(Y1); c = new FP4(0); } if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { b = new FP4(0); c = new FP4(Y1); c.Times_I(); } A.Add(B); } //System.out.println("Out of line"); return(new FP12(a, b, c)); }
/* 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); }