/* 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(); }
/* 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); }
/* 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(); }
/* 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); }
/* this*=s where s is FP2 */ public void PMul(FP2 s) { a.Mul(s); b.Mul(s); }
/* 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)); }