/* 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); }
/* 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); }
/* test this==0 ? */ public bool iszilch() { reduce(); return(a.iszilch() && b.iszilch()); }