BOOL zzn2_sqrt(_MIPD_ zzn2 *u,zzn2 *w) { /* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) where i*i=n */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return FALSE; zzn2_copy(u,w); if (zzn2_iszero(w)) return TRUE; MR_IN(204) if (size(w->b)==0) { if (!nres_sqroot(_MIPP_ w->a,mr_mip->w15)) { nres_negate(_MIPP_ w->a,w->b); zero(w->a); if (mr_mip->qnr==-2) nres_div2(_MIPP_ w->b,w->b); nres_sqroot(_MIPP_ w->b,w->b); } else copy(mr_mip->w15,w->a); MR_OUT return TRUE; } if (mr_mip->qnr==-1 && size(w->a)==0) { nres_div2(_MIPP_ w->b,w->b); if (nres_sqroot(_MIPP_ w->b,mr_mip->w15)) { copy(mr_mip->w15,w->b); copy(w->b,w->a); } else { nres_negate(_MIPP_ w->b,w->b); nres_sqroot(_MIPP_ w->b,w->b); nres_negate(_MIPP_ w->b,w->a); } MR_OUT return TRUE; }
ZZn sqrt(const ZZn& b) {ZZn z; nres_sqroot(b.fn,z.fn); return z;}