Ejemplo n.º 1
0
// recursive factoring (precondition: n composite)
// currently only uses ECM
void factor_r(vec_pair_ZZ_long& factors, const ZZ& _n,
	      const ZZ& bnd, double failure_prob, bool verbose) {
  ZZ q;
  ZZ n(_n);
  do {
    // attempt to factor n
    if (bnd>0)
      ECM(q,n,bnd,failure_prob,verbose);
    else
      ECM(q,n,ZZ::zero(),0,verbose);

    if (IsOne(q)) {
      // give up
      addFactor(factors,n);
      return;
    }

    // compute other factor
    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);

    // check if n is still composite
    if (ProbPrime_notd(n)) {
      addFactor(factors,n);
      return;
    }
  } while (true);
}
Ejemplo n.º 2
0
// 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;
    }
  }
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
void ExerciseFactorize::slotFactor19ButtonClicked()
{
    addFactor(19);

    return;
}
Ejemplo n.º 5
0
void ExerciseFactorize::slotFactor7ButtonClicked()
{
    addFactor(7);

    return;
}