// factor n into a*b using Pollard Rho method // pre-condition: n>1 inline void PollardRho(ZZ& a, ZZ& b, const ZZ& n, const ZZ& bnd=ZZ::zero()) { ZZ_pBak bak; bak.save(); ZZ_p::init(n); ZZ d; ZZ_p x1; random(x1); ZZ_p x2(x1); ZZ end(IsZero(bnd)?5*SqrRoot(SqrRoot(n)):2*SqrRoot(bnd)); for (; !IsZero(end); --end) { x1 = x1*x1 + 1; x2 = x2*x2 + 1; x2 = x2*x2 + 1; GCD(d,n,rep(x2-x1)); if ((d>1)&&(d<n)) { a=d; b=n/d; return; } } // failure a=1; b=n; }
void ECM(ZZ& q, const ZZ& N, long ncurves, long B1, long B2, long D, bool verbose) { // initialize ZZ_p ZZ_pBak bak; bak.save(); ZZ_p::init(N); PrimeSeq seq; for (long i=0; i<ncurves; ++i) { if (verbose) { if (ncurves<NTL_MAX_LONG) std::cout<<"ECM: "<<NumBits(N)<<" bits; " <<i<<"/"<<ncurves<<" curves\r"<<std::flush; else std::cout<<"ECM: "<<NumBits(N)<<" bits; " <<i<<" curves\r"<<std::flush; } // try to find a factor ECM_one_curve(q,seq,B1,B2,D); if (!IsOne(q)) { if (verbose) { std::cout<<"ECM: "<<NumBits(N)<<" bits; " <<(i+1)<<" curves; found "<<q<<" "<<std::endl; } return; } } if (verbose) std::cout<<"ECM: "<<NumBits(N)<<" bits; FAILED! "<<std::endl; set(q); }
void inv(ZZ& d_out, mat_ZZ& x_out, const mat_ZZ& A, long deterministic) { long n = A.NumRows(); if (A.NumCols() != n) Error("solve: nonsquare matrix"); if (n == 0) { set(d_out); x_out.SetDims(0, 0); return; } zz_pBak zbak; zbak.save(); ZZ_pBak Zbak; Zbak.save(); mat_ZZ x(INIT_SIZE, n, n); ZZ d, d1; ZZ d_prod, x_prod; set(d_prod); set(x_prod); long d_instable = 1; long x_instable = 1; long gp_cnt = 0; long check = 0; mat_ZZ y; long i; long bound = 2+DetBound(A); for (i = 0; ; i++) { if ((check || IsZero(d)) && !d_instable) { if (NumBits(d_prod) > bound) { break; } else if (!deterministic && bound > 1000 && NumBits(d_prod) < 0.25*bound) { ZZ P; long plen = 90 + NumBits(max(bound, NumBits(d))); GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p AA; conv(AA, A); ZZ_p dd; determinant(dd, AA); if (CRT(d, d_prod, rep(dd), P)) d_instable = 1; else break; } } zz_p::FFTInit(i); long p = zz_p::modulus(); mat_zz_p AA; conv(AA, A); if (!check) { mat_zz_p xx; zz_p dd; inv(dd, xx, AA); d_instable = CRT(d, d_prod, rep(dd), p); if (!IsZero(dd)) { mul(xx, xx, dd); x_instable = CRT(x, x_prod, xx); } else x_instable = 1; if (!d_instable && !x_instable) { mul(y, x, A); if (IsDiag(y, n, d)) { d1 = d; check = 1; } } } else { zz_p dd; determinant(dd, AA); d_instable = CRT(d, d_prod, rep(dd), p); } } if (check && d1 != d) { mul(x, x, d); ExactDiv(x, d1); } d_out = d; if (check) x_out = x; zbak.restore(); Zbak.restore(); }
void determinant(ZZ& rres, const mat_ZZ& a, long deterministic) { long n = a.NumRows(); if (a.NumCols() != n) Error("determinant: nonsquare matrix"); if (n == 0) { set(rres); return; } zz_pBak zbak; zbak.save(); ZZ_pBak Zbak; Zbak.save(); long instable = 1; long gp_cnt = 0; long bound = 2+DetBound(a); ZZ res, prod; clear(res); set(prod); long i; for (i = 0; ; i++) { if (NumBits(prod) > bound) break; if (!deterministic && !instable && bound > 1000 && NumBits(prod) < 0.25*bound) { ZZ P; long plen = 90 + NumBits(max(bound, NumBits(res))); GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p A; conv(A, a); ZZ_p t; determinant(t, A); if (CRT(res, prod, rep(t), P)) instable = 1; else break; } zz_p::FFTInit(i); long p = zz_p::modulus(); mat_zz_p A; conv(A, a); zz_p t; determinant(t, A); instable = CRT(res, prod, rep(t), p); } rres = res; zbak.restore(); Zbak.restore(); }