Пример #1
0
/*-------------------------------------------------------------------*/
static void convert_to_integer(mpz_poly_t *alg_sqrt, mpz_t n,
				mpz_t c, mpz_t m1, 
				mpz_t m0, mpz_t res) {

	/* given the completed square root, apply the homomorphism
	   to convert the polynomial to an integer. We do this
	   by evaluating alg_sqrt at -c*m0/m1, with all calculations
	   performed mod n */

	uint32 i;
	mpz_t m1_pow;
	mpz_t m0c;

	mpz_init_set(m1_pow, m1);
	mpz_poly_mod_q(alg_sqrt, n, alg_sqrt);

	mpz_init_set_ui(m0c, 0);
	mpz_submul(m0c, m0, c);
	mpz_mod(m0c, m0c, n);

	i = alg_sqrt->degree;
	mpz_set(res, alg_sqrt->coeff[i]);
	while (--i) {
		mpz_mul(res, res, m0c);
		mpz_addmul(res, m1_pow, alg_sqrt->coeff[i]);
		mpz_mul(m1_pow, m1_pow, m1);
	}
	mpz_mul(res, res, m0c);
	mpz_addmul(res, m1_pow, alg_sqrt->coeff[i]);
	mpz_mod(res, res, n);

	mpz_clear(m1_pow);
	mpz_clear(m0c);
}
void
refmpq_sub (mpq_ptr w, mpq_srcptr x, mpq_srcptr y)
{
  mpz_mul    (mpq_numref(w), mpq_numref(x), mpq_denref(y));
  mpz_submul (mpq_numref(w), mpq_denref(x), mpq_numref(y));
  mpz_mul    (mpq_denref(w), mpq_denref(x), mpq_denref(y));
  mpq_canonicalize (w);
}
Пример #3
0
void
testmain (int argc, char **argv)
{
  unsigned i;
  mpz_t a, b, res, ref;

  mpz_init (a);
  mpz_init (b);
  mpz_init_set_ui (res, 5);
  mpz_init (ref);

  for (i = 0; i < COUNT; i++)
    {
      mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
      if (i & 1) {
	mpz_add (ref, ref, res);
	if (mpz_fits_ulong_p (b))
	  mpz_addmul_ui (res, a, mpz_get_ui (b));
	else
	  mpz_addmul (res, a, b);
      } else {
	mpz_sub (ref, res, ref);
	if (mpz_fits_ulong_p (b))
	  mpz_submul_ui (res, a, mpz_get_ui (b));
	else
	  mpz_submul (res, a, b);
      }
      if (mpz_cmp (res, ref))
	{
	  if (i & 1)
	    fprintf (stderr, "mpz_addmul failed:\n");
	  else
	    fprintf (stderr, "mpz_submul failed:\n");
	  dump ("a", a);
	  dump ("b", b);
	  dump ("r", res);
	  dump ("ref", ref);
	  abort ();
	}
    }
  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (res);
  mpz_clear (ref);
}
Пример #4
0
/**
 * Set pivot column to 0
 * @param r indice de la premiere ligne a annuler
 * on recalcule les coefficients modulo mod a chaque fois
 */
void del_coeffs(int r, int matrix_length, mpz_t *M, mpz_t mod){
  int i, j;
  mpz_t M_tmp[matrix_length*matrix_length];
  for (i=0; i < matrix_length*matrix_length; i++){
    mpz_init(M_tmp[i]);
    mpz_set(M_tmp[i], M[i]);
  }
    
  for (i=r; i<matrix_length; i++){

    for (j=r-1; j<matrix_length; j++){
      /* a modifier si on enleve la normalisation */
      mpz_submul(M_tmp[i*matrix_length+j], M[i*matrix_length+r-1], M[(r-1)*matrix_length+j]);
    }
  }
  for (i=0; i < matrix_length*matrix_length; i++){
    mpz_mod(M[i], M_tmp[i], mod);
  }
	/* Clear */
	for(i=0;i<matrix_length*matrix_length;i++)
		mpz_clear(M_tmp[i]);
}
Пример #5
0
void
check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y)
{
  mpz_t  want, got;

  mpz_init (want);
  mpz_init (got);

  mpz_mul (want, x, y);
  mpz_add (want, w, want);
  mpz_set (got, w);
  mpz_addmul (got, x, y);
  MPZ_CHECK_FORMAT (got);
  if (mpz_cmp (want, got) != 0)
    {
      printf ("mpz_addmul fail\n");
    fail:
      mpz_trace ("w", w);
      mpz_trace ("x", x);
      mpz_trace ("y", y);
      mpz_trace ("want", want);
      mpz_trace ("got ", got);
      abort ();
    }

  mpz_mul (want, x, y);
  mpz_sub (want, w, want);
  mpz_set (got, w);
  mpz_submul (got, x, y);
  MPZ_CHECK_FORMAT (got);
  if (mpz_cmp (want, got) != 0)
    {
      printf ("mpz_submul fail\n");
      goto fail;
    }

  mpz_clear (want);
  mpz_clear (got);
}
Пример #6
0
/**
 *  Extended Euclid's algorithm
 *  output the combination coefficients
 */
void cpt_ext_gcd(mpz_t res, mpz_t c1, mpz_t c2, mpz_srcptr a, mpz_srcptr b)
{
	mpz_t ax,bx,x,y,q,r,ay,by;
	mpz_init(q);
	mpz_init(r);
	mpz_init_set_si(bx,0);
	mpz_init_set_si(ay,0);
	if(mpz_cmp_si(a,0)>=0)
	{
		mpz_init_set(x,a);
		mpz_init_set_si(ax,1);
	}
	else
	{
		mpz_init(x);
		mpz_neg(x,a);
		mpz_init_set_si(ax,-1);
	}
	if(mpz_cmp_si(b,0)>=0)
	{
		mpz_init_set(y,b);
		mpz_init_set_si(by,1);
	}
	else
	{
		mpz_init(y);
		mpz_neg(y,b);
		mpz_init_set_si(by,-1);
	}
	if(mpz_cmp(x,y) > 0)
	{
		mpz_swap(x,y);
		mpz_swap(ax,ay);
		mpz_swap(bx,by);
	}
	while(mpz_cmp_si(x,0)>0)
	{
		mpz_t tmp1,tmp2;
		mpz_tdiv_qr(q,r,y,x);
		mpz_set(y,x);
		mpz_init_set(tmp1,ay);
		mpz_init_set(tmp2,by);
		mpz_set(ay,ax);
		mpz_set(by,bx);
		mpz_set(x,r);
		mpz_submul(tmp1,q,ax);
		mpz_submul(tmp2,q,bx);
		mpz_set(ax,tmp1);
		mpz_set(bx,tmp2);
		mpz_clear(tmp1);
		mpz_clear(tmp2);
	}
	mpz_set(res,y);
	mpz_set(c1,ay);
	mpz_set(c2,by);
	mpz_clear(ax);
	mpz_clear(bx);
	mpz_clear(ay);
	mpz_clear(by);
	mpz_clear(x);
	mpz_clear(y);
	mpz_clear(q);
	mpz_clear(r);
}
Пример #7
0
//Le but de la fonction est de calculer le développement en fractions continue jusqu'à un certain rang de racine carrée de kN et de stocker les couples (A_n-1,Q_n) comme décrit dans la section (à venir)
cfrac expand(const mpz_t N, const long long unsigned int rang, const mpz_t k)
{
	cfrac res;	//Contient l'ensemble des A_n-1 et l'ensemble Q_n
	mpz_inits(res.N, res.k, res.g, NULL);

	//Initialisation des variables
	mpz_t* A = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Le tableau contenant les A_n-1
	mpz_t* Q = (mpz_t*)malloc((rang+2)*sizeof(mpz_t));		//Le tableau contenant les Q_n
	mpz_t* P = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Éléments reliés au Q_n
	mpz_t* r = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Interviennent dans le calcul des A_n-1 & Q_n
	mpz_t* q = (mpz_t*)malloc(rang*sizeof(mpz_t));			//Idem
	mpz_t g, tempz;											//Idem, tempz = variable à tout faire	
	mpf_t sqrtkN, tempf, tempf2;									//sqrtkN = sqrt(k*N), tempf = variable à tout faire

	

	//Valeurs d'initialisation de la boucle
	mpz_inits(g, A[0], Q[0], r[0], tempz, NULL);
	mpf_inits(tempf, sqrtkN, tempf2, NULL);

	//Initialisation des différentes valeurs "indépendantes"

	mpz_set(tempz, N);
	mpz_mul(tempz, tempz, k);
	mpf_set_z(sqrtkN, tempz);
	mpf_sqrt(sqrtkN, sqrtkN);
	mpf_floor(tempf, sqrtkN);
	mpz_set_f(g, tempf);				//g = [sqrt(kN)]

	mpz_set(Q[0], k);
	mpz_mul(Q[0], Q[0], N);				//Q_-1 = kN = Q[0]
	mpz_set(r[0], g);					//r_-1 = r[0]
	mpz_set_ui(A[0], 1);				//A_-1 = A[0]

	
	//Calcul de P_0 & Q_0
	mpz_init_set_ui(Q[1], 1);			//Q_0 = Q[1]
	mpz_init_set_ui(P[0], 0);			//P_0 = P[0]	

	for(long long int i = 0; i < rang; i++)
	{
		switch(i)
		{
			case 0:

				//Calcul de q_0
				mpz_init_set(q[0], g);				//q_0 = [(sqrt(kN) + P_0)/Q_0] avec P_0 = 0 et Q_0 = 1

				//Calcul de A_0
				mpz_init_set(A[1],A[0]);
				mpz_mul(A[1], A[1], q[0]);			//A_0 = q_0*A_-1
				mpz_mod(A[1], A[1], N);				//On réduit mod N

				//Calcul de r_0
				mpz_init_set_ui(r[1], 0);			//r_0 = P_0 + g - q_0.Q_0 = 0 + g - g.1 = 0

				//Calcul de P_1
				mpz_init_set(P[1], g);				//P_1 = g - r_0 = g - 0 = g

				//Calcul de Q_1 = Q[2]
				mpz_init_set(Q[2], r[1]);		
				mpz_sub(Q[2], Q[2], r[0]);
				mpz_mul(Q[2], Q[2], q[0]);
				mpz_add(Q[2], Q[2], Q[0]);
				
				break;
			default:
				//Calcul q_i
				mpz_init(q[i]);	
				mpf_set_z(tempf, P[i]);
				mpf_set_z(tempf2, Q[i+1]);
				mpf_add(tempf, tempf, sqrtkN);				//sqrt(kN) + P_i
				mpf_div(tempf, tempf, tempf2);		
				mpf_floor(tempf, tempf);					//floor((sqrt(kN) + P_i)/Q_i)
				mpz_set_f(q[i], tempf);

				//Calcul de r_n = r[n+1]	
				mpz_init(r[i+1]);
				mpz_submul(r[i+1], q[i], Q[i+1]);
				mpz_add(r[i+1], r[i+1], P[i]);
				mpz_add(r[i+1], r[i+1], g);

				//Calcul de A_n = A[n+1] 		
				mpz_init_set(A[i+1],A[i]);
				mpz_mul(A[i+1], A[i+1], q[i]);		//A_i-1*q_i
				mpz_add(A[i+1], A[i+1], A[i-1]);	//A_i-1*q_i + A_i-2
				mpz_mod(A[i+1], A[i+1], N);			//réduction modulo N

				//Calcul P_n+1 
				mpz_init_set(P[i+1], g);
				mpz_sub(P[i+1], P[i+1], r[i+1]);		//P[n+1] = g - r_n = g - r[n+1]

				//Calcul Q_n+1 = Q[n+2]
				mpz_init_set(Q[i+2], r[i+1]); 
				mpz_sub(Q[i+2],	Q[i+2], r[i]);		//(r_n - r_n-1)
				mpz_mul(Q[i+2], Q[i+2], q[i]);		//q_n(r_n - r_n-1)
				mpz_add(Q[i+2], Q[i+2], Q[i]);		//Q_n-1 + q_n(r_n - r_n-1)
				
				break;
		}

	}

	//Test de routine pour voir si le développement de la fraction continue s'est bien passé
	mpz_t tempsqrt;
	mpz_init(tempsqrt);
	mpz_set(tempsqrt, k);
	mpz_mul(tempsqrt, tempsqrt, N);
	mpz_sqrt(tempsqrt, tempsqrt);
	mpz_mul_ui(tempsqrt, tempsqrt, 2);

	for(int i = 1; i < rang; i++)				//Éviter de commencer à i = 0 puisque cela représente Q_-1 qui n'intervient uniquement dans l'algo et non dans le développement en fraction continue
	{
		if(mpz_cmp(Q[i], tempsqrt) >= 0)	//Si Q_n >= 2sqrt(kN)
		{
			res.rang = 0;

			mpz_clears(g, tempz, NULL);
			mpf_clears(sqrtkN, tempf, tempf2, NULL);
			return res;
		}
	}

	//Assignation des tableaux dans le résultat
	res.A = A;
	res.Q = Q;
	res.r = r;
	res.q = q;
	res.P = P;
	mpz_set(res.N, N);
	mpz_set(res.k, k);
	res.rang = rang;
	mpz_set(res.g, g);

	//Libération de mémoire
	mpz_clears(g, tempz, NULL);
	mpf_clears(sqrtkN, tempf, tempf2, NULL);

	return res;
}
Пример #8
0
Файл: pow.c Проект: tomi500/MPC
/* If x^y is exactly representable (with maybe a larger precision than z),
   round it in z and return the (mpc) inexact flag in [0, 10].

   If x^y is not exactly representable, return -1.

   If intermediate computations lead to numbers of more than maxprec bits,
   then abort and return -2 (in that case, to avoid loops, mpc_pow_exact
   should be called again with a larger value of maxprec).

   Assume one of Re(x) or Im(x) is non-zero, and y is non-zero (y is real).

   Warning: z and x might be the same variable, same for Re(z) or Im(z) and y.

   In case -1 or -2 is returned, z is not modified.
*/
static int
mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd,
               mpfr_prec_t maxprec)
{
  mpfr_exp_t ec, ed, ey;
  mpz_t my, a, b, c, d, u;
  unsigned long int t;
  int ret = -2;
  int sign_rex = mpfr_signbit (mpc_realref(x));
  int sign_imx = mpfr_signbit (mpc_imagref(x));
  int x_imag = mpfr_zero_p (mpc_realref(x));
  int z_is_y = 0;
  mpfr_t copy_of_y;

  if (mpc_realref (z) == y || mpc_imagref (z) == y)
    {
      z_is_y = 1;
      mpfr_init2 (copy_of_y, mpfr_get_prec (y));
      mpfr_set (copy_of_y, y, MPFR_RNDN);
    }

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

  ey = mpfr_get_z_exp (my, y);
  /* normalize so that my is odd */
  t = mpz_scan1 (my, 0);
  ey += (mpfr_exp_t) t;
  mpz_tdiv_q_2exp (my, my, t);
  /* y = my*2^ey with my odd */

  if (x_imag)
    {
      mpz_set_ui (c, 0);
      ec = 0;
    }
  else
    ec = mpfr_get_z_exp (c, mpc_realref(x));
  if (mpfr_zero_p (mpc_imagref(x)))
    {
      mpz_set_ui (d, 0);
      ed = ec;
    }
  else
    {
      ed = mpfr_get_z_exp (d, mpc_imagref(x));
      if (x_imag)
        ec = ed;
    }
  /* x = c*2^ec + I * d*2^ed */
  /* equalize the exponents of x */
  if (ec < ed)
    {
      mpz_mul_2exp (d, d, (unsigned long int) (ed - ec));
      if ((mpfr_prec_t) mpz_sizeinbase (d, 2) > maxprec)
        goto end;
    }
  else if (ed < ec)
    {
      mpz_mul_2exp (c, c, (unsigned long int) (ec - ed));
      if ((mpfr_prec_t) mpz_sizeinbase (c, 2) > maxprec)
        goto end;
      ec = ed;
    }
  /* now ec=ed and x = (c + I * d) * 2^ec */

  /* divide by two if possible */
  if (mpz_cmp_ui (c, 0) == 0)
    {
      t = mpz_scan1 (d, 0);
      mpz_tdiv_q_2exp (d, d, t);
      ec += (mpfr_exp_t) t;
    }
  else if (mpz_cmp_ui (d, 0) == 0)
    {
      t = mpz_scan1 (c, 0);
      mpz_tdiv_q_2exp (c, c, t);
      ec += (mpfr_exp_t) t;
    }
  else /* neither c nor d is zero */
    {
      unsigned long v;
      t = mpz_scan1 (c, 0);
      v = mpz_scan1 (d, 0);
      if (v < t)
        t = v;
      mpz_tdiv_q_2exp (c, c, t);
      mpz_tdiv_q_2exp (d, d, t);
      ec += (mpfr_exp_t) t;
    }

  /* now either one of c, d is odd */

  while (ey < 0)
    {
      /* check if x is a square */
      if (ec & 1)
        {
          mpz_mul_2exp (c, c, 1);
          mpz_mul_2exp (d, d, 1);
          ec --;
        }
      /* now ec is even */
      if (mpc_perfect_square_p (a, b, c, d) == 0)
        break;
      mpz_swap (a, c);
      mpz_swap (b, d);
      ec /= 2;
      ey ++;
    }

  if (ey < 0)
    {
      ret = -1; /* not representable */
      goto end;
    }

  /* Now ey >= 0, it thus suffices to check that x^my is representable.
     If my > 0, this is always true. If my < 0, we first try to invert
     (c+I*d)*2^ec.
  */
  if (mpz_cmp_ui (my, 0) < 0)
    {
      /* If my < 0, 1 / (c + I*d) = (c - I*d)/(c^2 + d^2), thus a sufficient
         condition is that c^2 + d^2 is a power of two, assuming |c| <> |d|.
         Assume a prime p <> 2 divides c^2 + d^2,
         then if p does not divide c or d, 1 / (c + I*d) cannot be exact.
         If p divides both c and d, then we can write c = p*c', d = p*d',
         and 1 / (c + I*d) = 1/p * 1/(c' + I*d'). This shows that if 1/(c+I*d)
         is exact, then 1/(c' + I*d') is exact too, and we are back to the
         previous case. In conclusion, a necessary and sufficient condition
         is that c^2 + d^2 is a power of two.
      */
      /* FIXME: we could first compute c^2+d^2 mod a limb for example */
      mpz_mul (a, c, c);
      mpz_addmul (a, d, d);
      t = mpz_scan1 (a, 0);
      if (mpz_sizeinbase (a, 2) != 1 + t) /* a is not a power of two */
        {
          ret = -1; /* not representable */
          goto end;
        }
      /* replace (c,d) by (c/(c^2+d^2), -d/(c^2+d^2)) */
      mpz_neg (d, d);
      ec = -ec - (mpfr_exp_t) t;
      mpz_neg (my, my);
    }

  /* now ey >= 0 and my >= 0, and we want to compute
     [(c + I * d) * 2^ec] ^ (my * 2^ey).

     We first compute [(c + I * d) * 2^ec]^my, then square ey times. */
  t = mpz_sizeinbase (my, 2) - 1;
  mpz_set (a, c);
  mpz_set (b, d);
  ed = ec;
  /* invariant: (a + I*b) * 2^ed = ((c + I*d) * 2^ec)^trunc(my/2^t) */
  while (t-- > 0)
    {
      unsigned long int v, w;
      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;
      if (mpz_tstbit (my, t)) /* multiply by c + I*d */
        {
          mpz_mul (u, a, c);
          mpz_submul (u, b, d); /* ac-bd */
          mpz_mul (b, b, c);
          mpz_addmul (b, a, d); /* bc+ad */
          mpz_swap (a, u);
          ed += ec;
        }
      /* remove powers of two in (a,b) */
      if (mpz_cmp_ui (a, 0) == 0)
        {
          w = mpz_scan1 (b, 0);
          mpz_tdiv_q_2exp (b, b, w);
          ed += (mpfr_exp_t) w;
        }
      else if (mpz_cmp_ui (b, 0) == 0)
        {
          w = mpz_scan1 (a, 0);
          mpz_tdiv_q_2exp (a, a, w);
          ed += (mpfr_exp_t) w;
        }
      else
        {
          w = mpz_scan1 (a, 0);
          v = mpz_scan1 (b, 0);
          if (v < w)
            w = v;
          mpz_tdiv_q_2exp (a, a, w);
          mpz_tdiv_q_2exp (b, b, w);
          ed += (mpfr_exp_t) w;
        }
      if (   (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec
          || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }
  /* now a+I*b = (c+I*d)^my */

  while (ey-- > 0)
    {
      unsigned long sa, sb;

      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;

      /* divide by largest 2^n possible, to avoid many loops for e.g.,
         (2+2*I)^16777216 */
      sa = mpz_scan1 (a, 0);
      sb = mpz_scan1 (b, 0);
      sa = (sa <= sb) ? sa : sb;
      mpz_tdiv_q_2exp (a, a, sa);
      mpz_tdiv_q_2exp (b, b, sa);
      ed += (mpfr_exp_t) sa;

      if (   (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec
          || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }

  ret = mpfr_set_z (mpc_realref(z), a, MPC_RND_RE(rnd));
  ret = MPC_INEX(ret, mpfr_set_z (mpc_imagref(z), b, MPC_RND_IM(rnd)));
  mpfr_mul_2si (mpc_realref(z), mpc_realref(z), ed, MPC_RND_RE(rnd));
  mpfr_mul_2si (mpc_imagref(z), mpc_imagref(z), ed, MPC_RND_IM(rnd));

 end:
  mpz_clear (my);
  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (c);
  mpz_clear (d);
  mpz_clear (u);

  if (ret >= 0 && x_imag)
    fix_sign (z, sign_rex, sign_imx, (z_is_y) ? copy_of_y : y);

  if (z_is_y)
    mpfr_clear (copy_of_y);

  return ret;
}
Пример #9
0
/*-------------------------------------------------------------------*/
static void gmp_poly_mul(gmp_poly_t *p1, gmp_poly_t *p2,
			gmp_poly_t *mod, uint32 free_p2) {

	/* multiply p1(x) by p2(x) modulo mod(x) (assumed monic)
	   If free_p2 is nonzero the coefficients of p2(x) are 
	   freed after being used */

	uint32 i, j;
	uint32 d = mod->degree;
	uint32 d1 = p1->degree;
	uint32 d2 = p2->degree;
	uint32 prod_degree;
	mpz_t tmp[MAX_POLY_DEGREE + 1];

	/* initialize */

	for (i = 0; i < MAX_POLY_DEGREE + 1; i++)
		mpz_init_set_ui(tmp[i], (unsigned long)0);

	/* multiply p1 by the leading coefficient of p2 */

	for (i = 0; i <= d1; i++) {
		mpz_mul(tmp[i], p1->coeff[i], p2->coeff[d2]);
	}
	prod_degree = d1;
	if (free_p2) {
		mpz_realloc2(p2->coeff[d2], 1);
	}

	/* for each of the other coefficients in p2 */

	for (i = d2 - 1; (int32)i >= 0; i--) {

		/* shift the accumulator up by one, bubbling
		   the highest-order coefficient to the lowest */

		for (j = prod_degree; (int32)j >= 0; j--)
			mpz_swap(tmp[j+1], tmp[j]);

		/* add in the product of p1(x) and coefficient
		   i of p2 */

		for (j = d1; j; j--) {
			mpz_addmul(tmp[j], p1->coeff[j], p2->coeff[i]);
		}
		mpz_mul(tmp[j], p1->coeff[j], p2->coeff[i]);
		if (free_p2) {
			mpz_realloc2(p2->coeff[i], 1);
		}

		/* recalculate the degree of the result */

		prod_degree = d + 1;
		while (prod_degree && mpz_sgn(tmp[prod_degree]) == 0)
			prod_degree--;

		/* if it exceeds the degree of mod(x), subtract
		   mod(x) * (leading accumulator coefficient) */

		if (prod_degree <= d)
			continue;

		for (j = d; (int32)j >= 0; j--) {
			mpz_submul(tmp[j], mod->coeff[j], tmp[prod_degree]);
		}
		prod_degree--;
	}

	/* move the result in the accumulator over to p1 */

	for (i = 0; i <= prod_degree; i++) {
		mpz_swap(p1->coeff[i], tmp[i]);
		mpz_clear(tmp[i]);
	}
	for (; i < MAX_POLY_DEGREE + 1; i++)
		mpz_clear(tmp[i]);

	/* recalculate the degree */

	i = prod_degree;
	while (i > 0 && mpz_sgn(p1->coeff[i]) == 0) {
		mpz_realloc2(p1->coeff[i], 1);
		i--;
	}
	p1->degree = i;
}
Пример #10
0
int ecpp_test(unsigned long n)
{
  mpz_t a, b,
        x0, y0,
        xt, yt,
        tmp;
  int z;
  int is_prime = 0;

  if (n <= USHRT_MAX)
  {
    return sieve_test(n);
  }

  mpz_init(a);
  mpz_init(b);
  mpz_init(x0);
  mpz_init(y0);
  mpz_init(xt);
  mpz_init(yt);
  mpz_init(tmp);

#ifdef DEBUG
  gmp_fprintf(stderr, "\nTesting %d with ECPP...\n", n);
#endif /* DEBUG */

  for (;;) /* keep trying while the curve order factoring fails */
  {
    for (;;) /* keep trying while n divides curve discriminant */
    {
      /* initialise a random point P = (x0, y0)
       * and a random elliptic curve E(a, b): y^2 = x^3 + a*x + b
       * with b expressed in terms of (a, x0, y0) so the point lies on the curve
       */

      mpz_set_ui(a, rand() % n);
      mpz_set_ui(x0, rand() % n);
      mpz_set_ui(y0, rand() % n);
      mpz_init(b);

      mpz_mul(b, y0, y0);
      mpz_mul(tmp, x0, x0);
      mpz_submul(b, tmp, x0);
      mpz_submul(b, a, x0);
      mpz_mod_ui(b, b, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\n\tn = %d\n", n);
      gmp_fprintf(stderr, "\tE: y^2 = x^3 + %Zd * x + %Zd\n", a, b);
      gmp_fprintf(stderr, "\tP = (%Zd,%Zd,1)\n", x0, y0);
#endif /* DEBUG */

      /* the discriminant of the curve and n are required to be coprimes
       * -- if not, then either
       *   A) n divides the discriminant -- a new curve must be generated
       *   B) n is composite and a proper factor is found -- the algorithm can
       *      terminate
       */

      ec_discriminant(tmp, a, b);

#ifdef DEBUG
      mpz_mod_ui(tmp, tmp, n);
      gmp_fprintf(stderr, "\tdelta(E/GF(n)) = %Zd\n", tmp);
#endif /* DEBUG */

      mpz_gcd_ui(tmp, tmp, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\tgcd(delta, n) = %Zd\n", tmp);
#endif /* DEBUG */

      if (0 == mpz_cmp_ui(tmp, 1))
      {
        break;
      }
      else if (0 != mpz_cmp_ui(tmp, n))
      {
#ifdef DEBUG
        gmp_fprintf(stderr, "\tfound a proper factor, %d is composite\n", n);
#endif /* DEBUG */
        is_prime = 0;
        goto cleanup_and_return;
      }
    }

    /* P + P != 0, or a new curve is generated
     */
    z = ec_add(xt, yt, x0, y0, 1, x0, y0, 1, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t2 * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 == z)
    {
      continue;
    }

    /* the curve order algorithm failing indicates n is composite
     */
    if (!(ec_order(tmp, a, b, n)))
    {
#ifdef DEBUG
      gmp_fprintf(stderr,
          "\tcurve order algorithm failed, %d must be composite\n", n);
#endif /* DEBUG */

      is_prime = 0;
      break;
    }

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E/GF(n)| = %Zd\n", tmp);
#endif /* DEBUG */

    /* the curve order should be the multiple of 2 and a "probable prime" n --
     * if the order is not even, a new curve is generated
     */
    if (!mpz_even_p(tmp))
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E/GF(n)| is odd, generating new curve...\n");
#endif /* DEBUG */
      continue;
    }

    /* order * P = 0, or n is composite
     */
    z = ec_times(xt, yt, x0, y0, 1, tmp, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E| * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 != z)
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E| * P is non-zero, %d is composite\n", n);
#endif /* DEBUG */
      is_prime = 0;
      break;
    }

    /* at this point, order/2 being a prime implies n is a prime --
     * a recursive call to ecpp_test is used to test order/2 for primality
     */
    mpz_div_ui(tmp, tmp, 2);
    if (ecpp_test(mpz_get_ui(tmp)))
    {
      is_prime = 1;
      break;
    }
  }

cleanup_and_return:
  mpz_clear(a);
  mpz_clear(b);
  mpz_clear(x0);
  mpz_clear(y0);
  mpz_clear(xt);
  mpz_clear(yt);
  mpz_clear(tmp);

  return is_prime;
}
Пример #11
0
/*------------------------------------------------------------------------*/
uint32
handle_collision(poly_coeff_t *c, uint64 p, uint32 special_q,
		uint64 special_q_root, int64 res)
{
	/* the proposed rational coefficient is p*special_q;
	   p and special_q must be coprime. The 'trivial
	   special q' has special_q = 1 and special_q_root = 0 */

	uint64_2gmp(p, c->p);
	mpz_gcd_ui(c->tmp1, c->p, special_q);
	if (mpz_cmp_ui(c->tmp1, 1))
		return 0;

	mpz_mul_ui(c->p, c->p, (unsigned long)special_q);

	/* the corresponding correction to trans_m0 is 
	   special_q_root + res * special_q^2, and can be
	   positive or negative */

	uint64_2gmp(special_q_root, c->tmp1);
	int64_2gmp(res, c->tmp2);
	mpz_set_ui(c->tmp3, special_q);

	mpz_mul(c->tmp3, c->tmp3, c->tmp3);
	mpz_addmul(c->tmp1, c->tmp2, c->tmp3);
	mpz_add(c->m, c->trans_m0, c->tmp1);

	/* a lot can go wrong before this function is called!
	   Check that Kleinjung's modular condition is satisfied */

	mpz_pow_ui(c->tmp1, c->m, c->degree);
	mpz_mul(c->tmp2, c->p, c->p);
	mpz_sub(c->tmp1, c->trans_N, c->tmp1);
	mpz_tdiv_r(c->tmp3, c->tmp1, c->tmp2);
	if (mpz_cmp_ui(c->tmp3, 0)) {
		gmp_printf("crap %Zd %Zd %Zd\n", c->high_coeff, c->p, c->m);
		return 0;
	}

	/* the pair works, now translate the computed m back
	   to the original polynomial. We have

	   computed_m = degree * high_coeff * real_m +
	   			(second_highest_coeff) * p

	   and need to solve for real_m and second_highest_coeff.
	   Per the CADO code: reducing the above modulo
	   degree*high_coeff causes the first term on the right
	   to disappear, so second_highest_coeff can be found
	   modulo degree*high_coeff and real_m then follows */

	mpz_mul_ui(c->tmp1, c->high_coeff, c->degree);
	mpz_tdiv_r(c->tmp2, c->m, c->tmp1);
	mpz_invert(c->tmp3, c->p, c->tmp1);
	mpz_mul(c->tmp2, c->tmp3, c->tmp2);
	mpz_tdiv_r(c->tmp2, c->tmp2, c->tmp1);

	/* make second_highest_coeff as small as possible in
	   absolute value */

	mpz_tdiv_q_2exp(c->tmp3, c->tmp1, 1);
	if (mpz_cmp(c->tmp2, c->tmp3) > 0) {
		mpz_sub(c->tmp2, c->tmp2, c->tmp1);
	}

	/* solve for real_m */
	mpz_submul(c->m, c->tmp2, c->p);
	mpz_tdiv_q(c->m, c->m, c->tmp1);
	return 1;
}
Пример #12
0
 void subtract_multiple(ElementType& result,
                        const ElementType& a,
                        const ElementType& b) const
 {
   mpz_submul(&result, &a, &b);
 }
Пример #13
0
Integer& Integer::maxpyin(Integer& res, const Integer& a, const Integer& x)
{
    if (isZero(a) || isZero(x)) return res;
    mpz_submul( (mpz_ptr)&res.gmp_rep, (mpz_srcptr)&a.gmp_rep, (mpz_srcptr)&x.gmp_rep);
    return res;
}