Beispiel #1
0
/* See Cohen 1.5.2 */
int cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p)
{
    int result = 0;
    mpz_t a, b, c, d;

    if (mpz_jacobi(D, p) < 0)     /* No solution */
        return 0;

    mpz_init(a);
    mpz_init(b);
    mpz_init(c);
    mpz_init(d);

    sqrtmod(x, D, p, a, b, c, d);
    mpz_set(a, p);
    mpz_set(b, x);
    mpz_sqrt(c, p);

    while (mpz_cmp(b,c) > 0) {
        mpz_set(d, a);
        mpz_set(a, b);
        mpz_mod(b, d, b);
    }

    mpz_mul(a, b, b);
    mpz_sub(a, p, a);   /* a = p - b^2 */
    mpz_abs(d, D);      /* d = |D| */

    if (mpz_divisible_p(a, d)) {
        mpz_divexact(c, a, d);
        if (mpz_perfect_square_p(c)) {
            mpz_set(x, b);
            mpz_sqrt(y, c);
            result = 1;
        }
    }

    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(d);

    return result;
}
Beispiel #2
0
int isprime( mpz_t n )
{
    mpz_t i, n2, tmp;
    int d, ret;

    /*  1は素数ではない */
    if( mpz_cmp_ui( n, 1 ) == 0 )
        return( 0 );

    /*  2,3は素数 */
    if( mpz_cmp_ui( n, 2 ) == 0 || mpz_cmp_ui( n, 3 ) == 0 )
        return( 1 );

    /*  2,3で割り切れたら合成数    */
    if( mpz_even_p( n ) || mpz_divisible_ui_p( n, 3 ) )
        return( 0 );

    mpz_init( i );
    mpz_init( n2 );
    mpz_init( tmp );

    /*  sqrt(n)+1を求める */
    mpz_sqrt( n2, n );

    /*  n2以下の2,3の倍数以外での剰余が0かどうか調べる   */
    d = 2;
    mpz_set_ui( i, 5 );
    ret = 1;
    while( mpz_cmp( i, n2 ) <= 0 ) {
        if( mpz_divisible_p( n, i ) ) {
            ret = 0;
            break;
        }
        mpz_add_ui( tmp, i, d );
        mpz_set( i, tmp );
        d = ( d == 2 ? 4 : 2 );
    }

    mpz_clear( i );
    mpz_clear( n2 );
    mpz_clear( tmp );

    return( ret );
}
unsigned int factorCount(mpz_t number)
{
    mpz_t maxNumber;
    mpz_t counter;
    mpz_t q;
    mpz_t r;
    unsigned int result = 0;
    
    //if (mpz_cmp_ui(number, 1) == 0)
    //    return 1;
    mpz_init_set(maxNumber, number);
    mpz_init(r);
    mpz_init(q);
    mpz_sqrt(maxNumber, number);
    for (mpz_init_set_ui(counter, 1); mpz_cmp(counter, maxNumber) <= 0; mpz_add_ui(counter, counter, 1))
        if (mpz_divisible_p(number, counter))
            result += 2;
    return result;
}
Beispiel #4
0
static void find_factors(mpz_t base)
{
	char *str;
	int res;
	mpz_t i;
	mpz_t half;
	mpz_t two;

	mpz_init_set_str(two, "2", 10);
	mpz_init_set_str(i, "2", 10);
	mpz_init(half);
	mpz_cdiv_q(half, base, two);

	str = mpz_to_str(base);
	if (!str)
		return;

	/*
	 * We simply return the prime number itself if the base is prime.
	 * (We use the GMP probabilistic function with 10 repetitions).
	 */
	res = mpz_probab_prime_p(base, 10);
	if (res) {
		printf("%s is a prime number\n", str);
		free(str);
		return;
	}

	printf("Trial: prime factors for %s are:", str);
	free(str);
	do {
		if (mpz_divisible_p(base, i) && verify_is_prime(i)) {
			str = mpz_to_str(i);
			if (!str)
				return;
			printf(" %s", str);
			free(str);
		}

		mpz_nextprime(i, i);
	} while (mpz_cmp(i, half) <= 0);
	printf("\n");
}
Beispiel #5
0
void *SumThread(void *context)
{
	PSUM_THREAD_CONTEXT tcontext = (PSUM_THREAD_CONTEXT)context;

	while (mpz_cmp(tcontext->factor, tcontext->end) < 0)
	{
		//Check if the number is divisible by the factor
		if (mpz_divisible_p(tcontext->num, tcontext->factor) != 0)
		{
			pthread_mutex_lock(tcontext->termMutex);

			//Add the factor
			mpz_add(*tcontext->sum, *tcontext->sum, tcontext->factor);

			//Add the other factor in the pair
			mpz_divexact(tcontext->otherfactor, tcontext->num, tcontext->factor);
			mpz_add(*tcontext->sum, *tcontext->sum, tcontext->otherfactor);

			//Bail early if we've exceeded our number
			if (mpz_cmp(*tcontext->sum, tcontext->num) > 0)
			{
				pthread_mutex_unlock(tcontext->termMutex);
				break;
			}

			pthread_mutex_unlock(tcontext->termMutex);
		}

		//This is a valid cancellation point
		pthread_testcancel();

		mpz_add_ui(tcontext->factor, tcontext->factor, 1);
	}

	pthread_mutex_lock(tcontext->termMutex);
	(*tcontext->termCount)++;
	pthread_cond_signal(tcontext->termVar);
	pthread_mutex_unlock(tcontext->termMutex);

	pthread_exit(NULL);
}
Beispiel #6
0
static PyObject *
GMPy_MPZ_Function_IsDivisible(PyObject *self, PyObject *args)
{
    unsigned long temp;
    int error, res;
    MPZ_Object *tempx, *tempd;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("is_divisible() requires 2 integer arguments");
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        return NULL;
    }

    temp = GMPy_Integer_AsUnsignedLongAndError(PyTuple_GET_ITEM(args, 1), &error);
    if (!error) {
        res = mpz_divisible_ui_p(tempx->z, temp);
        Py_DECREF((PyObject*)tempx);
        if (res)
            Py_RETURN_TRUE;
        else
            Py_RETURN_FALSE;
    }

    if (!(tempd = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) {
        TYPE_ERROR("is_divisible() requires 2 integer arguments");
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

    res = mpz_divisible_p(tempx->z, tempd->z);
    Py_DECREF((PyObject*)tempx);
    Py_DECREF((PyObject*)tempd);
    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
Beispiel #7
0
/*-----------------------------------------------------------------------------*/
void build_tree(tree_t tree)
{
  mpz_t M_tmp;
  mpz_init(M_tmp);
  
  /* si on est appelé et que l'on a le droit à aucune addition,    */
  /* cela signifie que l'on a déjà trouvé une solution directe     */
  /* par ailleurs: on rend la main et disant qu'on n'a pas trouvé. */
  if(mpz_cmp_ui(tree->max_add, 0) <= 0)
  {
    mpz_set_si(tree->max_add,-1);
    return;
  }
  
  if(!mpz_cmp_ui(tree->M_red, 1))
  {
    mpz_set_ui(tree->max_add,0);
  }
  else
  {
    char *bin;
    int len;
    int k;
    tree_t node;
   
    /* M = M'+1 */    
    mpz_sub_ui(M_tmp, tree->M_red, 1);
    tree->node[0] = create_node(M_tmp);
    mpz_sub_ui(tree->node[0]->max_add, tree->max_add, 1);
    mpz_set_si(tree->max_add, -1);
    build_tree(tree->node[0]);
    if(mpz_cmp_si(tree->node[0]->max_add, -1) != 0) 
    {
      mpz_set(tree->max_add, tree->node[0]->max_add);
      mpz_add_ui(tree->max_add, tree->max_add, 1);
    }

    /* M = M'-1 */
    mpz_add_ui(M_tmp, tree->M_red, 1);
    tree->node[1] = create_node(M_tmp);
    mpz_sub_ui(tree->node[1]->max_add, tree->max_add, 1);
    build_tree(tree->node[1]);
    if(mpz_cmp_si(tree->node[1]->max_add, -1) != 0) 
    {
      mpz_set(tree->max_add, tree->node[1]->max_add);
      mpz_add_ui(tree->max_add, tree->max_add, 1);
    }
    
    bin = mpz_get_str(NULL, 2, tree->M_red);
    len = strlen(bin);
    free(bin);
    /* M = (2^k+1)M' */
    tree->node[2] = NULL;
    for(k=len-1;k>0;k--)
    {
      mpz_set_ui(M_tmp, 1);
      mpz_mul_2exp(M_tmp, M_tmp, k);
      mpz_add_ui(M_tmp, M_tmp, 1);
      if(mpz_divisible_p(tree->M_red, M_tmp))
      {
        mpz_cdiv_q(M_tmp, tree->M_red, M_tmp);
        node = create_node(M_tmp);
        mpz_sub_ui(node->max_add, tree->max_add, 1);
        build_tree(node);
        if(mpz_cmp_si(node->max_add, -1) != 0) 
        {
          destroy_node(tree->node[2]);
          tree->node[2] = node;
          tree->k = k;
          mpz_set(tree->max_add, tree->node[2]->max_add);
          mpz_add_ui(tree->max_add, tree->max_add, 1);
        }
        else 
          destroy_node(node);    
      }
    }  
    
    /* M = (2^k-1)M' */
    tree->node[3] = NULL;
    for(k=len-1;k>0;k--)
    {
      mpz_set_ui(M_tmp, 1);
      mpz_mul_2exp(M_tmp, M_tmp, k);
      mpz_sub_ui(M_tmp, M_tmp, 1);
      if(mpz_divisible_p(tree->M_red, M_tmp))
      {
        mpz_cdiv_q(M_tmp, tree->M_red, M_tmp);
        node = create_node(M_tmp);
        mpz_sub_ui(node->max_add, tree->max_add, 1);
        build_tree(node);
        if(mpz_cmp_si(node->max_add, -1) != 0) 
        {
          destroy_node(tree->node[3]);
          tree->node[3] = node;
          tree->k = k;
          mpz_set(tree->max_add, tree->node[3]->max_add);
          mpz_add_ui(tree->max_add, tree->max_add, 1);
        }       
        else 
          destroy_node(node);            
      }  
    }
  }
  
  mpz_clear(M_tmp);
}
Beispiel #8
0
/** 
\brief 整系数多项式最大公因子.
\param f,g 整系数本原多项式,且\f$\deg f=n\ge\deg g\ge 1\f$.
\param r 最大公因子.
\note 小素数模方法.
\todo 理论文档此处有误.
*/
void UniGcdZ_SmallPrime1(poly_z & r,const poly_z & f,const poly_z & g)
{
	poly_z fp,gp,vp,v1;
	poly_z fstar,gstar;
	mpz_t c,s,t;
	mpz_init(c);mpz_init(s);mpz_init(t);
	mpz_t A,b,B,z_temp,k,p_bound,p,p_low_bound,p1,B2;
	mpf_t float_temp;
	mpz_init(A);mpz_init(b);mpz_init(B);mpz_init(z_temp);mpz_init(k);mpz_init(p_bound);mpz_init(p);mpz_init(p1);mpz_init(p_low_bound);mpf_init(float_temp);mpz_init(B2);
	UniMaxNormZ(A,f);UniMaxNormZ(b,g);
	int n=f.size()-1,m=g.size()-1;
	if(mpz_cmp(A,b)<0)mpz_set(A,b);
	mpz_gcd(b,f[n],g[m]);
	mpz_ui_pow_ui(B,2,n);
	mpz_mul(B,B,A);
	mpz_mul(B,B,b);
	mpf_sqrt_ui(float_temp,n+1);
	mpz_set_f(z_temp,float_temp);
	mpz_mul(B,B,z_temp);
	mpz_mul_ui(B2,B,2);
	mpz_set_si(z_temp,n);
	int tempint;
	tempint=2*n*mpz_sizeinbase(z_temp,2)+2*mpz_sizeinbase(b,2)+4*n*mpz_sizeinbase(A,2);
	//tempint=2*n*Modules::NumberTheory::IntegerLength(Z(n),2)+2*Modules::NumberTheory::IntegerLength(b,2)+4*n*Modules::NumberTheory::IntegerLength(A,2);
	mpz_set_si(k,tempint);
	mpz_mul_ui(p_bound,k,2);
	mpz_mul_ui(p_bound,p_bound,mpz_sizeinbase(k,2));
	mpz_set_ui(p_low_bound,3);
	fstar.resize(n+1);
	for(size_t i=0;i<=n;i++)
	{
		mpz_mul(fstar[i],f[i],b);
	}
	gstar.resize(m+1);
	for(size_t i=0;i<=m;i++)
	{
		mpz_mul(gstar[i],g[i],b);
	}
	while(1)
	{
		while(1)
		{
			random::randominteger(p,p_low_bound,p_bound);
			if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
		}
		UniPolynomialMod(fp,f,p);
		UniPolynomialMod(gp,g,p);
		UniGcdZp(vp,fp,gp,p);
		if(vp.size()==1)
		{
			r.resize(1);
			mpz_set_si(r[0],1);
			fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
			fstar.resize(0);gstar.resize(0);
			mpz_clear(c);mpz_clear(s);mpz_clear(t);
			mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
			return ;
		}
		mpz_set(p1,p);
		copy_poly_z(v1,vp);
		while(mpz_cmp(p1,B2)<0)
		{
			while(1)
			{
				random::randominteger(p,p_low_bound,p_bound);
				if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
			}
			UniPolynomialMod(fp,f,p);
			UniPolynomialMod(gp,g,p);
			UniGcdZp(vp,fp,gp,p);
			if(vp.size()==1)
			{
				r.resize(1);
				mpz_set_si(r[0],1);
				fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
				fstar.resize(0);gstar.resize(0);
				mpz_clear(c);mpz_clear(s);mpz_clear(t);
				mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
				return ;
			}
			if(vp.size()<v1.size())
			{
				mpz_set(p1,p);
				copy_poly_z(v1,vp);
				continue;
			}
			if(vp.size()==v1.size())
			{
				mpz_gcdext(c,s,t,p1,p);
				mpz_mul(t,p,t);
				mpz_mul(s,p1,s);
				mpz_mul(p1,p1,p);
				for(size_t i=0;i<vp.size();i++)
				{
					mpz_mul(c,v1[i],t);
					mpz_addmul(c,vp[i],s);
					mpz_set(v1[i],c);
				}
				UniPolynomialMod(v1,v1,p1);
			}
		}
		for(size_t i=0;i<v1.size();i++)mpz_mul(v1[i],v1[i],b);
		UniPolynomialMod(v1,v1,p1);
		if(poly_z_divisible(fstar,v1)&&poly_z_divisible(gstar,v1))
		{
			UniPPZ(r,v1);break;
		}
	}
	fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
	fstar.resize(0);gstar.resize(0);
	mpz_clear(c);mpz_clear(s);mpz_clear(t);
	mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
	return ;
}
Beispiel #9
0
int main(int argc, char** argv)
{
	int 		my_rank,
				procs;

	MPI_Status	status;

	mpz_t 		q,
				p,
				pq,
				n,
				gap,
				sqn;

	mpz_t			*k;

	double 		*timearray;
	double		begin, end;
	double 		time_spent;
	
	int 		done = 0,
				found = 0;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &procs);


	begin = MPI_Wtime();

	mpz_init(n);
	mpz_init(q);
	mpz_init(p);
	mpz_init(pq);
	mpz_init(sqn);
	mpz_init(gap);

	mpz_set_str(n,argv[1],10);
	mpz_sqrt(sqn,n);
	mpz_set(gap, sqn);

	mpz_set_ui(p,1);
	mpz_nextprime(q, p);


	size_t mag = mpz_sizeinbase (gap, 10);
	mag=mag*procs;

	k = (mpz_t*)malloc(sizeof(mpz_t)*(mag+1));
	
	mpz_t temp;
	mpz_init(temp);
	mpz_tdiv_q_ui(temp,gap,mag);	

	for (int i=0;i<=mag;i++)
	{
		mpz_init(k[i]);
		mpz_mul_ui(k[i],temp,i);
	}
	mpz_set(k[mag],sqn);





	int counter=0;


	for (int i=my_rank; i<mag; i=i+procs)
	{
		mpz_set(q,k[i]);

		mpz_sub_ui(q,q,1);
		mpz_nextprime(q,q);


		while (( mpz_cmp(q,k[i+1]) <= 0 )&&(!done)&&(!found)&&(mpz_cmp(q,sqn)<=0))
		{//finding the prime numbers
			counter++;
			if (counter%5000==0)MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);

			if (mpz_divisible_p(n,q)==0) 
			{//if n is not divisible by q
				mpz_nextprime(q,q);
				continue;
			}

			//since it is divisible, try n/q and see if result is prime
			mpz_divexact(p,n,q);
			int reps;
			if (mpz_probab_prime_p(p,reps)!=0)
			{
				found = 1;
				done = 1;
			}
			else
			{
				mpz_nextprime(q,q);
			}
		}//done finding primes

		
		if (found || done) break;
		
	}
	
	end = MPI_Wtime();



	if (found)
	{
		MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
		gmp_printf("*************************\nP%d: Finished\np*q=n\np=%Zd q=%Zd n=%Zd\n*************************\n", my_rank,p,q,n);
	}
	else if (!done)
	{
		while (!done&&!found)
			MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
	}



	time_spent = (double)(end - begin);





	if (my_rank!=0)
	{
		MPI_Send(&time_spent, sizeof(double),MPI_CHAR,0,0,MPI_COMM_WORLD);
	}
	else
	{
		timearray = (double*)malloc(sizeof(double)*procs);
		
		
		timearray[0] = time_spent;

		int j; 
		for (j = 1; j<procs;j++)
		{
			double *ptr = timearray+j;
			MPI_Recv(ptr, sizeof(double),MPI_CHAR,j,0,MPI_COMM_WORLD,&status);
		}


		writeTime(argv[1],timearray,procs);
		free(timearray);

	}


	
	free(k);

	MPI_Finalize();
	return 0;
}
Beispiel #10
0
static int check_for_factor2(mpz_t f, mpz_t inputn, mpz_t fmin, mpz_t n, int stage, mpz_t* sfacs, int* nsfacs, int degree)
{
  int success, sfaci;
  UV B1;

  /* Use this so we don't modify their input value */
  mpz_set(n, inputn);

  if (mpz_cmp(n, fmin) <= 0) return 0;

#if 0
  {
    /* Straightforward trial division up to 3000. */
    PRIME_ITERATOR(iter);
    UV tf;
    UV const trial_limit = 3000;
    for (tf = 2; tf < trial_limit; tf = prime_iterator_next(&iter)) {
      if (mpz_cmp_ui(n, tf*tf) < 0) break;
      while (mpz_divisible_ui_p(n, tf))
        mpz_divexact_ui(n, n, tf);
    }
    prime_iterator_destroy(&iter);
  }
#else
  /* Utilize GMP's fast gcd algorithms.  Trial to 224737 with two gcds. */
  mpz_tdiv_q_2exp(n, n, mpz_scan1(n, 0));
  while (mpz_divisible_ui_p(n, 3))  mpz_divexact_ui(n, n, 3);
  while (mpz_divisible_ui_p(n, 5))  mpz_divexact_ui(n, n, 5);
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_small);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, n, _gcd_small);
  }
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_large);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, n, _gcd_large);
  }
  /* Quick stage 1 n-1 using a single big powm + gcd. */
  if (stage == 0) {
    if (mpz_cmp(n, fmin) <= 0) return 0;
    mpz_set_ui(f, 2);
    mpz_powm(f, f, _lcm_small, n);
    mpz_sub_ui(f, f, 1);
    mpz_gcd(f, f, n);
    if (mpz_cmp_ui(f, 1) != 0 && mpz_cmp(f, n) != 0) {
      mpz_divexact(n, n, f);
      if (mpz_cmp(f, n) > 0)
        mpz_set(n, f);
    }
  }
#endif

  sfaci = 0;
  success = 1;
  while (success) {
    UV nsize = mpz_sizeinbase(n, 2);

    if (mpz_cmp(n, fmin) <= 0) return 0;
    if (_GMP_is_prob_prime(n)) { mpz_set(f, n); return (mpz_cmp(f, fmin) > 0); }

    success = 0;
    B1 = 300 + 3 * nsize;
    if (degree <= 2) B1 += nsize; /* D1 & D2 are cheap to prove.  Encourage. */
    if (degree <= 0) B1 += nsize; /* N-1 and N+1 are really cheap. */
    if (degree > 20 && stage <= 1) B1 -= nsize;   /* Less time on big polys. */
    if (degree > 40) B1 -= nsize/2;               /* Less time on big polys. */
    if (stage >= 1) {
#ifdef USE_LIBECM
      /* TODO: Tune stage 1 (PM1?) */
      /* TODO: LIBECM in other stages */
      if (!success) {
        ecm_params params;
        ecm_init(params);
        params->method = ECM_ECM;
        mpz_set_ui(params->B2, 10*B1);
        mpz_set_ui(params->sigma, 0);
        success = ecm_factor(f, n, B1/4, params);
        ecm_clear(params);
        if (mpz_cmp(f, n) == 0)  success = 0;
      }
#else
      if (!success) success = _GMP_pminus1_factor(n, f, B1, 6*B1);
      if (!success) success = _GMP_pplus1_factor(n, f, 0, B1/8, B1/8);
      if (!success && nsize < 500) success = _GMP_pbrent_factor(n, f, nsize, 1024-nsize);
#endif
    }
    /* Try any factors found in previous stage 2+ calls */
    while (!success && sfaci < *nsfacs) {
      if (mpz_divisible_p(n, sfacs[sfaci])) {
        mpz_set(f, sfacs[sfaci]);
        success = 1;
      }
      sfaci++;
    }
    if (stage > 1 && !success) {
      if (stage == 2) {
        if (!success) success = _GMP_pbrent_factor(n, f, nsize-1, 8192);
        if (!success) success = _GMP_pminus1_factor(n, f, 6*B1, 60*B1);
        /* p+1 with different initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 1, B1/2, B1/2);
        if (!success) success = _GMP_ecm_factor_projective(n, f, 250, 3);
      } else if (stage == 3) {
        if (!success) success = _GMP_pbrent_factor(n, f, nsize+1, 16384);
        if (!success) success = _GMP_pminus1_factor(n, f, 60*B1, 600*B1);
        /* p+1 with a third initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 2, 1*B1, 1*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/4, 4);
      } else if (stage == 4) {
        if (!success) success = _GMP_pminus1_factor(n, f, 300*B1, 300*20*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/2, 4);
      } else if (stage >= 5) {
        UV B = B1 * (stage-4) * (stage-4) * (stage-4);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B, 8+stage);
      }
    }
    if (success) {
      if (mpz_cmp_ui(f, 1) == 0 || mpz_cmp(f, n) == 0) {
        gmp_printf("factoring %Zd resulted in factor %Zd\n", n, f);
        croak("internal error in ECPP factoring");
      }
      /* Add the factor to the saved factors list */
      if (stage > 1 && *nsfacs < MAX_SFACS) {
        /* gmp_printf(" ***** adding factor %Zd ****\n", f); */
        mpz_init_set(sfacs[*nsfacs], f);
        nsfacs[0]++;
      }
      /* Is the factor f what we want? */
      if ( mpz_cmp(f, fmin) > 0 && _GMP_is_prob_prime(f) )  return 1;
      /* Divide out f */
      mpz_divexact(n, n, f);
    }
  }
  /* n is larger than fmin and not prime */
  mpz_set(f, n);
  return -1;
}
Beispiel #11
0
static PyObject *
GMPy_MPZ_is_aprcl_prime(PyObject *self, PyObject *other)
{
  mpz_t N;
  s64_t T, U;
  int i, j, H, I, J, K, P, Q, W, X;
  int IV, InvX, LEVELnow, NP, PK, PL, PM, SW, VK, TestedQs, TestingQs;
  int QQ, T1, T3, U1, U3, V1, V3;
  int break_this = 0;
  MPZ_Object *tempx;

  if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) {
    TYPE_ERROR("is_aprcl_prime() requires 'mpz' argument");
    return NULL;
  }

  mpz_init(N);
  mpz_set(N, tempx->z);
  Py_DECREF(tempx);

  /* make sure the input is >= 2 and odd */
  if (mpz_cmp_ui(N, 2) < 0)
    Py_RETURN_FALSE;

  if (mpz_divisible_ui_p(N, 2)) {
    if (mpz_cmp_ui(N, 2) == 0)
      Py_RETURN_TRUE;
    else
      Py_RETURN_FALSE;
  }

  /* only three small exceptions for this implementation */
  /* with this set of P and Q primes */
  if (mpz_cmp_ui(N, 3) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 7) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 11) == 0)
    Py_RETURN_TRUE;

  /* If the input number is larger than 7000 decimal digits
     we will just return whether it is a BPSW (probable) prime */
  NumberLength = mpz_sizeinbase(N, 10);
  if (NumberLength > 7000) {
      VALUE_ERROR("value too large to test");
      return NULL;
  }

  allocate_vars();

  mpz_set(TestNbr, N);
  mpz_set_si(biS, 0);

  j = PK = PL = PM = 0;
  for (J = 0; J < PWmax; J++) {
    /* aiJX[J] = 0; */
    mpz_set_ui(aiJX[J], 0);
  }
  break_this = 0;
/* GetPrimes2Test : */
  for (i = 0; i < LEVELmax; i++) {
    /* biS[0] = 2; */
    mpz_set_ui(biS, 2);

    for (j = 0; j < aiNQ[i]; j++) {
      Q = aiQ[j];
      if (aiT[i]%(Q-1) != 0)
        continue;
      U = aiT[i] * Q;
      do {
        U /= Q;
        /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
        mpz_mul_ui(biS, biS, Q);
      } while (U % Q == 0);

      // Exit loop if S^2 > N.
      if (CompareSquare(biS, TestNbr) > 0) {
        /* break GetPrimes2Test; */
        break_this = 1;
        break;
      }
    } /* End for j */

    if (break_this) break;
  } /* End for i */

  if (i == LEVELmax)
  { /* too big */
    free_vars();
    VALUE_ERROR("value too large to test");
    return NULL;
  }
  LEVELnow = i;
  TestingQs = j;
  T = aiT[LEVELnow];
  NP = aiNP[LEVELnow];

MainStart:
  for (;;)
  {
    for (i = 0; i < NP; i++)
    {
      P = aiP[i];
      if (T%P != 0) continue;

      SW = TestedQs = 0;
      /* Q = W = (int) BigNbrModLong(TestNbr, P * P); */
      Q = W = mpz_fdiv_ui(TestNbr, P * P);
      for (J = P - 2; J > 0; J--)
      {
        W = (W * Q) % (P * P);
      }
      if (P > 2 && W != 1)
      {
        SW = 1;
      }
      for (;;)
      {
        for (j = TestedQs; j <= TestingQs; j++)
        {
          Q = aiQ[j] - 1;
          /* G = aiG[j]; */
          K = 0;
          while (Q % P == 0)
          {
            K++;
            Q /= P;
          }
          Q = aiQ[j];
          if (K == 0)
          {
            continue;
          }

          PM = 1;
          for (I = 1; I < K; I++)
          {
            PM = PM * P;
          }
          PL = (P - 1) * PM;
          PK = P * PM;
          for (I = 0; I < PK; I++)
          {
            /* aiJ0[I] = aiJ1[I] = 0; */
            mpz_set_ui(aiJ0[I], 0);
            mpz_set_ui(aiJ1[I], 0);
          }
          if (P > 2)
          {
            JacobiSum(0, P, PL, Q);
          }
          else
          {
            if (K != 1)
            {
              JacobiSum(0, P, PL, Q);
              for (I = 0; I < PK; I++)
              {
                /* aiJW[I] = 0; */
                mpz_set_ui(aiJW[I], 0);
              }
              if (K != 2)
              {
                for (I = 0; I < PM; I++)
                {
                  /* aiJW[I] = aiJ0[I]; */
                  mpz_set(aiJW[I], aiJ0[I]);
                }
                JacobiSum(1, P, PL, Q);
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_JW(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ1[I] = aiJS[I]; */
                  mpz_set(aiJ1[I], aiJS[I]);
                }
                JacobiSum(2, P, PL, Q);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_2(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ2[I] = aiJS[I]; */
                  mpz_set(aiJ2[I], aiJS[I]);
                }
              }
            }
          }
          /* aiJ00[0] = aiJ01[0] = 1; */
          mpz_set_ui(aiJ00[0], 1);
          mpz_set_ui(aiJ01[0], 1);
          for (I = 1; I < PK; I++)
          {
            /* aiJ00[I] = aiJ01[I] = 0; */
            mpz_set_ui(aiJ00[I], 0);
            mpz_set_ui(aiJ01[I], 0);
          }
          /* VK = (int) BigNbrModLong(TestNbr, PK); */
          VK = mpz_fdiv_ui(TestNbr, PK);
          for (I = 1; I < PK; I++)
          {
            if (I % P != 0)
            {
              U1 = 1;
              U3 = I;
              V1 = 0;
              V3 = PK;
              while (V3 != 0)
              {
                QQ = U3 / V3;
                T1 = U1 - V1 * QQ;
                T3 = U3 - V3 * QQ;
                U1 = V1;
                U3 = V3;
                V1 = T1;
                V3 = T3;
              }
              aiInv[I] = (U1 + PK) % PK;
            }
            else
            {
              aiInv[I] = 0;
            }
          }
          if (P != 2)
          {
            for (IV = 0; IV <= 1; IV++)
            {
              for (X = 1; X < PK; X++)
              {
                for (I = 0; I < PK; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                if (X % P == 0)
                {
                  continue;
                }
                if (IV == 0)
                {
                  /* LongToBigNbr(X, biExp, NumberLength); */
                  mpz_set_ui(biExp, X);
                }
                else
                {
                  /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                  mpz_set_ui(biExp, (VK * X) / PK);
                  if ((VK * X) / PK == 0)
                  {
                    continue;
                  }
                }
                JS_E(PK, PL, PM, P);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                InvX = aiInv[X];
                for (I = 0; I < PK; I++)
                {
                  J = (I * InvX) % PK;
                  /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                  mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                }
                NormalizeJW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ00[I]; */
                    mpz_set(aiJS[I], aiJ00[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                }
                JS_JW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ00[I] = aiJS[I]; */
                    mpz_set(aiJ00[I], aiJS[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                }
              } /* end for X */
            } /* end for IV */
          }
          else
          {
            if (K == 1)
            {
              /* MultBigNbrByLongModN(1, Q, aiJ00[0], TestNbr, NumberLength); */
              mpz_set_ui(aiJ00[0], Q);
              /* aiJ01[0] = 1; */
              mpz_set_ui(aiJ01[0], 1);
            }
            else
            {
              if (K == 2)
              {
                if (VK == 1)
                {
                  /* aiJ01[0] = 1; */
                  mpz_set_ui(aiJ01[0], 1);
                }
                /* aiJS[0] = aiJ0[0]; */
                /* aiJS[1] = aiJ0[1]; */
                mpz_set(aiJS[0], aiJ0[0]);
                mpz_set(aiJS[1], aiJ0[1]);
                JS_2(PK, PL, PM, P);
                if (VK == 3)
                {
                  /* aiJ01[0] = aiJS[0]; */
                  /* aiJ01[1] = aiJS[1]; */
                  mpz_set(aiJ01[0], aiJS[0]);
                  mpz_set(aiJ01[1], aiJS[1]);
                }
                /* MultBigNbrByLongModN(aiJS[0], Q, aiJ00[0], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[0], aiJS[0], Q);
                /* MultBigNbrByLongModN(aiJS[1], Q, aiJ00[1], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[1], aiJS[1], Q);
              }
              else
              {
                for (IV = 0; IV <= 1; IV++)
                {
                  for (X = 1; X < PK; X += 2)
                  {
                    for (I = 0; I <= PM; I++)
                    {
                      /* aiJS[I] = aiJ1[I]; */
                      mpz_set(aiJS[I], aiJ1[I]);
                    }
                    if (X % 8 == 5 || X % 8 == 7)
                    {
                      continue;
                    }
                    if (IV == 0)
                    {
                      /* LongToBigNbr(X, biExp, NumberLength); */
                      mpz_set_ui(biExp, X);
                    }
                    else
                    {
                      /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                      mpz_set_ui(biExp, VK * X / PK);
                      if (VK * X / PK == 0)
                      {
                        continue;
                      }
                    }
                    JS_E(PK, PL, PM, P);
                    for (I = 0; I < PK; I++)
                    {
                      /* aiJW[I] = 0; */
                      mpz_set_ui(aiJW[I], 0);
                    }
                    InvX = aiInv[X];
                    for (I = 0; I < PK; I++)
                    {
                      J = I * InvX % PK;
                      /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                      mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                    }
                    NormalizeJW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ00[I]; */
                        mpz_set(aiJS[I], aiJ00[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ01[I]; */
                        mpz_set(aiJS[I], aiJ01[I]);
                      }
                    }
                    NormalizeJS(PK, PL, PM, P);
                    JS_JW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ00[I] = aiJS[I]; */
                        mpz_set(aiJ00[I], aiJS[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ01[I] = aiJS[I]; */
                        mpz_set(aiJ01[I], aiJS[I]);
                      }
                    }
                  } /* end for X */
                  if (IV == 0 || VK % 8 == 1 || VK % 8 == 3)
                  {
                    continue;
                  }
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJW[I] = aiJ2[I]; */
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJW[I], aiJ2[I]);
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                  for (; I < PK; I++)
                  {
                    /* aiJW[I] = aiJS[I] = 0; */
                    mpz_set_ui(aiJW[I], 0);
                    mpz_set_ui(aiJS[I], 0);
                  }
                  JS_JW(PK, PL, PM, P);
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                } /* end for IV */
              }
            }
          }
          for (I = 0; I < PL; I++)
          {
            /* aiJS[I] = aiJ00[I]; */
            mpz_set(aiJS[I], aiJ00[I]);
          }
          for (; I < PK; I++)
          {
            /* aiJS[I] = 0; */
            mpz_set_ui(aiJS[I], 0);
          }
          /* DivBigNbrByLong(TestNbr, PK, biExp, NumberLength); */
          mpz_fdiv_q_ui(biExp, TestNbr, PK);
          JS_E(PK, PL, PM, P);
          for (I = 0; I < PK; I++)
          {
            /* aiJW[I] = 0; */
            mpz_set_ui(aiJW[I], 0);
          }
          for (I = 0; I < PL; I++)
          {
            for (J = 0; J < PL; J++)
            {
              /* MontgomeryMult(aiJS[I], aiJ01[J], biTmp); */
              /* AddBigNbrModN(biTmp, aiJW[(I + J) % PK], aiJW[(I + J) % PK], TestNbr, NumberLength); */
              mpz_mul(biTmp, aiJS[I], aiJ01[J]);
              mpz_add(aiJW[(I + J) % PK], biTmp, aiJW[(I + J) % PK]);
            }
          }
          NormalizeJW(PK, PL, PM, P);
/* MatchingRoot : */
          do
          {
            H = -1;
            W = 0;
            for (I = 0; I < PL; I++)
            {
              if (mpz_cmp_ui(aiJW[I], 0) != 0)/* (!BigNbrIsZero(aiJW[I])) */
              {
                /* if (H == -1 && BigNbrAreEqual(aiJW[I], 1)) */
                if (H == -1 && (mpz_cmp_ui(aiJW[I], 1) == 0))
                {
                  H = I;
                }
                else
                {
                  H = -2;
                  /* AddBigNbrModN(aiJW[I], MontgomeryMultR1, biTmp, TestNbr, NumberLength); */
                  mpz_add_ui(biTmp, aiJW[I], 1);
                  mpz_mod(biTmp, biTmp, TestNbr);
                  if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
                  {
                    W++;
                  }
                }
              }
            }
            if (H >= 0)
            {
              /* break MatchingRoot; */
              break;
            }
            if (W != P - 1)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (I = 0; I < PM; I++)
            {
              /* AddBigNbrModN(aiJW[I], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
              {
                break;
              }
            }
            if (I == PM)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (J = 1; J <= P - 2; J++)
            {
              /* AddBigNbrModN(aiJW[I + J * PM], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I + J * PM], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
              {
                /* Not prime */
                free_vars();
                Py_RETURN_FALSE;
              }
            }
            H = I + PL;
          }
          while (0);

          if (SW == 1 || H % P == 0)
          {
            continue;
          }
          if (P != 2)
          {
            SW = 1;
            continue;
          }
          if (K == 1)
          {
            if ((mpz_get_ui(TestNbr) & 3) == 1)
            {
              SW = 1;
            }
            continue;
          }

          // if (Q^((N-1)/2) mod N != N-1), N is not prime.

          /* MultBigNbrByLongModN(1, Q, biTmp, TestNbr, NumberLength); */
          mpz_set_ui(biTmp, Q);
          mpz_mod(biTmp, biTmp, TestNbr);

          mpz_sub_ui(biT, TestNbr, 1); /* biT = n-1 */
          mpz_divexact_ui(biT, biT, 2); /* biT = (n-1)/2 */
          mpz_powm(biR, biTmp, biT, TestNbr); /* biR = Q^((n-1)/2) mod n */
          mpz_add_ui(biTmp, biR, 1);
          mpz_mod(biTmp, biTmp, TestNbr);

          if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
          {
            /* Not prime */
            free_vars();
            Py_RETURN_FALSE;
          }
          SW = 1;
        } /* end for j */
        if (SW == 0)
        {
          TestedQs = TestingQs + 1;
          if (TestingQs < aiNQ[LEVELnow] - 1)
          {
            TestingQs++;
            Q = aiQ[TestingQs];
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);

            continue; /* Retry */
          }
          LEVELnow++;
          if (LEVELnow == LEVELmax)
          {
            free_vars();
            // return mpz_bpsw_prp(N); /* Cannot tell */
            VALUE_ERROR("maximum levels reached");
            return NULL;
          }
          T = aiT[LEVELnow];
          NP = aiNP[LEVELnow];
          /* biS = 2; */
          mpz_set_ui(biS, 2);
          for (J = 0; J <= aiNQ[LEVELnow]; J++)
          {
            Q = aiQ[J];
            if (T%(Q-1) != 0) continue;
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);
            if (CompareSquare(biS, TestNbr) > 0)
            {
              TestingQs = J;
              /* continue MainStart; */ /* Retry from the beginning */
              goto MainStart;
            }
          } /* end for J */
          free_vars();
          VALUE_ERROR("internal failure");
          return NULL;
        } /* end if */
        break;
      } /* end for (;;) */
    } /* end for i */

    // Final Test

    /* biR = 1 */
    mpz_set_ui(biR, 1);
    /* biN <- TestNbr mod biS */ /* Compute N mod S */
    mpz_fdiv_r(biN, TestNbr, biS);

    for (U = 1; U <= T; U++)
    {
      /* biR <- (biN * biR) mod biS */
      mpz_mul(biR, biN, biR);
      mpz_mod(biR, biR, biS);
      if (mpz_cmp_ui(biR, 1) == 0) /* biR == 1 */
      {
        /* Number is prime */
        free_vars();
        Py_RETURN_TRUE;
      }
      if (mpz_divisible_p(TestNbr, biR) && mpz_cmp(biR, TestNbr) < 0) /* biR < N and biR | TestNbr */
      {
        /* Number is composite */
        free_vars();
        Py_RETURN_FALSE;
      }
    } /* End for U */
    /* This should never be reached. */
    free_vars();
    SYSTEM_ERROR("Internal error: APR-CL error with final test.");
    return NULL;
  }
}
Beispiel #12
0
bool BitcoinMiner(primecoinBlock_t* primecoinBlock, CSieveOfEratosthenes*& psieve, unsigned int threadIndex, unsigned int nonceStep) {
	if (pctx == NULL) { pctx = BN_CTX_new(); }

	primecoinBlock->nonce = 1+threadIndex;
	const unsigned long maxNonce = 0xFFFFFFFF;

	uint32 nTime = getTimeMilliseconds() + 1000*600;
	uint32 loopCount = 0;


	mpz_class mpzHashFactor = 2310; //11 Hash Factor

	time_t unixTimeStart;
	time(&unixTimeStart);
	uint32 nTimeRollStart = primecoinBlock->timestamp - 5;
   uint32 nLastRollTime = getTimeMilliseconds();
	uint32 nCurrentTick = nLastRollTime;
	while( nCurrentTick < nTime && primecoinBlock->serverData.blockHeight == jhMiner_getCurrentWorkBlockHeight(primecoinBlock->threadIndex) )
			{
		nCurrentTick = getTimeMilliseconds();
      // Roll Time stamp every 10 secs.
		if ((primecoinBlock->xptMode) && (nCurrentTick < nLastRollTime || (nLastRollTime - nCurrentTick >= 10000)))
		{
			// when using x.pushthrough, roll time
			time_t unixTimeCurrent;
			time(&unixTimeCurrent);
			uint32 timeDif = unixTimeCurrent - unixTimeStart;
			uint32 newTimestamp = nTimeRollStart + timeDif;
			if( newTimestamp != primecoinBlock->timestamp )
			{
				primecoinBlock->timestamp = newTimestamp;
				primecoinBlock->nonce = 1+threadIndex;
			}
         nLastRollTime = nCurrentTick;
		}

		primecoinBlock_generateHeaderHash(primecoinBlock, primecoinBlock->blockHeaderHash.begin());

		bool fNewBlock = true;
		unsigned int nTriedMultiplier = 0;
		// Primecoin: try to find hash divisible by primorial
        uint256 phash = primecoinBlock->blockHeaderHash;
        mpz_class mpzHash;
        mpz_set_uint256(mpzHash.get_mpz_t(), phash);
        
		while ((phash < hashBlockHeaderLimit || !mpz_divisible_p(mpzHash.get_mpz_t(), mpzHashFactor.get_mpz_t())) && primecoinBlock->nonce < maxNonce) {
			primecoinBlock->nonce += nonceStep;
			if (primecoinBlock->nonce >= maxNonce) { primecoinBlock->nonce = 2+threadIndex; }
			primecoinBlock_generateHeaderHash(primecoinBlock, primecoinBlock->blockHeaderHash.begin());
            phash = primecoinBlock->blockHeaderHash;
            mpz_set_uint256(mpzHash.get_mpz_t(), phash);
		}

		mpz_class mpzPrimorial;mpz_class mpzFixedMultiplier;
		unsigned int nRoundTests = 0;unsigned int nRoundPrimesHit = 0;
		unsigned int nTests = 0;unsigned int nPrimesHit = 0;

		unsigned int nProbableChainLength;
		if (primeStats.tSplit) {
			unsigned int nPrimorialMultiplier = primeStats.nPrimorials[threadIndex%primeStats.nPrimorialsSize];
			Primorial(nPrimorialMultiplier, mpzPrimorial);
			mpzFixedMultiplier = mpzPrimorial / mpzHashFactor;
			MineProbablePrimeChain(psieve, primecoinBlock, mpzFixedMultiplier, fNewBlock, nTriedMultiplier, nProbableChainLength, nTests, nPrimesHit, threadIndex, mpzHash, nPrimorialMultiplier);
		} else {
			unsigned int nPrimorialMultiplier = primeStats.nPrimorials[threadSNum];
			Primorial(nPrimorialMultiplier, mpzPrimorial);
			mpzFixedMultiplier = mpzPrimorial / mpzHashFactor;
		MineProbablePrimeChain(psieve, primecoinBlock, mpzFixedMultiplier, fNewBlock, nTriedMultiplier, nProbableChainLength, nTests, nPrimesHit, threadIndex, mpzHash, nPrimorialMultiplier);
			threadSNum++;if (threadSNum>=primeStats.nPrimorialsSize) { threadSNum = 0; }
#ifdef _WIN32
		threadHearthBeat[threadIndex] = getTimeMilliseconds();
#endif
		if (appQuitSignal)
		{
			printf( "Shutting down mining thread %d.\n", threadIndex);
			return false;
		}
		}
		
	if (appQuitSignal) { printf( "Shutting down mining thread %d.\n", threadIndex);return false; }

		nRoundTests += nTests;
		nRoundPrimesHit += nPrimesHit;

		primecoinBlock->nonce += nonceStep;
		loopCount++;
	}
	
	return true;
}
Beispiel #13
0
static int check_for_factor(mpz_t f, mpz_t inputn, mpz_t fmin, mpz_t n, int stage, mpz_t* sfacs, int* nsfacs, int degree)
{
  int success, sfaci;
  UV B1;

  /* Use this so we don't modify their input value */
  mpz_set(n, inputn);

  if (mpz_cmp(n, fmin) <= 0) return 0;

#if 0
  /* Use this to really encourage n-1 / n+1 proof types */
  if (degree <= 0) {
    if (stage == 1) return -1;
    if (stage == 0) stage = 1;
  }
#endif

  /* Utilize GMP's fast gcd algorithms.  Trial to 224737+ with two gcds. */
  mpz_tdiv_q_2exp(n, n, mpz_scan1(n, 0));
  while (mpz_divisible_ui_p(n, 3))  mpz_divexact_ui(n, n, 3);
  while (mpz_divisible_ui_p(n, 5))  mpz_divexact_ui(n, n, 5);
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_small);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, f, n);
  }
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_large);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, f, n);
  }

  sfaci = 0;
  success = 1;
  while (success) {
    UV nsize = mpz_sizeinbase(n, 2);
    const int do_pm1 = 1;
    const int do_pp1 = 1;
    const int do_pbr = 0;
    const int do_ecm = 0;

    if (mpz_cmp(n, fmin) <= 0) return 0;
    if (is_bpsw_prime(n)) { mpz_set(f, n); return (mpz_cmp(f, fmin) > 0); }

    success = 0;
    B1 = 300 + 3 * nsize;
    if (degree <= 2) B1 += nsize;             /* D1 & D2 are cheap to prove. */
    if (degree <= 0) B1 += 2*nsize;         /* N-1 and N+1 are really cheap. */
    if (degree > 20 && stage <= 1) B1 -= nsize;   /* Less time on big polys. */
    if (degree > 40) B1 -= nsize/2;               /* Less time on big polys. */
    if (stage == 0) {
      /* A relatively small performance hit, makes slightly smaller proofs. */
      if (nsize < 900 && degree <= 2) B1 *= 1.8;
      /* We need to try a bit harder for the large sizes :( */
      if (nsize > 1400)  B1 *= 2;
      if (nsize > 2000)  B1 *= 2;
      if (!success)
        success = _GMP_pminus1_factor(n, f, 100+B1/8, 100+B1);
    } else if (stage >= 1) {
      /* P-1 */
      if ((!success && do_pm1))
        success = _GMP_pminus1_factor(n, f, B1, 6*B1);
      /* Pollard's Rho */
      if ((!success && do_pbr && nsize < 500))
        success = _GMP_pbrent_factor(n, f, nsize % 53, 1000-nsize);
      /* P+1 */
      if ((!success && do_pp1)) {
        UV ppB = (nsize < 2000) ? B1/4 : B1/16;
        success = _GMP_pplus1_factor(n, f, 0, ppB, ppB);
      }
      if ((!success && do_ecm))
        success = _GMP_ecm_factor_projective(n, f, 400, 2000, 1);
#ifdef USE_LIBECM
      /* TODO: LIBECM in other stages */
      /* Note: this will be substantially slower than our code for small sizes
       *       and the small B1/B2 values we're using. */
      if (!success && degree <= 2 && nsize > 600) {
        ecm_params params;
        ecm_init(params);
        params->method = ECM_ECM;
        mpz_set_ui(params->B2, 10*B1);
        mpz_set_ui(params->sigma, 0);
        success = ecm_factor(f, n, B1/4, params);
        ecm_clear(params);
        if (mpz_cmp(f, n) == 0)  success = 0;
        if (success) { printf("ECM FOUND FACTOR\n"); }
      }
#endif
    }
    /* Try any factors found in previous stage 2+ calls */
    while (!success && sfaci < *nsfacs) {
      if (mpz_divisible_p(n, sfacs[sfaci])) {
        mpz_set(f, sfacs[sfaci]);
        success = 1;
      }
      sfaci++;
    }
    if (stage > 1 && !success) {
      if (stage == 2) {
        /* if (!success) success = _GMP_pbrent_factor(n, f, nsize-1, 8192); */
        if (!success) success = _GMP_pminus1_factor(n, f, 6*B1, 60*B1);
        /* p+1 with different initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 1, B1/2, B1/2);
        if (!success) success = _GMP_ecm_factor_projective(n, f, 250, 2500, 8);
      } else if (stage == 3) {
        if (!success) success = _GMP_pbrent_factor(n, f, nsize+1, 16384);
        if (!success) success = _GMP_pminus1_factor(n, f, 60*B1, 600*B1);
        /* p+1 with a third initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 2, 1*B1, 1*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/4, B1*4, 5);
      } else if (stage == 4) {
        if (!success) success = _GMP_pminus1_factor(n, f, 300*B1, 300*20*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/2, B1*8, 4);
      } else if (stage >= 5) {
        UV B = B1 * (stage-4) * (stage-4) * (stage-4);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B, 10*B, 8+stage);
      }
    }
    if (success) {
      if (mpz_cmp_ui(f, 1) == 0 || mpz_cmp(f, n) == 0) {
        gmp_printf("factoring %Zd resulted in factor %Zd\n", n, f);
        croak("internal error in ECPP factoring");
      }
      /* Add the factor to the saved factors list */
      if (stage > 1 && *nsfacs < MAX_SFACS) {
        /* gmp_printf(" ***** adding factor %Zd ****\n", f); */
        mpz_init_set(sfacs[*nsfacs], f);
        nsfacs[0]++;
      }
      /* Is the factor f what we want? */
      if ( mpz_cmp(f, fmin) > 0 && is_bpsw_prime(f) )  return 1;
      /* Divide out f */
      mpz_divexact(n, n, f);
    }
  }
  /* n is larger than fmin and not prime */
  mpz_set(f, n);
  return -1;
}