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