예제 #1
0
파일: ZZFactoring.cpp 프로젝트: onechip/ecm
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);
}
예제 #2
0
long PrimeTest(const ZZ& n, long t)
{
   if (n <= 1) return 0;

   PrimeSeq s;  
   long p;

   p = s.next();
   while (p && p < 2000) {
      if ((n % p) == 0) return (n == p);
      p = s.next();  
   }

   ZZ x;
   long i;

   for (i = 0; i < t; i++)
   {
      x = RandomBnd(n); 

      if (witness(n, x)) 
         return 0;
   }

   return 1;
}
예제 #3
0
bool RSA::isPrime(const ZZ& prime, long t)
{

  if (prime <= 1) 
		return false;

	// First, just try out the division by the first 2000 primes
	// Source: http://www.shoup.net/ntl/doc/tour-ex1.html
	PrimeSeq primeSequence; 
	long tempPrime;

	tempPrime = primeSequence.next();
	while(tempPrime && tempPrime < 2000) 
	{
		if((prime % tempPrime) == 0) 
			return prime == tempPrime;
		tempPrime = primeSequence.next();
	}

	// Not it's time for real prime testing
	ZZ x;
	long i;

	for(i = 0; i < t; i++) 
	{
		x = bigRandom(this->numberOfBits / 4); // random number between 0 and n-1

		if (MRTest(prime, x)) 
			return false;
	}

	return true;
}
예제 #4
0
파일: ZZFactoring.cpp 프로젝트: onechip/ecm
// trial division primitive
void TrialDivision(vec_pair_ZZ_long& factors, ZZ& q, const ZZ& n, long bnd) {
  factors.SetLength(0);

  if (&q!=&n) q=n;
  if (bnd==0) {
    bnd=10000;  // should probably be higher
  }

  PrimeSeq s;
  ZZ d;
  for (long p=s.next(); (p>0 && p<=bnd); p=s.next()) {
    if (DivRem(d,q,p)==0) {
      long e=1;
      q=d;
      while (DivRem(d,q,p)==0) {
	++e;
	q=d;
      }
      addFactor(factors,to_ZZ(p),e);
      if (IsOne(q))
	return;
    }
    if (d<=p) {
      // q must be prime
      addFactor(factors,q);
      set(q);
      return;
    }
  }
}
예제 #5
0
int main() {
    PrimeSeq gen;
    for (int i = 1; i < P; ++i)
        primes[i] = gen.next();
    print("{}\n", gen.next());

    dfs(1, 1, 1, ZZ(1));
    print("ans = {}\n", ans);

    return 0;
}
예제 #6
0
파일: ecpp-test.cpp 프로젝트: onechip/ecpp
// q is largest prime factor of m
// return true if q>=threshold and prime
bool check_for_factor(ZZ& q, const ZZ& m, const ZZ& threshold) {
  static const long bound=100000;

  // m must be composite
  if (ProbPrime(m))
    return false;

  // remove small factors
  q=m;
  ZZ t;
  PrimeSeq s;
  for (long p=s.next(); p<bound; p=s.next())
    while (DivRem(t,q,p)==0)
      q=t;

  if (q<threshold)
    return false;

  // lower bound on size of smallest factor
  // we are assuming that ECM finds factors smallest first (more or less)
  ZZ small_factor;
  conv(small_factor,bound);

  do {
    if (ProbPrime(q))
      return true;

    // q is composite and has a factor greater than small_factor,
    // thus it must be at least threshold*small_factor to have a 
    // large factor >threshold
    if (q<threshold*small_factor)
      return false;

    // attempt to factor with ECM
    // we are looking for factor such that
    //    small_factor < factor < q/threshold
    ECM(t,q,to_ZZ(NTL_MAX_LONG),0.5,true);

    if (IsOne(t))
      return false;

    if (t<threshold) {
      // new lower bound on remaining factors
      if (small_factor<t)
	small_factor=t;
      q/=t;
    }
    else {
      // this will be rare, but we should update small_factor anyway
      q=t;
    }

  } while (true);
}
예제 #7
0
 void main() {
     PrimeSeq gen;
     for (int u; (u = gen.next()) < n; )
         pi[u] = 1;
     for (int i = 1; i <= n; ++i) {
         pi[i] += pi[i - 1];
         if (i % 1000000 == 0) {
             print("current = {}\n", i);
         }
         for (int w = i, cnt = 0; w; w = pi[w]) {
             cnt += pi[w] == pi[w - 1];
             if (w != i) {
                 if (cnt == 100) {
                     print("XXX\n");
                     return;
                 }
                 P[cnt] += 1;
             }
         }
     }
     long ans = 1;
     for (int i = 0; i <= 100; ++i) {
         if (P[i] == 0) {
             break;
         }
         ans = ans * (P[i] % MOD) % MOD;
     }
     print("ans = {}\n", ans);
 }
예제 #8
0
void factorize(Vec< Pair<long, long> > &factors, long N)
{
  factors.SetLength(0);

  if (N < 2) return;

  PrimeSeq s;
  long n = N;
  while (n > 1) {
    if (ProbPrime(n)) {
      append(factors, cons(n, 1L));
      return;
    }

    long p = s.next();
    if ((n % p) == 0) {
      long e = 1;
      n = n/p;
      while ((n % p) == 0) {
        n = n/p;
        e++;
      }
      append(factors, cons(p, e));
    }
  }
}
예제 #9
0
파일: ZZFactoring.cpp 프로젝트: onechip/ecm
// returns a non-trivial factor q of ZZ_p::modulus(), or 1 otherwise
void ECM_stage_one(ZZ& q, EC_p& Q, PrimeSeq& seq, long bound) {
  long sbound = (long)sqrt((double)bound);
  seq.reset(0);
  long p = seq.next();
  for (; p<=sbound; p=seq.next()) {
    long pp,t=p;
    do { pp=t; t*=p; } while (t>pp && t<=bound); // we might overflow t here
    mul(Q,Q,pp);
  }
  for (; p<=bound; p=seq.next())
    mul(Q,Q,p);
  if (!IsZero(Q))
    GCD(q,ZZ_p::modulus(),rep(Q.Z));
  else
    set(q);
}
예제 #10
0
파일: aks.cpp 프로젝트: maximusprimate/aks
int step0(ZZ n){

    long p;

    PrimeSeq s;
    
    p = s.next();  
    while (p && p < 2000) {
        if ((n % p) == 0){
            cout << p << " divides " << n << '\n';
            return (1 + (n == p)); // 1: composite
        }                          // 2: prime
        p = s.next();              
    }
    return 0; // 0: continue
}
예제 #11
0
// Returns a list of prime factors and their multiplicity, 
// N = \prod_i factors[i].first^{factors[i].second}
void factorize(Vec< Pair<long, long> > &factors, long N)
{
  factors.SetLength(0);

  if (N < 2) return;

  PrimeSeq s;
  long n = N;
  while (n > 1) {
    if (ProbPrime(n)) { // n itself is a prime, add (n,1) to the list
      append(factors, cons(n, 1L));
      return;
    }

    long p = s.next();
    if ((n % p) == 0) { // p divides n, find its multiplicity
      long e = 1;
      n = n/p;
      while ((n % p) == 0) {
        n = n/p;
        e++;
      }
      append(factors, cons(p, e)); // add (p,e) to the list
    }
  }
}
예제 #12
0
template<class zp,class zz> void FindPrimRootT(zp &root, unsigned long e)
{
  zz qm1 = zp::modulus()-1;

  assert(qm1 % e == 0);
  
  vector<long> facts;
  factorize(facts,e); // factorization of e

  root = 1;

  for (unsigned long i = 0; i < facts.size(); i++) {
    long p = facts[i];
    long pp = p;
    long ee = e/p;
    while (ee % p == 0) {
      ee = ee/p;
      pp = pp*p;
    }
    // so now we have e = pp * ee, where pp is 
    // the power of p that divides e.
    // Our goal is to find an element of order pp

    PrimeSeq s;
    long q;
    zp qq, qq1;
    long iter = 0;
    do {
      iter++;
      if (iter > 1000000) 
        Error("FindPrimitiveRoot: possible infinite loop?");
      q = s.next();
      conv(qq, q);
      power(qq1, qq, qm1/p);
    } while (qq1 == 1);
    power(qq1, qq, qm1/pp); // qq1 has order pp

    mul(root, root, qq1);
  }

  // independent check that we have an e-th root of unity 
  {
    zp s;

    power(s, root, e);
    if (s != 1) Error("FindPrimitiveRoot: internal error (1)");

    // check that s^{e/p} != 1 for any prime divisor p of e
    for (unsigned long i=0; i<facts.size(); i++) {
      long e2 = e/facts[i];
      power(s, root, e2);   // s = root^{e/p}
      if (s == 1) 
        Error("FindPrimitiveRoot: internal error (2)");
    }
  }
}
예제 #13
0
/* Compute Phi(N) */
long phi_N(long N)
{
  long phiN=1,p,e;
  PrimeSeq s;
  while (N!=1)
    { p=s.next();
      e=0;
      while ((N%p)==0) { N=N/p; e++; }
      if (e!=0)
        { phiN=phiN*(p-1)*power_long(p,e-1); }
    }
  return phiN;
}
예제 #14
0
파일: ecpp-test.cpp 프로젝트: onechip/ecpp
bool ProvePrime(const ZZ& N, vec_vec_ZZ& certs) {
  certs.SetLength(0);
  long i=0;
  ZZ num(N);
  HCP_generate HCP;
  while (NumBits(num)>30) {
    certs.SetLength(i+1);
    if (!ProvePrime_Atkin(num,certs[i],HCP))
      return false;
    num=certs[i][1];
    ++i;
  }
  // prove small prime by trial division
  long n,limit;
  conv(limit,SqrRoot(num));
  conv(n,num);
  PrimeSeq s;
  for (long p=s.next(); p<=limit; p=s.next())
    if (n%p==0)
      return false;
  return true;
}
예제 #15
0
int main(){
        long n = 183783600;
        long b = 18;
        long rootn=SqrRoot(n);
        long p;
        PrimeSeq s;
        vector<long> values;
        vector<long> logV;
        for(long m=n+1;m<1.66*n;m++){
                values.push_back(m);
                logV.push_back(log(m));
        }
                s.reset(b);
                p=s.next();
                int temp=log(p);
                while(p<rootn){
        for(int i=0;i<logV.size();i++){
                        long t=pow(10,(logV[i]/temp));
                        if(ceil(t)-t<0.05 || t-floor(t)<0.05){
//                        cout<<"here at "<<i<<endl;
                                values[i]=0;
                                
                                break;
                        }
                }
                        p=s.next();
        }
        int y=0;
        cout<<"arr=[";
        for(int i=0;i<values.size();++i){
                if(values[i]!=0)cout<<values[i]<<",";
//                if(temp[i]!=0)cout<<temp[i]<<endl;
        }
        cout<<"0]"<<endl;
        cout<<"ND = numdiv("<<n<<"); nd = 0; i = 1; while( nd<=ND, nd = numdiv(arr[i]); i = i+1); print(arr[i-1])"<<endl;

        return 0;
}
예제 #16
0
/* Compute mobius function (naive method as n is small) */
long mobius(long n)
{
  long p,e,arity=0;
  PrimeSeq s;
  while (n!=1)
    { p=s.next();
      e=0;
      while ((n%p==0)) { n=n/p; e++; }
      if (e>1) { return 0; }
      if (e!=0) { arity^=1; }
    }     
  if (arity==0) { return 1; }
  return -1;
}
예제 #17
0
    void main() {
        PrimeSeq gen;
        for (int u; u = gen.next(), u <= LMT; )
            ++cnt[coef(LMT, u)];
        for (int i = 0; i <= 20; ++i)
            print("{} ", cnt[i]);
        print("\n");

        for (int i = 0; i < NUM_PRIMES; ++i)
            for (int j = 0; j <= i; ++j)
                cb[i][j] = j ? (cb[i - 1][j - 1] + cb[i - 1][j]) % MOD : 1;
        ans = 0;
        dfs(16, 1, 1);
        print("ans = {}\n", ans % MOD);
    }
예제 #18
0
파일: aks.cpp 프로젝트: maximusprimate/aks
ZZ phi(long x){

    ZZ n, ph,p; ph = 1;
    n = 0; n = n + x; // promoting x to type ZZ

    int k;

    for(PrimeSeq s; n>1; ){
        p = s.next();
        k = 0;
        while(n%p == 0){
            k++; n/=p;
        }
        if(k>0)
        ph *= power(p,k-1)*(p-1);
    }
    return ph;
}
예제 #19
0
/* Find a primitive root modulo N */
long primroot(long N,long phiN)
{
  long g=2,p;
  PrimeSeq s;
  bool flag=false;

  while (flag==false)
    { flag=true;
      s.reset(1);
      do
        { p=s.next();
          if ((phiN%p)==0)
            { if (PowerMod(g,phiN/p,N)==1)
                { flag=false; }
            }
        }
      while (p<phiN && flag);
      if (flag==false) { g++; }
    }
  return g;
}
예제 #20
0
    void main() {
        PrimeSeq gen;
        for (int i = 1; i <= n; ++i)
            S[i] = PowerMod(gen.next() % MOD, i, MOD);
        for (int i = n; i; --i)
            S[i] += S[i / 10000 + 1];

        long ans = 0;
        for (int i = 1; i <= n; ++i) {
            // print("> {}\n", S[i]);
            update(S[i], +1);
            if (i >= K) {
                ans += query(K / 2) + query(K / 2 + 1);
                // if (i == K) {
                //     print("{}\n", query(K / 2) + query(K / 2 + 1));
                // }
                update(S[i - K + 1], -1);
            }
        }
        print("ans = {}\n", ans);
    }
예제 #21
0
// Factoring by trial division, only works for N<2^{60}.
// Only the primes are recorded, not their multiplicity
template<class zz> static void factorT(vector<zz> &factors, const zz &N)
{
  factors.resize(0); // reset the factors

  if (N<2) return;   // sanity check

  PrimeSeq s;
  zz n = N;
  while (true) {
    if (ProbPrime(n)) { // we are left with just a single prime
      factors.push_back(n);
      return;
    }
    // if n is a composite, check if the next prime divides it
    long p = s.next();
    if ((n%p)==0) {
      zz pp;
      conv(pp,p);
      factors.push_back(pp);
      do { n /= p; } while ((n%p)==0);
    }
    if (n==1) return;
  }
}
예제 #22
0
// simple test program for computing discrete logarithms using index calculus
int main(int argc, char* argv[]) {

  // L2 cache size of sieving
  FactorBase::CACHE_SIZE = 128*1024;

  // initialize random number generator
  SetSeed(to_ZZ(time(0)));

  // size of modulus (in bits)
  long k=64;

  // choose a random modulus
  ZZ p,q;
  GenGermainPrime(q,k-1);  // q has one less bit than p
  p = 2*q+1;
  ZZ_p::init(p);
  std::cout<<"Modulus: "<<p<<std::endl;

  // factorization of p-1
  vec_pair_ZZ_long f;
  f.SetLength(2);
  f[0].a = 2;  f[0].b = 1;
  f[1].a = q;  f[1].b = 1;

  // choose a base (generator)
  ZZ_p g;
  PrimeSeq s;
  do {
    conv(g,s.next());
  } while (!isGenerator(g,f));
  std::cout<<"Base:    "<<g<<std::endl;

  // set verboseness (set to 1 for more output)
  DLog_IC_Base::VERBOSE=0;

  // initialize NFS
  double start = GetTime();
  DLog_NFS dlog(g);
  std::cout<<"Setup time: "<<(GetTime()-start)<<" seconds"<<std::endl;

  for (long i=0; i<5; ++i) {

    // choose a power to find logarithm for
    ZZ_p y;
    if (i==0) {
      conv(y,2);
      if (y==g)
        ++y;
    }
    else {
      random(y);
    }

    // find discrete logarithm
    std::cout<<std::endl;
    std::cout<<"Finding logarithm of: "<<y<<std::endl;
    ZZ x;
    start = GetTime();
    x = dlog.log(y); 
    std::cout<<"Time to find logarithm: "<<(GetTime()-start)<<" seconds"
             <<std::endl;
    // verify logarithm
    ZZ_p yy;
    power(yy,g,x);
    if (y==yy)
      std::cout<<"Logarithm is: "<<x<<std::endl;
    else 
      std::cout<<"Logarithm ("<<x<<") is incorrect!"<<std::endl;
    if (x<0)
      break;
  }

  return 0;
}
예제 #23
0
파일: ZZFactoring.cpp 프로젝트: onechip/ecm
// returns a non-trivial factor q of ZZ_p::modulus(), or 1 otherwise
void ECM_stage_two(ZZ& q, EC_p& Q, PrimeSeq& seq, long bound, long D) {
  long B1 = seq.next();
  if (B1<=2*D) {
    // no primes to work with
    set(q);
    return;
  }

  EC_p R;
  mul(R,B1,Q);
  // check R for divisor
  if (IsZero(R)) {
    set(q);
    return;
  }
  GCD(q,ZZ_p::modulus(),rep(R.Z));
  if (!IsOne(q))
    return;
  EC_p T;
  mul(T,B1-2*D,Q);

  // compute point multiples S[d]=2*d*Q
  EC_p S[D+1];
  S[0]=Q;
  doub(S[1],Q);
  doub(S[2],S[1]);
  for (long d=3; d<=D; ++d)
    addh(S[d],S[d-1],S[1],S[d-2]);
  ZZ_p beta[D+1];
  for (long d=0; d<=D; ++d)
    mul(beta[d],S[d].X,S[d].Z);

  ZZ_p g,t,t2;
  set(g);
  ZZ_p alpha;
  long r=B1;
  long p=seq.next();
  do {
    mul(alpha,R.X,R.Z);
    do {
      long delta = (p-r)/2;
      if (delta>D) break;
      //g *= (R.X-S[delta].X) * (R.Z+S[delta].Z) - alpha + beta[delta];
      sub(t,R.X,S[delta].X);
      add(t2,R.Z,S[delta].Z);
      t*=t2;
      t-=alpha;
      t+=beta[delta];
      g*=t;
      // next prime
      p = seq.next();
      if (p==0) {
	// ran out of primes (should never happen)
	p=NTL_MAX_LONG;
	break;
      }
    } while (p<=bound);
    if (p>bound)
      break;
    addh(T,R,S[D],T);
    swap(R,T);
    r+=2*D;
  } while (true);
  if (!IsZero(g))
    GCD(q,ZZ_p::modulus(),rep(g));
  else
    set(q);
}