Пример #1
0
// 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;
}
Пример #2
0
 void main() {
     int cnt = 0;
     set<pair<int, int>> S;
     for (long b = 5; b <= 640; b += 5) {
         for (long t = 1; t <= 11328; t += 1) {
             // if ((59 * b / 5 + t) % 5 != 0) continue;
             for (long h = 41; h <= 3776; h += 41) {
                 long A = 6 * ((59 * b + t * 5) * 41 + 450 * h);
                 long B = (b + t + h) * 41 * 25;
                 long g = GCD(A, B);
                 B /= g, A /= g;
                 if ((59. / 41) * (59. / 41) * B / A > 1.) continue;
                 if (is_sqr(A) && is_sqr(B)) {
                     A = SqrRoot(A), B = SqrRoot(B);
                     if (b * 59 * B % (A * 5) != 0) continue;
                     if (t % A != 0) continue;
                     if (h * 90 * B % (A * 41) != 0) continue;
                     pair<int, int> s = {B, A};
                     if (!S.count(s)) {
                         S.insert(s);
                         ++cnt;
                         print("#{}: b = {}, t = {}, h = {}, m = {}/{}, ans = {}\n", cnt, b, t, h, B * 59, A * 41, B * 59. / (A * 41.));
                     }
                 }
             }
         }
     }
     if (S.count({25, 36}))
         print("good!\n");
 }
Пример #3
0
void SqrRoot(RR& z, const RR& a)
{
   if (sign(a) < 0)
      ArithmeticError("RR: attempt to take square root of negative number");

   if (IsZero(a)) {
      clear(z);
      return;
   }

   RR t;
   ZZ T1, T2;
   long k;

   k = 2*RR::prec - NumBits(a.x) + 1;

   if (k < 0) k = 0;

   if ((a.e - k) & 1) k++;

   LeftShift(T1, a.x, k);
   // since k >= 2*prec - bits(a) + 1, T1 has at least 2*prec+1 bits,           
   // thus T1 >= 2^(2*prec)                                                     

   SqrRoot(t.x, T1); // t.x >= 2^prec thus t.x contains the round bit           
   t.e = (a.e - k)/2;
   sqr(T2, t.x);  

   // T1-T2 is the (lower part of the) sticky bit                               
   normalize(z, t, T2 < T1);
}
Пример #4
0
void Comp3Mod(zz_pX& x1, zz_pX& x2, zz_pX& x3, 
              const zz_pX& g1, const zz_pX& g2, const zz_pX& g3,
              const zz_pX& h, const zz_pXModulus& F)

{
   long m = SqrRoot(g1.rep.length() + g2.rep.length() + g3.rep.length());

   if (m == 0) {
      clear(x1);
      clear(x2);
      clear(x3);
      return;
   }

   zz_pXArgument A;

   build(A, h, F, m);

   zz_pX xx1, xx2, xx3;

   CompMod(xx1, g1, A, F);
   CompMod(xx2, g2, A, F);
   CompMod(xx3, g3, A, F);

   x1 = xx1;
   x2 = xx2;
   x3 = xx3;
}
Пример #5
0
bool ProvePrime(const ZZ& _n) {
  ZZ n(_n);
  if (n<0)
    abs(n,n);
  if (n<=1)
    return 0;

  if (n<=1000000) {
    // n is small so use trial division to check primality
    long ln = to_long(n);
    long end = to_long(SqrRoot(n));
    PrimeSeq s;
    for (long p=s.next(); p<=end; p=s.next())
      if ((ln%p)==0)
	return 0;
    return 1;
  }

  // check small primes
  PrimeSeq s;
  for (long p=s.next(); p<1000; p=s.next())
    if (divide(n,p))
      return 0;

  // obviously, something is missing here!

  return ProbPrime(n);
}
NTL_START_IMPL

static
long CharPolyBound(const mat_ZZ& a)
// This bound is computed via interpolation
// through complex roots of unity.

{
   long n = a.NumRows();
   long i;
   ZZ res, t1, t2;

   set(res);

   for (i = 0; i < n; i++) {
      InnerProduct(t1, a[i], a[i]);
      abs(t2, a[i][i]);
      mul(t2, t2, 2);
      add(t2, t2, 1);
      add(t1, t1, t2);
      if (t1 > 1) {
         SqrRoot(t1, t1);
         add(t1, t1, 1);
      }
      mul(res, res, t1);
   }

   return NumBits(res);
}
Пример #7
0
static
void GenerateBabySteps(GF2EX& h1, const GF2EX& f, const GF2EX& h, long k,
                       long verbose)

{
   double t;

   if (verbose) { cerr << "generating baby steps..."; t = GetTime(); }

   GF2EXModulus F;
   build(F, f);

   GF2EXArgument H;

#if 0
   double n2 = sqrt(double(F.n));
   double n4 = sqrt(n2);
   double n34 = n2*n4;
   long sz = long(ceil(n34/sqrt(sqrt(2.0))));
#else
   long sz = 2*SqrRoot(F.n);
#endif

   build(H, h, F, sz);


   h1 = h;

   long i;

   long HexOutput = GF2X::HexOutput;
   GF2X::HexOutput = 1;

   if (!use_files) {
      BabyStepFile.kill();
      BabyStepFile.SetLength(k-1);
   }

   for (i = 1; i <= k-1; i++) {
      if (use_files) {
         ofstream s;
         OpenWrite(s, FileName(GF2EX_stem, "baby", i));
         s << h1 << "\n";
         s.close();
      }
      else
         BabyStepFile(i) = h1;

      CompMod(h1, h1, H, F);
      if (verbose) cerr << "+";
   }

   if (verbose)
      cerr << (GetTime()-t) << "\n";

   GF2X::HexOutput = HexOutput;
}
Пример #8
0
long UseComposeFrobenius(long d, long n)
{
   long i;
   i = 1;
   while (i <= d) i = i << 1;
   i = i >> 1;

   i = i >> 1;
   long m = 1;

   long dz;

   if (n == 2) {
      dz = 1;
   }
   else {
      while (i) {
         long m1 = 2*m;
         if (i & d) m1++;
   
         if (m1 >= NTL_BITS_PER_LONG-1 || (1L << m1) >= n) break;
   
         m = m1;
         i = i >> 1;
      }

      dz = 1L << m;
   }

   long rootn = SqrRoot(n);
   long cnt = 0;

   if (i) {
      cnt += SqrRoot(dz+1);
      i = i >> 1;
   }

   while (i) {
      cnt += rootn;
      i = i >> 1;
   }

   return 4*cnt <= d;
}
Пример #9
0
void SqrRootPrec(RR& x, const RR& a, long p)
{
   if (p < 1 || NTL_OVERFLOW(p, 1, 0))
      Error("SqrRootPrec: bad precsion");

   long old_p = RR::prec;
   RR::prec = p;
   SqrRoot(x, a);
   RR::prec = old_p;
}
Пример #10
0
// generate only matrices of the form s(X^{g^i})->s(X), but not all of them.
// For a generator g whose order is larger than bound, generate only enough
// matrices for the giant-step/baby-step procedures (2*sqrt(ord(g))of them).
void addSome1DMatrices(FHESecKey& sKey, long bound, long keyID)
{
  const FHEcontext &context = sKey.getContext();
  long m = context.zMStar.getM();

  // key-switching matrices for the automorphisms
  for (long i = 0; i < (long)context.zMStar.numOfGens(); i++) {
    // For generators of small order, add all the powers
    if (bound >= (long)context.zMStar.OrderOf(i))
      for (long j = 1; j < (long)context.zMStar.OrderOf(i); j++) {
	long val = PowerMod(context.zMStar.ZmStarGen(i), j, m); // val = g^j
	// From s(X^val) to s(X)
	sKey.GenKeySWmatrix(1, val, keyID, keyID);
	if (!context.zMStar.SameOrd(i))
	  // also from s(X^{1/val}) to s(X)
	  sKey.GenKeySWmatrix(1, InvMod(val,m), keyID, keyID);
      }
    else { // For generators of large order, add only some of the powers
      long num = SqrRoot(context.zMStar.OrderOf(i)); // floor(ord^{1/2})
      if (num*num < (long) context.zMStar.OrderOf(i)) num++; // ceil(ord^{1/2})

      // VJS: the above two lines replaces the following inexact calculation
      // with an exact calculation
      // long num = ceil(sqrt((double)context.zMStar.OrderOf(i)));

      for (long j=1; j <= num; j++) { // Add matrices for g^j and g^{j*num}
	long val1 = PowerMod(context.zMStar.ZmStarGen(i), j, m);  // g^j
	long val2 = PowerMod(context.zMStar.ZmStarGen(i),num*j,m);// g^{j*num}
	if (j < num) {
	  sKey.GenKeySWmatrix(1, val1, keyID, keyID);
	  sKey.GenKeySWmatrix(1, val2, keyID, keyID);
	}
	if (!context.zMStar.SameOrd(i)) {
	  //	  sKey.GenKeySWmatrix(1, InvMod(val1,m), keyID, keyID);
	  sKey.GenKeySWmatrix(1, InvMod(val2,m), keyID, keyID);
	}
      }

      // VJS: experimantal feature...because the replication code
      // uses rotations by -1, -2, -4, -8, we add a few
      // of these as well...only the small ones are important,
      // and we only need them if SameOrd(i)...
      // Note: we do indeed get a nontrivial speed-up

      if (context.zMStar.SameOrd(i)) {
        for (long k = 1; k <= num; k = 2*k) {
          long j = context.zMStar.OrderOf(i) - k;
          long val = PowerMod(context.zMStar.ZmStarGen(i), j, m); // val = g^j
          sKey.GenKeySWmatrix(1, val, keyID, keyID);
        }
      }
    }
  }
  sKey.setKeySwitchMap(); // re-compute the key-switching map
}
Пример #11
0
void SqrRootPrec(RR& x, const RR& a, long p)
{
   if (p < 1)
      LogicError("SqrRootPrec: bad precsion");
   if (NTL_OVERFLOW(p, 1, 0))
      ResourceError("SqrRootPrec: bad precsion");

   RRPush push;
   RR::prec = p;
   SqrRoot(x, a);
}
Пример #12
0
NTL_CLIENT
#include "FHE.h"

long KSGiantStepSize(long D)
{
  //OLD: assert(D > 0);
  helib::assertTrue<helib::InvalidArgument>(D > 0l, "Step size must be positive");
  long g = SqrRoot(D);
  if (g*g < D) g++;  // g = ceiling(sqrt(D))
  return g;
}
static
void GenerateBabySteps(ZZ_pEX& h1, const ZZ_pEX& f, const ZZ_pEX& h, long k,
                       FileList& flist, long verbose)

{
   double t;

   if (verbose) { cerr << "generating baby steps..."; t = GetTime(); }

   ZZ_pEXModulus F;
   build(F, f);

   ZZ_pEXArgument H;

#if 0
   double n2 = sqrt(double(F.n));
   double n4 = sqrt(n2);
   double n34 = n2*n4;
   long sz = long(ceil(n34/sqrt(sqrt(2.0))));
#else
   long sz = 2*SqrRoot(F.n);
#endif

   build(H, h, F, sz);


   h1 = h;

   long i;

   if (!use_files) {
      (*BabyStepFile).SetLength(k-1);
   }

   for (i = 1; i <= k-1; i++) {
      if (use_files) {
         ofstream s;
         OpenWrite(s, FileName("baby", i), flist);
         s << h1 << "\n";
         CloseWrite(s);
      }
      else
         (*BabyStepFile)(i) = h1;

      CompMod(h1, h1, H, F);
      if (verbose) cerr << "+";
   }

   if (verbose)
      cerr << (GetTime()-t) << "\n";

}
Пример #14
0
static
void GenerateGiantSteps(const ZZ_pX& f, const ZZ_pX& h, long l, long verbose)
{

   double t;

   if (verbose) { cerr << "generating giant steps..."; t = GetTime(); }

   ZZ_pXModulus F;
   build(F, f);

   ZZ_pXArgument H;
   build(H, h, F, 2*SqrRoot(F.n));

   ZZ_pX h1;

   h1 = h;

   long i;

   if (!use_files) {
      GiantStepFile.kill();
      GiantStepFile.SetLength(l);
   }

   for (i = 1; i <= l-1; i++) {
      if (use_files) {
         ofstream s;
         OpenWrite(s, FileName(ZZ_pX_stem, "giant", i));
         s << h1 << "\n";
         s.close();
      }
      else
         GiantStepFile(i) = h1;

      CompMod(h1, h1, H, F);
      if (verbose) cerr << "+";
   }

   if (use_files) {
      ofstream s;
      OpenWrite(s, FileName(ZZ_pX_stem, "giant", i));
      s << h1 << "\n";
      s.close();
   }
   else
      GiantStepFile(i) = h1;

   if (verbose)
      cerr << (GetTime()-t) << "\n";
}
Пример #15
0
static
void hadamard(ZZ& num_bound, ZZ& den_bound,
              const mat_ZZ& A, const vec_ZZ& b)
{
    long n = A.NumRows();

    if (n == 0) Error("internal error: hadamard with n = 0");

    ZZ b_len, min_A_len, prod, t1;

    InnerProduct(min_A_len, A[0], A[0]);

    prod = min_A_len;

    long i;
    for (i = 1; i < n; i++) {
        InnerProduct(t1, A[i], A[i]);
        if (t1 < min_A_len)
            min_A_len = t1;
        mul(prod, prod, t1);
    }

    if (min_A_len == 0) {
        num_bound = 0;
        den_bound = 0;
        return;
    }

    InnerProduct(b_len, b, b);

    div(t1, prod, min_A_len);
    mul(t1, t1, b_len);

    SqrRoot(num_bound, t1);
    SqrRoot(den_bound, prod);
}
Пример #16
0
void CompMod(zz_pX& x, const zz_pX& g, const zz_pX& h, const zz_pXModulus& F)
   // x = g(h) mod f
{
   long m = SqrRoot(g.rep.length());

   if (m == 0) {
      clear(x);
      return;
   }

   zz_pXArgument A;

   build(A, h, F, m);

   CompMod(x, g, A, F);
}
Пример #17
0
void ProjectPowers(vec_zz_p& x, const vec_zz_p& a, long k,
                   const zz_pX& h, const zz_pXModulus& F)

{
   if (a.length() > F.n || k < 0) Error("ProjectPowers: bad args");

   if (k == 0) {
      x.SetLength(0);
      return;
   }

   long m = SqrRoot(k);

   zz_pXArgument H;

   build(H, h, F, m);
   ProjectPowers(x, a, k, H, F);
}
Пример #18
0
static
long DetBound(const mat_ZZ& a)
{
    long n = a.NumRows();
    long i;
    ZZ res, t1;

    set(res);

    for (i = 0; i < n; i++) {
        InnerProduct(t1, a[i], a[i]);
        if (t1 > 1) {
            SqrRoot(t1, t1);
            add(t1, t1, 1);
        }
        mul(res, res, t1);
    }

    return NumBits(res);
}
Пример #19
0
static
void GenerateBabySteps(ZZ_pX& h1, const ZZ_pX& f, const ZZ_pX& h, long k,
                       FileList& flist, long verbose)

{
   double t;

   if (verbose) { cerr << "generating baby steps..."; t = GetTime(); }

   ZZ_pXModulus F;
   build(F, f);

   ZZ_pXArgument H;
   build(H, h, F, 2*SqrRoot(F.n));


   h1 = h;

   long i;

   if (!use_files) {
      (*BabyStepFile).SetLength(k-1);
   }

   for (i = 1; i <= k-1; i++) {
      if (use_files) {
         ofstream s;
         OpenWrite(s, FileName("baby", i), flist);
         s << h1 << "\n";
         CloseWrite(s); 
      }
      else
         (*BabyStepFile)(i) = h1;

      CompMod(h1, h1, H, F);
      if (verbose) cerr << "+";
   }

   if (verbose)
      cerr << (GetTime()-t) << "\n";
}
Пример #20
0
// ECM primitive
void ECM(ZZ& q, const ZZ& n, const ZZ& _bnd, double failure_prob,
	 bool verbose) {
  ZZ bnd;
  SqrRoot(bnd,n);
  if (_bnd>0 && _bnd<bnd)
    bnd=_bnd;

  long B1,B2,D;
  double prob;
  ECM_parameters(B1,B2,prob,D,NumBits(bnd),NumBits(n));
  if (verbose)
    std::cout<<"ECM: bnd="<<NumBits(bnd)<<"bits  B1="<<B1<<"  B2="<<B2
             <<"  D="<<D<<"  prob="<<prob<<std::endl;
  
  if (failure_prob<=0) {
    // run "forever"
    if (verbose)
      std::cout<<"ECM: expected ncurves="<<(1/prob)<<std::endl;
    ECM(q,n,NTL_MAX_LONG,B1,B2,D,verbose); 
  }
  else if (failure_prob>=1) {
    // run on one curve
    ECM(q,n,1,B1,B2,D,verbose); 
  }
  else {
    // run just the right number of times
    // failure_prob = (1-prob)^ncurves;
    double ncurves_d;
    if (prob<0.1)
      ncurves_d = to_double(log(failure_prob)/log1p(to_RR(-prob)));
    else
      ncurves_d = log(failure_prob)/log(1-prob);
    long ncurves = ncurves_d<=1 ? 1 :
      (ncurves_d>=NTL_MAX_LONG ? NTL_MAX_LONG : (long)ncurves_d);
    if (verbose)
      std::cout<<"ECM: good_prob="<<prob<<"  failure_prob="<<failure_prob
               <<"  ncurves="<<ncurves<<std::endl;
    ECM(q,n,ncurves,B1,B2,D,verbose); 
  }
}
Пример #21
0
void Comp2Mod(ZZ_pX& x1, ZZ_pX& x2, const ZZ_pX& g1, const ZZ_pX& g2,
              const ZZ_pX& h, const ZZ_pXModulus& F)

{
   long m = SqrRoot(g1.rep.length() + g2.rep.length());

   if (m == 0) {
      clear(x1);
      clear(x2);
      return;
   }

   ZZ_pXArgument A;

   build(A, h, F, m);

   ZZ_pX xx1, xx2;

   CompMod(xx1, g1, A, F);
   CompMod(xx2, g2, A, F);

   x1 = xx1;
   x2 = xx2;
}
Пример #22
0
long IsFFTPrime(long n, long& w)
{
   long  m, x, y, z;
   long j, k;


   if (n <= 1 || n >= NTL_SP_BOUND) return 0;

   if (n % 2 == 0) return 0;

   if (n % 3 == 0) return 0;

   if (n % 5 == 0) return 0;

   if (n % 7 == 0) return 0;
   
   m = n - 1;
   k = 0;
   while ((m & 1) == 0) {
      m = m >> 1;
      k++;
   }

   for (;;) {
      x = RandomBnd(n);

      if (x == 0) continue;
      z = PowerMod(x, m, n);
      if (z == 1) continue;

      x = z;
      j = 0;
      do {
         y = z;
         z = MulMod(y, y, n);
         j++;
      } while (j != k && z != 1);

      if (z != 1 || y !=  n-1) return 0;

      if (j == k) 
         break;
   }

   /* x^{2^k} = 1 mod n, x^{2^{k-1}} = -1 mod n */

   long TrialBound;

   TrialBound = m >> k;
   if (TrialBound > 0) {
      if (!ProbPrime(n, 5)) return 0;
   
      /* we have to do trial division by special numbers */
   
      TrialBound = SqrRoot(TrialBound);
   
      long a, b;
   
      for (a = 1; a <= TrialBound; a++) {
         b = (a << k) + 1;
         if (n % b == 0) return 0; 
      }
   }

   /* n is an FFT prime */

   for (j = NTL_FFTMaxRoot; j < k; j++)
      x = MulMod(x, x, n);

   w = x;
   return 1;
}
Пример #23
0
    void main() {
        R = SqrRoot(m);
        int cnt = 0;
        for (long i = 1; m / i > R; ++i)
            basis[++cnt] = m / i;
        for (int i = R; i; --i)
            basis[++cnt] = i;
        // for (int i = 1; i <= cnt; ++i) {
        //     if (get_index(basis[i]) != i)
        //         print("!!! {} {}\n", get_index(basis[i]), i);
        // }

        for (int i = 1; i <= cnt; ++i) {
            num_primes[i] = basis[i] - 1;
        }
        // for (int i = 1; i < cnt; ++i) {
        //     for (int v = basis[i + 1] + 1; v <= basis[i]; ++v)
        //         if (v > R && ProbPrime(v))
        //             f[basis[i]] += 2;
        // }
        // f[1] = 1;
        // for (int i = cnt - 1; i; --i) {
        //     f[basis[i]] += f[basis[i + 1]];
        //     // print("init {} = {}\n", basis[i], f[basis[i]]);
        // }

        // long ans = 0;
        // for (int i = 1; i <= m; ++i) {
        //     ans += m / i;
        // }
        // print("bf = {}\n", ans);
        for (long x = 2; x <= R; ++x) {
            if (ProbPrime(x)) {
                print("current = {}\n", x);
                for (int i = 1; i <= cnt; ++i) {
                    long y = basis[i];
                    if (x * x > y)
                        break;
                    auto a = num_primes[get_index(y / x)];
                    auto b = num_primes[get_index(x - 1)];
                    num_primes[i] -= a - b;
                }
            }
        }
        for (int i = 1; i <= cnt; ++i) {
            num_primes[i] %= MOD;
            // print("{} {}\n", basis[i], num_primes[i]);
        }
        for (int i = 1; i <= cnt; ++i) {
            f[i] = 1;
            // if (basis[i] >= R) {
            //     f[i] += 2 * (num_primes[get_index(basis[i])] - num_primes[R]);
            // }
            // print("init {} {}\n", basis[i], f[i]);
        }

        for (long p = R; p; --p) {
            if (ProbPrime(p)) {
                print("current = {}\n", p);

                int t = p > n ? 0 : get_power(p, n);
                for (int e = 0; e <= 60; ++e)
                    g[e] = (e + 1) * (t + 1) + t * (t + 1) / 2;

                for (int i = 1; i <= cnt; ++i) {
                    long y = basis[i];
                    if (t == 0 && p * p > y)
                        break;
                    long v = 0; // 2 * (num_primes[get_index(y)] - num_primes[p]);
                    for (int e = 0; y; ++e) {
                        v += real_f(y, p) * g[e] % MOD;
                        y /= p;
                    }
                    if (basis[i] >= p)
                        v -= 2 * (num_primes[i] - num_primes[get_index(p)] + 1) % MOD;
                    f[i] = (v + MOD) % MOD;
                    // print("update {} = {}\n", basis[i], v);
                }
            }
        }
        print("ans = {}\n", real_f(m, 1));
    }
static
void GenerateGiantSteps(const ZZ_pEX& f, const ZZ_pEX& h, long l, long verbose)
{

   double t;

   if (verbose) { cerr << "generating giant steps..."; t = GetTime(); }

   ZZ_pEXModulus F;
   build(F, f);

   ZZ_pEXArgument H;

#if 0
   double n2 = sqrt(double(F.n));
   double n4 = sqrt(n2);
   double n34 = n2*n4;
   long sz = long(ceil(n34/sqrt(sqrt(2.0))));
#else
   long sz = 2*SqrRoot(F.n);
#endif

   build(H, h, F, sz);

   ZZ_pEX h1;

   h1 = h;

   long i;

   if (!use_files) {
      GiantStepFile.kill();
      GiantStepFile.SetLength(l);
   }

   for (i = 1; i <= l-1; i++) {
      if (use_files) {
         ofstream s;
         OpenWrite(s, FileName(ZZ_pEX_stem, "giant", i));
         s << h1 << "\n";
         s.close();
      }
      else
        GiantStepFile(i) = h1;

      CompMod(h1, h1, H, F);
      if (verbose) cerr << "+";
   }

   if (use_files) {
      ofstream s;
      OpenWrite(s, FileName(ZZ_pEX_stem, "giant", i));
      s << h1 << "\n";
      s.close();
   }
   else
      GiantStepFile(i) = h1;

   if (verbose)
      cerr << (GetTime()-t) << "\n";

}
Пример #25
0
// general purpose factoring method
void factor(vec_pair_ZZ_long& factors, const ZZ& _n,
            const ZZ& bnd, double failure_prob, 
	    bool verbose) {
  ZZ n(_n);
  if (n<=1) {
    abs(n,n);
    if (n<=1) {
      factors.SetLength(0);
      return;
    }
  }

  // upper bound on size of smallest prime factor
  ZZ upper_bound;
  SqrRoot(upper_bound,n);
  if (bnd>0 && bnd<upper_bound)
    upper_bound=bnd;

  // figure out appropriate lower_bound for trial division
  long B1,B2,D;
  double prob;
  ECM_parameters(B1,B2,prob,D,NumBits(upper_bound),NumBits(n));
  ZZ lower_bound;
  conv(lower_bound,max(B2,1<<14));
  if (lower_bound>upper_bound)
    lower_bound=upper_bound;
  
  // start factoring with trial division
  TrialDivision(factors,n,n,to_long(lower_bound));
  if (IsOne(n))
    return;
  if (upper_bound<=lower_bound || ProbPrime_notd(n)) {
    addFactor(factors,n);
    return;
  }

  /* n is composite and smallest prime factor is assumed to be such that
   *     lower_bound < factor <= upper_bound
   *
   * Ramp-up to searching for factors of size upper_bound.  This is a good
   * idea in cases where we have no idea what size factors N might have,
   * but we don't want to spend too much time doing this.
   */
  
  for(lower_bound<<=4; lower_bound<upper_bound; lower_bound<<=4) {
    ZZ q;
    ECM(q,n,lower_bound,1,verbose); // one curve only
    if (!IsOne(q)) {
      div(n,n,q);
      if (n<q) swap(n,q);
      // q is small factor, n is large factor
      if (ProbPrime_notd(q))
	addFactor(factors,q);
      else
	factor_r(factors,q,bnd,failure_prob,verbose);
      if (ProbPrime_notd(n)) {
	addFactor(factors,n);
	return;
      }
      // new upper_bound
      SqrRoot(upper_bound,n);
      if (bnd>0 && bnd<upper_bound)
	upper_bound=bnd;
    }
  }

  // search for factors of size bnd
  factor_r(factors,n,bnd,failure_prob,verbose);
}
Пример #26
0
void DDF(vec_pair_ZZ_pX_long& factors, const ZZ_pX& ff, const ZZ_pX& hh, 
         long verbose)
{
   ZZ_pX f = ff;
   ZZ_pX h = hh;

   if (!IsOne(LeadCoeff(f)))
      Error("DDF: bad args");

   factors.SetLength(0);

   if (deg(f) == 0)
      return;

   if (deg(f) == 1) {
      AddFactor(factors, f, 1, verbose);
      return;
   }

   long CompTableSize = 2*SqrRoot(deg(f)); 

   long GCDTableSize = ZZ_pX_BlockingFactor;

   ZZ_pXModulus F;
   build(F, f);

   ZZ_pXArgument H;

   build(H, h, F, min(CompTableSize, deg(f)));

   long i, d, limit, old_n;
   ZZ_pX g, X;


   vec_ZZ_pX tbl(INIT_SIZE, GCDTableSize);

   SetX(X);

   i = 0;
   g = h;
   d = 1;
   limit = GCDTableSize;


   while (2*d <= deg(f)) {

      old_n = deg(f);
      sub(tbl[i], g, X);
      i++;
      if (i == limit) {
         ProcessTable(f, factors, F, i, tbl, d, verbose);
         i = 0;
      }

      d = d + 1;
      if (2*d <= deg(f)) {
         // we need to go further

         if (deg(f) < old_n) {
            // f has changed 

            build(F, f);
            rem(h, h, f);
            rem(g, g, f);
            build(H, h, F, min(CompTableSize, deg(f)));
         }

         CompMod(g, g, H, F);
      }
   }

   ProcessTable(f, factors, F, i, tbl, d-1, verbose);

   if (!IsOne(f)) AddFactor(factors, f, deg(f), verbose);
}
Пример #27
0
 bool is_sqr(int x) {
     int t = SqrRoot(x);
     return x == t * t;
 }
long IterIrredTest(const ZZ_pEX& f)
{
   if (deg(f) <= 0) return 0;
   if (deg(f) == 1) return 1;

   ZZ_pEXModulus F;

   build(F, f);
   
   ZZ_pEX h;

   FrobeniusMap(h, F);

   long CompTableSize = 2*SqrRoot(deg(f));

   ZZ_pEXArgument H;

   build(H, h, F, CompTableSize);

   long i, d, limit, limit_sqr;
   ZZ_pEX g, X, t, prod;


   SetX(X);

   i = 0;
   g = h;
   d = 1;
   limit = 2;
   limit_sqr = limit*limit;

   set(prod);


   while (2*d <= deg(f)) {
      sub(t, g, X);
      MulMod(prod, prod, t, F);
      i++;
      if (i == limit_sqr) {
         GCD(t, f, prod);
         if (!IsOne(t)) return 0;

         set(prod);
         limit++;
         limit_sqr = limit*limit;
         i = 0;
      }

      d = d + 1;
      if (2*d <= deg(f)) {
         CompMod(g, g, H, F);
      }
   }

   if (i > 0) {
      GCD(t, f, prod);
      if (!IsOne(t)) return 0;
   }

   return 1;
}