/* Called when g is supposed to be gcd(a,b), and g = s a + t b, for some t.
   Uses temp1 and temp2 */
static int
gcdext_valid_p (const mpz_t a, const mpz_t b, const mpz_t g, const mpz_t s)
{
  /* It's not clear that gcd(0,0) is well defined, but we allow it and require that
     allow gcd(0,0) = 0. */
  if (mpz_sgn (g) < 0)
    return 0;
  
  if (mpz_sgn (a) == 0)
    {
      /* Must have g == abs (b). Any value for s is in some sense "correct",
	 but it makes sense to require that s == 0. */
      return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
    }
  else if (mpz_sgn (b) == 0)
    {
      /* Must have g == abs (a), s == sign (a) */
      return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
    }

  if (mpz_sgn (g) <= 0)
    return 0;

  if (! (mpz_divisible_p (a, g)
	 && mpz_divisible_p (b, g)
	 && mpz_cmpabs (s, b) <= 0))
    return 0;
      
  mpz_mul(temp1, s, a);
  mpz_sub(temp1, g, temp1);
  mpz_tdiv_qr(temp1, temp2, temp1, b);

  return mpz_sgn (temp2) == 0 && mpz_cmpabs (temp1, a) <= 0;
}
Esempio n. 2
0
/* Called when g is supposed to be gcd(a,b), and g = s a + t b, for some t.
   Uses temp1, temp2 and temp3. */
static int
gcdext_valid_p (const mpz_t a, const mpz_t b, const mpz_t g, const mpz_t s)
{
  /* It's not clear that gcd(0,0) is well defined, but we allow it and require that
     gcd(0,0) = 0. */
  if (mpz_sgn (g) < 0)
    return 0;

  if (mpz_sgn (a) == 0)
    {
      /* Must have g == abs (b). Any value for s is in some sense "correct",
	 but it makes sense to require that s == 0. */
      return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
    }
  else if (mpz_sgn (b) == 0)
    {
      /* Must have g == abs (a), s == sign (a) */
      return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
    }

  if (mpz_sgn (g) <= 0)
    return 0;

  mpz_tdiv_qr (temp1, temp3, a, g);
  if (mpz_sgn (temp3) != 0)
    return 0;

  mpz_tdiv_qr (temp2, temp3, b, g);
  if (mpz_sgn (temp3) != 0)
    return 0;

  /* Require that 2 |s| < |b/g|, or |s| == 1. */
  if (mpz_cmpabs_ui (s, 1) > 0)
    {
      mpz_mul_2exp (temp3, s, 1);
      if (mpz_cmpabs (temp3, temp2) >= 0)
	return 0;
    }

  /* Compute the other cofactor. */
  mpz_mul(temp2, s, a);
  mpz_sub(temp2, g, temp2);
  mpz_tdiv_qr(temp2, temp3, temp2, b);

  if (mpz_sgn (temp3) != 0)
    return 0;

  /* Require that 2 |t| < |a/g| or |t| == 1*/
  if (mpz_cmpabs_ui (temp2, 1) > 0)
    {
      mpz_mul_2exp (temp2, temp2, 1);
      if (mpz_cmpabs (temp2, temp1) >= 0)
	return 0;
    }
  return 1;
}
Esempio n. 3
0
void mpz_sqrtmn
	(mpz_ptr root, mpz_srcptr a, 
	mpz_srcptr p, mpz_srcptr q, mpz_srcptr n)
{
	mpz_t g, u, v;
	mpz_init(g), mpz_init(u), mpz_init(v);
	mpz_gcdext(g, u, v, p, q);
	if (mpz_cmp_ui(g, 1L) == 0)
	{
		mpz_t root_p, root_q, root1, root2, root3, root4;
		/* single square roots */
		mpz_init(root_p), mpz_init(root_q);
		mpz_sqrtmp(root_p, a, p);
		mpz_sqrtmp(root_q, a, q);
		/* construct common square root */
		mpz_init_set(root1, root_q);
		mpz_init_set(root2, root_p);
		mpz_init_set(root3, root_q);
		mpz_init_set(root4, root_p);
		mpz_mul(root1, root1, u);
		mpz_mul(root1, root1, p);
		mpz_mul(root2, root2, v);
		mpz_mul(root2, root2, q);
		mpz_add(root1, root1, root2);
		mpz_mod(root1, root1, n);
		mpz_sqrtmn_2(root2, root1, n);
		mpz_neg(root3, root3);
		mpz_mul(root3, root3, u);
		mpz_mul(root3, root3, p);
		mpz_mul(root4, root4, v);
		mpz_mul(root4, root4, q);
		mpz_add(root3, root3, root4);
		mpz_mod(root3, root3, n);
		mpz_sqrtmn_2 (root4, root3, n);
		/* choose smallest root */
		mpz_set(root, root1);
		if (mpz_cmpabs(root2, root) < 0)
			mpz_set(root, root2);
		if (mpz_cmpabs(root3, root) < 0)
			mpz_set(root, root3);
		if (mpz_cmpabs(root4, root) < 0)
			mpz_set(root, root4);
		mpz_clear(root_p), mpz_clear(root_q);
		mpz_clear(root1), mpz_clear(root2);
		mpz_clear(root3), mpz_clear(root4);
		mpz_clear(g), mpz_clear(u), mpz_clear(v);
		return;
	}
	mpz_clear(g), mpz_clear(u), mpz_clear(v);
	/* error, return zero root */
	mpz_set_ui(root, 0L);
}
Esempio n. 4
0
/* Called when s is supposed to be floor(root(u,z)), and r = u - s^z */
static int
rootrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r, unsigned long z)
{
  mpz_t t;

  mpz_init (t);
  if (mpz_fits_ulong_p (s))
    mpz_ui_pow_ui (t, mpz_get_ui (s), z);
  else
    mpz_pow_ui (t, s, z);
  mpz_sub (t, u, t);
  if (mpz_sgn (t) != mpz_sgn(u) || mpz_cmp (t, r) != 0)
    {
      mpz_clear (t);
      return 0;
    }
  if (mpz_sgn (s) > 0)
    mpz_add_ui (t, s, 1);
  else
    mpz_sub_ui (t, s, 1);
  mpz_pow_ui (t, t, z);
  if (mpz_cmpabs (t, u) <= 0)
    {
      mpz_clear (t);
      return 0;
    }

  mpz_clear (t);
  return 1;
}
Esempio n. 5
0
void
check_one (mpz_ptr x, mpz_ptr y, int want_cmp, int want_cmpabs)
{
  int  got;

  got = mpz_cmp (x, y);
  if ((   got <  0) != (want_cmp <  0)
      || (got == 0) != (want_cmp == 0)
      || (got >  0) != (want_cmp >  0))
    {
      printf ("mpz_cmp got %d want %d\n", got, want_cmp);
      mpz_trace ("x", x);
      mpz_trace ("y", y);
      abort ();
    }

  got = mpz_cmpabs (x, y);
  if ((   got <  0) != (want_cmpabs <  0)
      || (got == 0) != (want_cmpabs == 0)
      || (got >  0) != (want_cmpabs >  0))
    {
      printf ("mpz_cmpabs got %d want %d\n", got, want_cmpabs);
      mpz_trace ("x", x);
      mpz_trace ("y", y);
      abort ();
    }
}
Esempio n. 6
0
ecc_point* sum(ecc_point p1,ecc_point p2){
	ecc_point* result;
	result = malloc(sizeof(ecc_point));
	mpz_init((*result).x);
	mpz_init((*result).y);
	if (mpz_cmp(p1.x,p2.x)==0 && mpz_cmp(p1.y,p2.y)==0)
		result=double_p(p1);
	else
		if( mpz_cmp(p1.x,p2.x)==0 && mpz_cmpabs(p2.y,p1.y)==0)
			result=INFINITY_POINT;
		else{
			mpz_t delta_x,x,y,delta_y,s,s_2;
			mpz_init(delta_x);
			mpz_init(x); mpz_init(y);
			mpz_init(s); mpz_init(s_2);
			mpz_init(delta_y);
			mpz_sub(delta_x,p1.x,p2.x);
			mpz_sub(delta_y,p1.y,p2.y);
			mpz_mod(delta_x,delta_x,prime);
			mpz_invert(delta_x,delta_x,prime);
			mpz_mul(s,delta_x,delta_y);
			mpz_mod(s,s,prime);
			mpz_pow_ui(s_2,s,2);
			mpz_sub(x,s_2,p1.x);
			mpz_sub(x,x,p2.x);
			mpz_mod(x,x,prime);
			mpz_set((*result).x,x);
			mpz_sub(delta_x,p2.x,x);
			mpz_neg(y,p2.y);
			mpz_addmul(y,s,delta_x);
			mpz_mod(y,y,prime);
			mpz_set((*result).y,y);
		};
	return result;	
}
Esempio n. 7
0
/**
\brief 整系数多项式的整数根(不含重数).
\param f 整系数多项式.
\return 整根的list.
\note 利用Zp中的根.
*/
void UniZRootZ_ByZp(std::vector<mpz_ptr> & rootlist,const poly_z & f)
{
    static mpz_t A,B,p,z_temp,nA;
    mpz_init(A);
    mpz_init(B);
    mpz_init(p);
    mpz_init(z_temp);
    mpz_init(nA);
    UniMaxNormZ(A,f);
    uint n=f.size()-1;
    mpz_mul(B,A,A);
    mpz_add(B,B,A);
    mpz_mul_ui(B,B,2*n);
    mpz_add_ui(p,B,1);
    mpz_nextprime(p,p);
    poly_z fp,vi,ui;
    std::vector<mpz_ptr> ulist;
    uint totalroot=0;
    UniPolynomialMod(fp,f,p);
    UniZpRootZp(ulist,fp,p);
    mpz_mul_ui(nA,A,n);
    ui.resize(2);
    mpz_set_ui(ui[1],1);
    for(uint i=0; i<ulist.size(); i++)
    {
        if(mpz_cmpabs(ulist[i],A)<=0)
        {
            mpz_neg(ui[0],ulist[i]);
            UniDivZp(vi,fp,ui,p);
            UniMaxNormZ(z_temp,vi);
            if(mpz_cmp(z_temp,nA)<=0)
            {
                totalroot++;
                resize_z_list(rootlist,totalroot);
                mpz_set(rootlist[totalroot-1],ulist[i]);
            }
        }
    }
    mpz_clear(A);
    mpz_clear(B);
    mpz_clear(p);
    mpz_clear(z_temp);
    mpz_clear(nA);
    fp.resize(0);
    vi.resize(0);
    ui.resize(0);
    resize_z_list(ulist,0);
    std::sort(rootlist.begin(),rootlist.end(),mpz_ptr_less);
    return ;
}
Esempio n. 8
0
int fmpz_cmpabs(const fmpz_t f, const fmpz_t g)
{
    if (f == g) return 0;  /* aliased inputs */

    if (!COEFF_IS_MPZ(*f))
    {
        if (!COEFF_IS_MPZ(*g)) 
        {
            mp_limb_t uf = FLINT_ABS(*f);
            mp_limb_t ug = FLINT_ABS(*g);
            
            return (uf < ug ? -1 : (uf > ug));
        }
        else return -1;
    }
    else 
    {
        if (!COEFF_IS_MPZ(*g)) return 1;  /* f is large, so if g isn't... */
        else return mpz_cmpabs(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)); 
    }
}
Esempio n. 9
0
File: aprcl.c Progetto: rexstout/ecm
/* returns the number of decimal digits of n */
unsigned int
b10_digits (const mpz_t n)
{
  mpz_t x;
  unsigned int size;

  size = mpz_sizeinbase (n, 10);

  /* the GMP documentation says mpz_sizeinbase returns the exact value,
     or one too big, thus:
     (a) either n < 10^(size-1), and n has size-1 digits
     (b) or n >= size-1, and n has size digits
     Note: mpz_sizeinbase returns 1 for n=0, thus we always have size >= 1.
  */
				    
  mpz_init (x);
  mpz_ui_pow_ui (x, 10, size - 1);
  if (mpz_cmpabs (n, x) < 0)
    size --;
  mpz_clear (x);

  return size;
}
Esempio n. 10
0
	// absCompare
	int32_t absCompare(const Integer &a, const Integer &b)
	{
		return mpz_cmpabs( (mpz_srcptr)&(a.gmp_rep), (mpz_srcptr)&(b.gmp_rep));
	}
Esempio n. 11
0
void
spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m)
{
  /* Knuth "Seminumerical Algorithms, Third Edition", section 3.3.4
     (pp. 101-103). */

  /* v[t] = min { sqrt (x[1]^2 + ... + x[t]^2) |
     x[1] + a*x[2] + ... + pow (a, t-1) * x[t] is congruent to 0 (mod m) } */


  /* Variables. */
  unsigned int ui_t;
  unsigned int ui_i, ui_j, ui_k, ui_l;
  mpf_t f_tmp1, f_tmp2;
  mpz_t tmp1, tmp2, tmp3;
  mpz_t U[GMP_SPECT_MAXT][GMP_SPECT_MAXT],
    V[GMP_SPECT_MAXT][GMP_SPECT_MAXT],
    X[GMP_SPECT_MAXT],
    Y[GMP_SPECT_MAXT],
    Z[GMP_SPECT_MAXT];
  mpz_t h, hp, r, s, p, pp, q, u, v;

  /* GMP inits. */
  mpf_init (f_tmp1);
  mpf_init (f_tmp2);
  for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++)
    {
      for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++)
	{
	  mpz_init_set_ui (U[ui_i][ui_j], 0);
	  mpz_init_set_ui (V[ui_i][ui_j], 0);
	}
      mpz_init_set_ui (X[ui_i], 0);
      mpz_init_set_ui (Y[ui_i], 0);
      mpz_init (Z[ui_i]);
    }
  mpz_init (tmp1);
  mpz_init (tmp2);
  mpz_init (tmp3);
  mpz_init (h);
  mpz_init (hp);
  mpz_init (r);
  mpz_init (s);
  mpz_init (p);
  mpz_init (pp);
  mpz_init (q);
  mpz_init (u);
  mpz_init (v);

  /* Implementation inits. */
  if (T > GMP_SPECT_MAXT)
    T = GMP_SPECT_MAXT;			/* FIXME: Lazy. */

  /* S1 [Initialize.] */
  ui_t = 2 - 1;			/* NOTE: `t' in description == ui_t + 1
				   for easy indexing */
  mpz_set (h, a);
  mpz_set (hp, m);
  mpz_set_ui (p, 1);
  mpz_set_ui (pp, 0);
  mpz_set (r, a);
  mpz_pow_ui (s, a, 2);
  mpz_add_ui (s, s, 1);		/* s = 1 + a^2 */

  /* S2 [Euclidean step.] */
  while (1)
    {
      if (g_debug > DEBUG_1)
	{
	  mpz_mul (tmp1, h, pp);
	  mpz_mul (tmp2, hp, p);
	  mpz_sub (tmp1, tmp1, tmp2);
	  if (mpz_cmpabs (m, tmp1))
	    {
	      printf ("***BUG***: h*pp - hp*p = ");
	      mpz_out_str (stdout, 10, tmp1);
	      printf ("\n");
	    }
	}
      if (g_debug > DEBUG_2)
	{
	  printf ("hp = ");
	  mpz_out_str (stdout, 10, hp);
	  printf ("\nh = ");
	  mpz_out_str (stdout, 10, h);
	  printf ("\n");
	  fflush (stdout);
	}

      if (mpz_sgn (h))
	mpz_tdiv_q (q, hp, h);	/* q = floor(hp/h) */
      else
	mpz_set_ui (q, 1);

      if (g_debug > DEBUG_2)
	{
	  printf ("q = ");
	  mpz_out_str (stdout, 10, q);
	  printf ("\n");
	  fflush (stdout);
	}

      mpz_mul (tmp1, q, h);
      mpz_sub (u, hp, tmp1);	/* u = hp - q*h */

      mpz_mul (tmp1, q, p);
      mpz_sub (v, pp, tmp1);	/* v = pp - q*p */

      mpz_pow_ui (tmp1, u, 2);
      mpz_pow_ui (tmp2, v, 2);
      mpz_add (tmp1, tmp1, tmp2);
      if (mpz_cmp (tmp1, s) < 0)
	{
	  mpz_set (s, tmp1);	/* s = u^2 + v^2 */
	  mpz_set (hp, h);	/* hp = h */
	  mpz_set (h, u);	/* h = u */
	  mpz_set (pp, p);	/* pp = p */
	  mpz_set (p, v);	/* p = v */
	}
      else
	break;
    }

  /* S3 [Compute v2.] */
  mpz_sub (u, u, h);
  mpz_sub (v, v, p);

  mpz_pow_ui (tmp1, u, 2);
  mpz_pow_ui (tmp2, v, 2);
  mpz_add (tmp1, tmp1, tmp2);
  if (mpz_cmp (tmp1, s) < 0)
    {
      mpz_set (s, tmp1);	/* s = u^2 + v^2 */
      mpz_set (hp, u);
      mpz_set (pp, v);
    }
  mpf_set_z (f_tmp1, s);
  mpf_sqrt (rop[ui_t - 1], f_tmp1);

  /* S4 [Advance t.] */
  mpz_neg (U[0][0], h);
  mpz_set (U[0][1], p);
  mpz_neg (U[1][0], hp);
  mpz_set (U[1][1], pp);

  mpz_set (V[0][0], pp);
  mpz_set (V[0][1], hp);
  mpz_neg (V[1][0], p);
  mpz_neg (V[1][1], h);
  if (mpz_cmp_ui (pp, 0) > 0)
    {
      mpz_neg (V[0][0], V[0][0]);
      mpz_neg (V[0][1], V[0][1]);
      mpz_neg (V[1][0], V[1][0]);
      mpz_neg (V[1][1], V[1][1]);
    }

  while (ui_t + 1 != T)		/* S4 loop */
    {
      ui_t++;
      mpz_mul (r, a, r);
      mpz_mod (r, r, m);

      /* Add new row and column to U and V.  They are initialized with
	 all elements set to zero, so clearing is not necessary. */

      mpz_neg (U[ui_t][0], r); /* U: First col in new row. */
      mpz_set_ui (U[ui_t][ui_t], 1); /* U: Last col in new row. */

      mpz_set (V[ui_t][ui_t], m); /* V: Last col in new row. */

      /* "Finally, for 1 <= i < t,
	   set q = round (vi1 * r / m),
	   vit = vi1*r - q*m,
	   and Ut=Ut+q*Ui */

      for (ui_i = 0; ui_i < ui_t; ui_i++)
	{
	  mpz_mul (tmp1, V[ui_i][0], r); /* tmp1=vi1*r */
	  zdiv_round (q, tmp1, m); /* q=round(vi1*r/m) */
	  mpz_mul (tmp2, q, m);	/* tmp2=q*m */
	  mpz_sub (V[ui_i][ui_t], tmp1, tmp2);

	  for (ui_j = 0; ui_j <= ui_t; ui_j++) /* U[t] = U[t] + q*U[i] */
	    {
	      mpz_mul (tmp1, q, U[ui_i][ui_j]);	/* tmp=q*uij */
	      mpz_add (U[ui_t][ui_j], U[ui_t][ui_j], tmp1); /* utj = utj + q*uij */
	    }
	}

      /* s = min (s, zdot (U[t], U[t]) */
      vz_dot (tmp1, U[ui_t], U[ui_t], ui_t + 1);
      if (mpz_cmp (tmp1, s) < 0)
	mpz_set (s, tmp1);

      ui_k = ui_t;
      ui_j = 0;			/* WARNING: ui_j no longer a temp. */

      /* S5 [Transform.] */
      if (g_debug > DEBUG_2)
	printf ("(t, k, j, q1, q2, ...)\n");
      do
	{
	  if (g_debug > DEBUG_2)
	    printf ("(%u, %u, %u", ui_t + 1, ui_k + 1, ui_j + 1);

	  for (ui_i = 0; ui_i <= ui_t; ui_i++)
	    {
	      if (ui_i != ui_j)
		{
		  vz_dot (tmp1, V[ui_i], V[ui_j], ui_t + 1); /* tmp1=dot(Vi,Vj). */
		  mpz_abs (tmp2, tmp1);
		  mpz_mul_ui (tmp2, tmp2, 2); /* tmp2 = 2*abs(dot(Vi,Vj) */
		  vz_dot (tmp3, V[ui_j], V[ui_j], ui_t + 1); /* tmp3=dot(Vj,Vj). */

		  if (mpz_cmp (tmp2, tmp3) > 0)
		    {
		      zdiv_round (q, tmp1, tmp3); /* q=round(Vi.Vj/Vj.Vj) */
		      if (g_debug > DEBUG_2)
			{
			  printf (", ");
			  mpz_out_str (stdout, 10, q);
			}

		      for (ui_l = 0; ui_l <= ui_t; ui_l++)
			{
			  mpz_mul (tmp1, q, V[ui_j][ui_l]);
			  mpz_sub (V[ui_i][ui_l], V[ui_i][ui_l], tmp1); /* Vi=Vi-q*Vj */
			  mpz_mul (tmp1, q, U[ui_i][ui_l]);
			  mpz_add (U[ui_j][ui_l], U[ui_j][ui_l], tmp1); /* Uj=Uj+q*Ui */
			}

		      vz_dot (tmp1, U[ui_j], U[ui_j], ui_t + 1); /* tmp1=dot(Uj,Uj) */
		      if (mpz_cmp (tmp1, s) < 0) /* s = min(s,dot(Uj,Uj)) */
			mpz_set (s, tmp1);
		      ui_k = ui_j;
		    }
		  else if (g_debug > DEBUG_2)
		    printf (", #"); /* 2|Vi.Vj| <= Vj.Vj */
		}
	      else if (g_debug > DEBUG_2)
		printf (", *");	/* i == j */
	    }

	  if (g_debug > DEBUG_2)
	    printf (")\n");

	  /* S6 [Advance j.] */
	  if (ui_j == ui_t)
	    ui_j = 0;
	  else
	    ui_j++;
	}
      while (ui_j != ui_k);	/* S5 */

      /* From Knuth p. 104: "The exhaustive search in steps S8-S10
	 reduces the value of s only rarely." */
#ifdef DO_SEARCH
      /* S7 [Prepare for search.] */
      /* Find minimum in (x[1], ..., x[t]) satisfying condition
	 x[k]^2 <= f(y[1], ...,y[t]) * dot(V[k],V[k]) */

      ui_k = ui_t;
      if (g_debug > DEBUG_2)
	{
	  printf ("searching...");
	  /*for (f = 0; f < ui_t*/
	  fflush (stdout);
	}

      /* Z[i] = floor (sqrt (floor (dot(V[i],V[i]) * s / m^2))); */
      mpz_pow_ui (tmp1, m, 2);
      mpf_set_z (f_tmp1, tmp1);
      mpf_set_z (f_tmp2, s);
      mpf_div (f_tmp1, f_tmp2, f_tmp1);	/* f_tmp1 = s/m^2 */
      for (ui_i = 0; ui_i <= ui_t; ui_i++)
	{
	  vz_dot (tmp1, V[ui_i], V[ui_i], ui_t + 1);
	  mpf_set_z (f_tmp2, tmp1);
	  mpf_mul (f_tmp2, f_tmp2, f_tmp1);
	  f_floor (f_tmp2, f_tmp2);
	  mpf_sqrt (f_tmp2, f_tmp2);
	  mpz_set_f (Z[ui_i], f_tmp2);
	}

      /* S8 [Advance X[k].] */
      do
	{
	  if (g_debug > DEBUG_2)
	    {
	      printf ("X[%u] = ", ui_k);
	      mpz_out_str (stdout, 10, X[ui_k]);
	      printf ("\tZ[%u] = ", ui_k);
	      mpz_out_str (stdout, 10, Z[ui_k]);
	      printf ("\n");
	      fflush (stdout);
	    }

	  if (mpz_cmp (X[ui_k], Z[ui_k]))
	    {
	      mpz_add_ui (X[ui_k], X[ui_k], 1);
	      for (ui_i = 0; ui_i <= ui_t; ui_i++)
		mpz_add (Y[ui_i], Y[ui_i], U[ui_k][ui_i]);

	      /* S9 [Advance k.] */
	      while (++ui_k <= ui_t)
		{
		  mpz_neg (X[ui_k], Z[ui_k]);
		  mpz_mul_ui (tmp1, Z[ui_k], 2);
		  for (ui_i = 0; ui_i <= ui_t; ui_i++)
		    {
		      mpz_mul (tmp2, tmp1, U[ui_k][ui_i]);
		      mpz_sub (Y[ui_i], Y[ui_i], tmp2);
		    }
		}
	      vz_dot (tmp1, Y, Y, ui_t + 1);
	      if (mpz_cmp (tmp1, s) < 0)
		mpz_set (s, tmp1);
	    }
	}
      while (--ui_k);
#endif /* DO_SEARCH */
      mpf_set_z (f_tmp1, s);
      mpf_sqrt (rop[ui_t - 1], f_tmp1);
#ifdef DO_SEARCH
      if (g_debug > DEBUG_2)
	printf ("done.\n");
#endif /* DO_SEARCH */
    } /* S4 loop */

  /* Clear GMP variables. */

  mpf_clear (f_tmp1);
  mpf_clear (f_tmp2);
  for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++)
    {
      for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++)
	{
	  mpz_clear (U[ui_i][ui_j]);
	  mpz_clear (V[ui_i][ui_j]);
	}
      mpz_clear (X[ui_i]);
      mpz_clear (Y[ui_i]);
      mpz_clear (Z[ui_i]);
    }
  mpz_clear (tmp1);
  mpz_clear (tmp2);
  mpz_clear (tmp3);
  mpz_clear (h);
  mpz_clear (hp);
  mpz_clear (r);
  mpz_clear (s);
  mpz_clear (p);
  mpz_clear (pp);
  mpz_clear (q);
  mpz_clear (u);
  mpz_clear (v);

  return;
}
Esempio n. 12
0
void
check_one (mpz_t root1, mpz_t x2, unsigned long nth, int i)
{
  mpz_t temp, temp2;
  mpz_t root2, rem2;

  mpz_init (root2);
  mpz_init (rem2);
  mpz_init (temp);
  mpz_init (temp2);

  MPZ_CHECK_FORMAT (root1);

  mpz_rootrem (root2, rem2, x2, nth);
  MPZ_CHECK_FORMAT (root2);
  MPZ_CHECK_FORMAT (rem2);

  mpz_pow_ui (temp, root1, nth);
  MPZ_CHECK_FORMAT (temp);

  mpz_add (temp2, temp, rem2);

  /* Is power of result > argument?  */
  if (mpz_cmp (root1, root2) != 0 || mpz_cmp (x2, temp2) != 0 || mpz_cmpabs (temp, x2) > 0)
    {
      fprintf (stderr, "ERROR after test %d\n", i);
      debug_mp (x2, 10);
      debug_mp (root1, 10);
      debug_mp (root2, 10);
      fprintf (stderr, "nth: %lu\n", nth);
      abort ();
    }

  if (nth > 1 && mpz_cmp_ui (temp, 1L) > 0 && ! mpz_perfect_power_p (temp))
    {
      fprintf (stderr, "ERROR in mpz_perfect_power_p after test %d\n", i);
      debug_mp (temp, 10);
      debug_mp (root1, 10);
      fprintf (stderr, "nth: %lu\n", nth);
      abort ();
    }

  if (nth <= 10000 && mpz_sgn(x2) > 0)		/* skip too expensive test */
    {
      mpz_add_ui (temp2, root1, 1L);
      mpz_pow_ui (temp2, temp2, nth);
      MPZ_CHECK_FORMAT (temp2);

      /* Is square of (result + 1) <= argument?  */
      if (mpz_cmp (temp2, x2) <= 0)
	{
	  fprintf (stderr, "ERROR after test %d\n", i);
	  debug_mp (x2, 10);
	  debug_mp (root1, 10);
	  fprintf (stderr, "nth: %lu\n", nth);
	  abort ();
	}
    }

  mpz_clear (root2);
  mpz_clear (rem2);
  mpz_clear (temp);
  mpz_clear (temp2);
}
Esempio n. 13
0
/* ***********************************************************************************************
 * mpz_selfridge_prp:
 * A "Lucas-Selfridge pseudoprime" n is a "Lucas pseudoprime" using Selfridge parameters of:
 * Find the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) = -1
 * Then use P=1 and Q=(1-D)/4 in the Lucas pseudoprime test.
 * Make sure n is not a perfect square, otherwise the search for D will only stop when D=n.
 * ***********************************************************************************************/
int mpz_selfridge_prp(mpz_t n)
{
  long int d = 5, p = 1, q = 0;
  int max_d = 1000000;
  int jacobi = 0;
  mpz_t zD;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(zD, d);

  while (1)
  {
    jacobi = mpz_jacobi(zD, n);

    /* if jacobi == 0, d is a factor of n, therefore n is composite... */
    /* if d == n, then either n is either prime or 9... */
    if (jacobi == 0)
    {
      if ((mpz_cmpabs(zD, n) == 0) && (mpz_cmp_ui(zD, 9) != 0))
      {
        mpz_clear(zD);
        return PRP_PRIME;
      }
      else
      {
        mpz_clear(zD);
        return PRP_COMPOSITE;
      }
    }
    if (jacobi == -1)
      break;

    /* if we get to the 5th d, make sure we aren't dealing with a square... */
    if (d == 13)
    {
      if (mpz_perfect_square_p(n))
      {
        mpz_clear(zD);
        return PRP_COMPOSITE;
      }
    }

    if (d < 0)
    {
      d *= -1;
      d += 2;
    }
    else
    {
      d += 2;
      d *= -1;
    }

    /* make sure we don't search forever */
    if (d >= max_d)
    {
      mpz_clear(zD);
      return PRP_ERROR;
    }

    mpz_set_si(zD, d);
  }
  mpz_clear(zD);

  q = (1-d)/4;

  return mpz_lucas_prp(n, p, q);

}/* method mpz_selfridge_prp */
Esempio n. 14
0
static PyObject *
GMPY_mpz_is_strongselfridge_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n;
    PyObject *result = 0, *temp = 0;
    long d = 5, p = 1, q = 0, max_d = 1000000;
    int jacobi = 0;
    mpz_t zD;

    if (PyTuple_Size(args) != 1) {
        TYPE_ERROR("is_strong_selfridge_prp() requires 1 integer argument");
        return NULL;
    }

    mpz_init(zD);

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    if (!n) {
        TYPE_ERROR("is_strong_selfridge_prp() requires 1 integer argument");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_strong_selfridge_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }


    mpz_set_ui(zD, d);

    while (1) {
        jacobi = mpz_jacobi(zD, n->z);

        /* if jacobi == 0, d is a factor of n, therefore n is composite... */
        /* if d == n, then either n is either prime or 9... */
        if (jacobi == 0) {
            if ((mpz_cmpabs(zD, n->z) == 0) && (mpz_cmp_ui(zD, 9) != 0)) {
                result = Py_True;
                goto cleanup;
            }
            else {
                result = Py_False;
                goto cleanup;
            }
        }
        if (jacobi == -1)
            break;

        /* if we get to the 5th d, make sure we aren't dealing with a square... */
        if (d == 13) {
            if (mpz_perfect_square_p(n->z)) {
                result = Py_False;
                goto cleanup;
            }
        }

        if (d < 0) {
            d *= -1;
            d += 2;
        }
        else {
            d += 2;
            d *= -1;
        }

        /* make sure we don't search forever */
        if (d >= max_d) {
            VALUE_ERROR("appropriate value for D cannot be found in is_strong_selfridge_prp()");
            goto cleanup;
        }

        mpz_set_si(zD, d);
    }

    q = (1-d)/4;

    /* Since "O" is used, the refcount for n is incremented so deleting
     * temp will not delete n.
     */
    temp = Py_BuildValue("Oll", n, p, q);
    if (!temp)
        goto cleanup;
    result = GMPY_mpz_is_stronglucas_prp(NULL, temp);
    Py_DECREF(temp);
    goto return_result;

  cleanup:
    Py_XINCREF(result);
  return_result:
    mpz_clear(zD);
    Py_DECREF((PyObject*)n);
    return result;
}
Esempio n. 15
0
unsigned long combine_large_primes(QS_t * qs_inf, linalg_t * la_inf, poly_t * poly_inf, 
                                                       FILE *COMB, mpz_t factor)
{
  char new_relation[MPQS_STRING_LENGTH], buf[MPQS_STRING_LENGTH];
  mpqs_lp_entry e[2]; /* we'll use the two alternatingly */
  unsigned long *ei; 
  long ei_size = qs_inf->num_primes;
  mpz_t * N = &qs_inf->mpz_n;
  long old_q;
  mpz_t inv_q, Y1, Y2, new_Y, new_Y1;
  mpz_init(inv_q); mpz_init(Y1); mpz_init(Y2); mpz_init(new_Y); mpz_init(new_Y1);
  long i, l, c = 0;
  unsigned long newrels = 0;

  if (!fgets(buf, MPQS_STRING_LENGTH, COMB)) return 0; /* should not happen */

  ei = (unsigned long *) malloc(sizeof(unsigned long)*ei_size);
  
  /* put first lp relation in row 0 of e */
  set_lp_entry(&e[0], buf);

  i = 1; /* second relation will go into row 1 */
  old_q = e[0].q;
  mpz_set_ui(inv_q, old_q);
  while (!mpz_invert(inv_q, inv_q, *N)) /* can happen */
  {
    /* We have found a factor. It could be N when N is quite small;  
       or we might just have found a divisor by sheer luck. */
    mpz_gcd_ui(inv_q, *N, old_q);
    if (!mpz_cmp(inv_q, *N)) /* pity */
    {
      if (!fgets(buf, MPQS_STRING_LENGTH, COMB)) { return 0; }
      set_lp_entry(&e[0], buf);
      old_q = e[0].q; 
      mpz_set_ui(inv_q, old_q);
      continue;
    }
    mpz_set(factor, inv_q);
    free(ei);
    mpz_clear(inv_q); mpz_clear(Y1); mpz_clear(Y2); mpz_clear(new_Y); mpz_clear(new_Y1);
    return c;
  }
  gmp_sscanf(e[0].Y, "%Zd", Y1);
  
  while (fgets(buf, MPQS_STRING_LENGTH, COMB))
  {
    set_lp_entry(&e[i], buf);
    if (e[i].q != old_q)
    {
      /* switch to combining a new bunch, swapping the rows */
      old_q = e[i].q;
      mpz_set_ui(inv_q, old_q);
      while (!mpz_invert(inv_q, inv_q, *N)) /* can happen */
      {
        mpz_gcd_ui(inv_q, *N, old_q);
        if (!mpz_cmp(inv_q, *N)) /* pity */
        {
          old_q = -1; /* sentinel */
          continue; /* discard this combination */
        }
        mpz_set(factor, inv_q);
        free(ei);
        mpz_clear(inv_q); mpz_clear(Y1); mpz_clear(Y2); mpz_clear(new_Y); mpz_clear(new_Y1);
        return c;
      }
      gmp_sscanf(e[i].Y, "%Zd", Y1);
      i = 1 - i; /* subsequent relations go to other row */
      continue;
    }
    /* count and combine the two we've got, and continue in the same row */
    memset((void *)ei, 0, ei_size * sizeof(long));
    set_exponents(ei, e[0].E);
    set_exponents(ei, e[1].E);
    gmp_sscanf(e[i].Y, "%Zd", Y2);
    
    if (mpz_cmpabs(Y1,Y2)!=0)
    {
       unsigned long * small = la_inf->small;
       fac_t * factor = la_inf->factor;
       unsigned long num_factors = 0;
       unsigned long small_primes = qs_inf->small_primes;
       unsigned long num_primes = qs_inf->num_primes;
       
       c++;
       mpz_mul(new_Y, Y1, Y2);
       mpz_mul(new_Y, new_Y, inv_q);
       mpz_mod(new_Y, new_Y, *N);
    
       mpz_sub(new_Y1, *N, new_Y);
       if (mpz_cmpabs(new_Y1, new_Y) < 0) mpz_set(new_Y, new_Y1);
    
       for (l = 0; l < small_primes; l++)
       {
          small[l] = ei[l];
       }
       for (l = small_primes; l < num_primes; l++)
       {
          if (ei[l])
          {
             factor[num_factors].ind = l;
             factor[num_factors].exp = ei[l];
             num_factors++;
          }
       }
       la_inf->num_factors = num_factors;
          
       newrels += insert_relation(qs_inf, la_inf, poly_inf, new_Y); 
    }
  } /* while */

  free(ei);
  mpz_clear(inv_q); mpz_clear(Y1); mpz_clear(Y2); mpz_clear(new_Y); mpz_clear(new_Y1);

  return newrels;
}
Esempio n. 16
0
static int
pol_expand(curr_poly_t *c, mpz_t gmp_N, mpz_t high_coeff,
		mpz_t gmp_p, mpz_t gmp_d, 
		double coeff_bound, uint32 degree)
{
	uint32 i, j;

	if (mpz_cmp_ui(c->gmp_p, (mp_limb_t)1) == 0)
		mpz_set_ui(c->gmp_help1, (mp_limb_t)1);
	else {
		if (!mpz_invert(c->gmp_help1, gmp_d, gmp_p))
			return 0;
	}

	mpz_set(c->gmp_b[1], c->gmp_help1);
	for (i = 2; i < degree; i++)
		mpz_mul(c->gmp_b[i], c->gmp_b[i-1], c->gmp_help1);

	mpz_set(c->gmp_c[1], gmp_d);
	for (i = 2; i <= degree; i++)
		mpz_mul(c->gmp_c[i], c->gmp_c[i-1], gmp_d);

	mpz_set(c->gmp_a[degree], high_coeff);
	mpz_set(c->gmp_help2, gmp_N);

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

		mpz_mul(c->gmp_help3, c->gmp_a[i+1], c->gmp_c[i+1]);
		mpz_sub(c->gmp_help3, c->gmp_help2, c->gmp_help3);
		mpz_tdiv_q(c->gmp_help2, c->gmp_help3, gmp_p);

		if (i > 0) {
			mpz_tdiv_q(c->gmp_a[i], c->gmp_help2, c->gmp_c[i]);
			mpz_mul(c->gmp_help3, c->gmp_help2, c->gmp_b[i]);
			mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_a[i]);
			mpz_tdiv_r(c->gmp_help4, c->gmp_help3, gmp_p);

			if (mpz_sgn(c->gmp_help4) < 0)
				mpz_add(c->gmp_help4, c->gmp_help4, gmp_p);

			mpz_add(c->gmp_a[i], c->gmp_a[i], c->gmp_help4);
		}
	}
	mpz_set(c->gmp_a[0], c->gmp_help2);

	mpz_tdiv_q_2exp(c->gmp_help1, gmp_d, (mp_limb_t)1);
	for (i = 0; i < degree; i++) {
		for (j = 0; j < MAX_CORRECT_STEPS &&
			    mpz_cmpabs(c->gmp_a[i], c->gmp_help1) > 0; j++) {

			if (mpz_sgn(c->gmp_a[i]) < 0) {
				mpz_add(c->gmp_a[i], c->gmp_a[i], gmp_d);
				mpz_sub(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p);
			}
			else {
				mpz_sub(c->gmp_a[i], c->gmp_a[i], gmp_d);
				mpz_add(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p);
			}
		}

		if (j == MAX_CORRECT_STEPS)
			return 0;
	}

#if 0
	gmp_printf("%+Zd\n", c->gmp_lina[0]);
	gmp_printf("%+Zd\n", c->gmp_lina[1]);
	for (i = 0; i <= degree; i++)
		gmp_printf("%+Zd\n", c->gmp_a[i]);

	printf("coeff ratio = %.5lf\n",
		fabs(mpz_get_d(c->gmp_a[degree-2])) / coeff_bound);
#endif

	if (check_poly(c, c->gmp_a, 
			c->gmp_lina[0], gmp_N, degree) != 1) {
		return 0;
	}

	if (mpz_cmpabs_d(c->gmp_a[degree - 2], coeff_bound) > 0) {
		return 1;
	}
	return 2;
}
Esempio n. 17
0
AlkValue AlkValue::convertDenominator(int _denom, const RoundingMethod how) const
{
  AlkValue in(*this);
  mpz_class in_num(mpq_numref(in.d->m_val.get_mpq_t()));

  AlkValue out; // initialize to zero

  int sign = sgn(in_num);
  if (sign != 0) {
    // sign is either -1 for negative numbers or +1 in all other cases

    AlkValue temp;
    mpz_class denom = _denom;
    // only process in case the denominators are different
    if (mpz_cmpabs(denom.get_mpz_t(), mpq_denref(d->m_val.get_mpq_t())) != 0) {
      mpz_class in_denom(mpq_denref(in.d->m_val.get_mpq_t()));
      mpz_class out_num, out_denom;

      if (sgn(in_denom) == -1) { // my denom is negative
        in_num = in_num * (- in_denom);
        in_num = 1;
      }

      mpz_class remainder;
      int denom_neg = 0;

      // if the denominator is less than zero, we are to interpret it as
      // the reciprocal of its magnitude.
      if (sgn(denom) < 0) {
        mpz_class temp_a;
        mpz_class temp_bc;
        denom        = -denom;
        denom_neg    = 1;
        temp_a       = ::abs(in_num);
        temp_bc      = in_denom * denom;
        remainder    = temp_a % temp_bc;
        out_num      = temp_a / temp_bc;
        out_denom    = denom;
      } else {
        temp = AlkValue(denom, in_denom);
        // the canonicalization required here is part of the ctor
        // temp.d->m_val.canonicalize();

        out_num      = ::abs(in_num * temp.d->m_val.get_num());
        remainder    = out_num % temp.d->m_val.get_den();
        out_num      = out_num / temp.d->m_val.get_den();
        out_denom    = denom;
      }

      if (remainder != 0) {
        switch (how) {
          case RoundFloor:
            if (sign < 0) {
              out_num = out_num + 1;
            }
            break;

          case RoundCeil:
            if (sign > 0) {
              out_num = out_num + 1;
            }
            break;

          case RoundTruncate:
            break;

          case RoundPromote:
            out_num = out_num + 1;
            break;

          case RoundHalfDown:
            if (denom_neg) {
              if ((2 * remainder) > (in_denom * denom)) {
                out_num = out_num + 1;
              }
            } else if ((2 * remainder) > (temp.d->m_val.get_den())) {
              out_num = out_num + 1;
            }
            break;

          case RoundHalfUp:
            if (denom_neg) {
              if ((2 * remainder) >= (in_denom * denom)) {
                out_num = out_num + 1;
              }
            } else if ((2 * remainder) >= temp.d->m_val.get_den()) {
              out_num = out_num + 1;
            }
            break;

          case RoundRound:
            if (denom_neg) {
              if ((remainder * 2) > (in_denom * denom)) {
                out_num = out_num + 1;
              } else if ((2 * remainder) == (in_denom * denom)) {
                if ((out_num % 2) != 0) {
                  out_num = out_num + 1;
                }
              }
            } else {
              if ((remainder * 2) > temp.d->m_val.get_den()) {
                out_num = out_num + 1;
              } else if ((2 * remainder) == temp.d->m_val.get_den()) {
                if ((out_num % 2) != 0) {
                  out_num = out_num + 1;
                }
              }
            }
            break;

          case RoundNever:
            qWarning("AlkValue: have remainder \"%s\"->convert(%d, %d)",
                     qPrintable(toString()), _denom, how);
            break;
        }
      }

      // construct the new output value
      out = AlkValue(out_num * sign, out_denom);

    } else {
      out = *this;
    }
  }
  return out;
}
Esempio n. 18
0
void
check_one (mpz_srcptr a, unsigned long d)
{
  mpz_t  q, r, p, d2exp;
  int    inplace;

  mpz_init (d2exp);
  mpz_init (q);
  mpz_init (r);
  mpz_init (p);

  mpz_set_ui (d2exp, 1L);
  mpz_mul_2exp (d2exp, d2exp, d);

#define INPLACE(fun,dst,src,d)  \
  if (inplace)                  \
    {                           \
      mpz_set (dst, src);       \
      fun (dst, dst, d);        \
    }                           \
  else                          \
    fun (dst, src, d);

  for (inplace = 0; inplace <= 1; inplace++)
    {
      INPLACE (mpz_fdiv_q_2exp, q, a, d);
      INPLACE (mpz_fdiv_r_2exp, r, a, d);

      mpz_mul_2exp (p, q, d);
      mpz_add (p, p, r);
      if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0)
	{
	  printf ("mpz_fdiv_r_2exp result out of range\n");
	  goto error;
	}
      if (mpz_cmp (p, a) != 0)
	{
	  printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n");
	  goto error;
	}


      INPLACE (mpz_cdiv_q_2exp, q, a, d);
      INPLACE (mpz_cdiv_r_2exp, r, a, d);

      mpz_mul_2exp (p, q, d);
      mpz_add (p, p, r);
      if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0)
	{
	  printf ("mpz_cdiv_r_2exp result out of range\n");
	  goto error;
	}
      if (mpz_cmp (p, a) != 0)
	{
	  printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n");
	  goto error;
	}


      INPLACE (mpz_tdiv_q_2exp, q, a, d);
      INPLACE (mpz_tdiv_r_2exp, r, a, d);

      mpz_mul_2exp (p, q, d);
      mpz_add (p, p, r);
      if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a))
	{
	  printf ("mpz_tdiv_r_2exp result wrong sign\n");
	  goto error;
	}
      if (mpz_cmpabs (r, d2exp) >= 0)
	{
	  printf ("mpz_tdiv_r_2exp result out of range\n");
	  goto error;
	}
      if (mpz_cmp (p, a) != 0)
	{
	  printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n");
	  goto error;
	}
    }

  mpz_clear (d2exp);
  mpz_clear (q);
  mpz_clear (r);
  mpz_clear (p);
  return;


 error:
  mpz_trace ("a", a);
  printf    ("d=%lu\n", d);
  mpz_trace ("q", q);
  mpz_trace ("r", r);
  mpz_trace ("p", p);

  mp_trace_base = -16;
  mpz_trace ("a", a);
  printf    ("d=0x%lX\n", d);
  mpz_trace ("q", q);
  mpz_trace ("r", r);
  mpz_trace ("p", p);

  abort ();
}
Esempio n. 19
0
void run_setup(int num_constraints, int num_inputs,
               int num_outputs, int num_vars, mpz_t p,
               string vkey_file, string pkey_file,
               string unprocessed_vkey_file) {

    std::ifstream Amat("./bin/" + std::string(NAME) + ".qap.matrix_a");
    std::ifstream Bmat("./bin/" + std::string(NAME) + ".qap.matrix_b");
    std::ifstream Cmat("./bin/" + std::string(NAME) + ".qap.matrix_c");

    libsnark::default_r1cs_gg_ppzksnark_pp::init_public_params();
    libsnark::r1cs_constraint_system<FieldT> q;

    int Ai, Aj, Bi, Bj, Ci, Cj;
    mpz_t  Acoef, Bcoef, Ccoef;
    mpz_init(Acoef);
    mpz_init(Bcoef);
    mpz_init(Ccoef);

    Amat >> Ai;
    Amat >> Aj;
    Amat >> Acoef;

    if (mpz_cmpabs(Acoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Acoef, p);
        mpz_mod(Acoef, Acoef, p);
    }
    if (mpz_sgn(Acoef) == -1) {
        mpz_add(Acoef, p, Acoef);
    }

    //    std::cout << Ai << " " << Aj << " " << Acoef << std::std::endl;

    Bmat >> Bi;
    Bmat >> Bj;
    Bmat >> Bcoef;
    if (mpz_cmpabs(Bcoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Bcoef, p);
        mpz_mod(Bcoef, Bcoef, p);
    }
    if (mpz_sgn(Bcoef) == -1) {
        mpz_add(Bcoef, p, Bcoef);
    }

    Cmat >> Ci;
    Cmat >> Cj;
    Cmat >> Ccoef;

    if (mpz_cmpabs(Ccoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Ccoef, p);
        mpz_mod(Ccoef, Ccoef, p);
    }
    if (mpz_sgn(Ccoef) == -1) {
        mpz_mul_si(Ccoef, Ccoef, -1);
    } else if(mpz_sgn(Ccoef) == 1) {
        mpz_mul_si(Ccoef, Ccoef, -1);
        mpz_add(Ccoef, p, Ccoef);
    }

    int num_intermediate_vars = num_vars;
    int num_inputs_outputs = num_inputs + num_outputs;

    q.primary_input_size = num_inputs_outputs;
    q.auxiliary_input_size = num_intermediate_vars;

    for (int currentconstraint = 1; currentconstraint <= num_constraints; currentconstraint++) {
        libsnark::linear_combination<FieldT> A, B, C;

        while(Aj == currentconstraint && Amat) {
            if (Ai <= num_intermediate_vars && Ai != 0) {
                Ai += num_inputs_outputs;
            } else if (Ai > num_intermediate_vars) {
                Ai -= num_intermediate_vars;
            }

            FieldT AcoefT(Acoef);
            A.add_term(Ai, AcoefT);
            if(!Amat) {
                break;
            }
            Amat >> Ai;
            Amat >> Aj;
            Amat >> Acoef;
            if (mpz_cmpabs(Acoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Acoef, p);
                mpz_mod(Acoef, Acoef, p);
            }
            if (mpz_sgn(Acoef) == -1) {
                mpz_add(Acoef, p, Acoef);
            }
        }

        while(Bj == currentconstraint && Bmat) {
            if (Bi <= num_intermediate_vars && Bi != 0) {
                Bi += num_inputs_outputs;
            } else if (Bi > num_intermediate_vars) {
                Bi -= num_intermediate_vars;
            }
            //         std::cout << Bi << " " << Bj << " " << Bcoef << std::std::endl;
            FieldT BcoefT(Bcoef);
            B.add_term(Bi, BcoefT);
            if (!Bmat) {
                break;
            }
            Bmat >> Bi;
            Bmat >> Bj;
            Bmat >> Bcoef;
            if (mpz_cmpabs(Bcoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Bcoef, p);
                mpz_mod(Bcoef, Bcoef, p);
            }
            if (mpz_sgn(Bcoef) == -1) {
                mpz_add(Bcoef, p, Bcoef);
            }
        }

        while(Cj == currentconstraint && Cmat) {
            if (Ci <= num_intermediate_vars && Ci != 0) {
                Ci += num_inputs_outputs;
            } else if (Ci > num_intermediate_vars) {
                Ci -= num_intermediate_vars;
            }
            //Libsnark constraints are A*B = C, vs. A*B - C = 0 for Zaatar.
            //Which is why the C coefficient is negated.

            // std::cout << Ci << " " << Cj << " " << Ccoef << std::std::endl;
            FieldT CcoefT(Ccoef);
            C.add_term(Ci, CcoefT);
            if (!Cmat) {
                break;
            }
            Cmat >> Ci;
            Cmat >> Cj;
            Cmat >> Ccoef;
            if (mpz_cmpabs(Ccoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Ccoef, p);
                mpz_mod(Ccoef, Ccoef, p);
            }
            if (mpz_sgn(Ccoef) == -1) {
                mpz_mul_si(Ccoef, Ccoef, -1);
            } else if (mpz_sgn(Ccoef) == 1) {
                mpz_mul_si(Ccoef, Ccoef, -1);
                mpz_add(Ccoef, p, Ccoef);
            }
        }

        q.add_constraint(libsnark::r1cs_constraint<FieldT>(A, B, C));

        //dump_constraint(r1cs_constraint<FieldT>(A, B, C), va, variable_annotations);
    }

    Amat.close();
    Bmat.close();
    Cmat.close();

    libff::start_profiling();
    libsnark::r1cs_gg_ppzksnark_keypair<libsnark::default_r1cs_gg_ppzksnark_pp> keypair = libsnark::r1cs_gg_ppzksnark_generator<libsnark::default_r1cs_gg_ppzksnark_pp>(q);
    libsnark::r1cs_gg_ppzksnark_processed_verification_key<libsnark::default_r1cs_gg_ppzksnark_pp> pvk = libsnark::r1cs_gg_ppzksnark_verifier_process_vk<libsnark::default_r1cs_gg_ppzksnark_pp>(keypair.vk);


    std::ofstream vkey(vkey_file);
    std::ofstream pkey(pkey_file);

    vkey << pvk;
    pkey << keypair.pk;
    pkey.close(); vkey.close();

    if (unprocessed_vkey_file.length() > 0) {
        std::ofstream unprocessed_vkey(unprocessed_vkey_file);
        unprocessed_vkey << keypair.vk;
        unprocessed_vkey.close();
    }
}
Esempio n. 20
0
static int
mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q,
           mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
{
  mpfr_exp_t ex, ey;
  int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
  mpz_t mx, my, r;
  int tiny = 0;

  MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
          || MPFR_IS_ZERO (y))
        {
          /* for remquo, quo is undefined */
          MPFR_SET_NAN (rem);
          MPFR_RET_NAN;
        }
      else                      /* either y is Inf and x is 0 or non-special,
                                   or x is 0 and y is non-special,
                                   in both cases the quotient is zero. */
        {
          if (quo)
            *quo = 0;
          return mpfr_set (rem, x, rnd);
        }
    }

  /* now neither x nor y is NaN, Inf or zero */

  mpz_init (mx);
  mpz_init (my);
  mpz_init (r);

  ex = mpfr_get_z_2exp (mx, x);  /* x = mx*2^ex */
  ey = mpfr_get_z_2exp (my, y);  /* y = my*2^ey */

  /* to get rid of sign problems, we compute it separately:
     quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
     quo(-x,y) = -quo(x,y), rem(-x,y)  = -rem(x,y)
     thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
  sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
  mpz_abs (mx, mx);
  mpz_abs (my, my);
  q_is_odd = 0;

  /* divide my by 2^k if possible to make operations mod my easier */
  {
    unsigned long k = mpz_scan1 (my, 0);
    ey += k;
    mpz_fdiv_q_2exp (my, my, k);
  }

  if (ex <= ey)
    {
      /* q = x/y = mx/(my*2^(ey-ex)) */

      /* First detect cases where q=0, to avoid creating a huge number
         my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy =
         mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and
         y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1
         the quotient is 0 */
      if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) <
          ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
        {
          tiny = 1;
          mpz_set (r, mx);
          mpz_set_ui (mx, 0);
        }
      else
        {
          mpz_mul_2exp (my, my, ey - ex);   /* divide mx by my*2^(ey-ex) */

          /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */
          mpz_tdiv_qr (mx, r, mx, my);
          /* 0 <= |r| <= |my|, r has the same sign as mx */
        }

      if (rnd_q == MPFR_RNDN)
        q_is_odd = mpz_tstbit (mx, 0);
      if (quo)                  /* mx is the quotient */
        {
          mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
          *quo = mpz_get_si (mx);
        }
    }
  else                          /* ex > ey */
    {
      if (quo) /* remquo case */
        /* for remquo, to get the low WANTED_BITS more bits of the quotient,
           we first compute R =  X mod Y*2^WANTED_BITS, where X and Y are
           defined below. Then the low WANTED_BITS of the quotient are
           floor(R/Y). */
        mpz_mul_2exp (my, my, WANTED_BITS);     /* 2^WANTED_BITS*Y */

      else if (rnd_q == MPFR_RNDN) /* remainder case */
        /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
           Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
           To be able to perform the rounding, we need the least significant
           bit of the quotient, i.e., one more bit in the remainder,
           which is obtained by dividing by 2Y. */
        mpz_mul_2exp (my, my, 1);       /* 2Y */

      mpz_set_ui (r, 2);
      mpz_powm_ui (r, r, ex - ey, my);  /* 2^(ex-ey) mod my */
      mpz_mul (r, r, mx);
      mpz_mod (r, r, my);

      if (quo)                  /* now 0 <= r < 2^WANTED_BITS*Y */
        {
          mpz_fdiv_q_2exp (my, my, WANTED_BITS);   /* back to Y */
          mpz_tdiv_qr (mx, r, r, my);
          /* oldr = mx*my + newr */
          *quo = mpz_get_si (mx);
          q_is_odd = *quo & 1;
        }
      else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */
        {
          mpz_fdiv_q_2exp (my, my, 1);     /* back to Y */
          /* least significant bit of q */
          q_is_odd = mpz_cmpabs (r, my) >= 0;
          if (q_is_odd)
            mpz_sub (r, r, my);
        }
      /* now 0 <= |r| < |my|, and if needed,
         q_is_odd is the least significant bit of q */
    }

  if (mpz_cmp_ui (r, 0) == 0)
    {
      inex = mpfr_set_ui (rem, 0, MPFR_RNDN);
      /* take into account sign of x */
      if (signx < 0)
        mpfr_neg (rem, rem, MPFR_RNDN);
    }
  else
    {
      if (rnd_q == MPFR_RNDN)
        {
          /* FIXME: the comparison 2*r < my could be done more efficiently
             at the mpn level */
          mpz_mul_2exp (r, r, 1);
          /* if tiny=1, we should compare r with my*2^(ey-ex) */
          if (tiny)
            {
              if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) <
                  ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
                compare = 0; /* r*2^ex < my*2^ey */
              else
                {
                  mpz_mul_2exp (my, my, ey - ex);
                  compare = mpz_cmpabs (r, my);
                }
            }
          else
            compare = mpz_cmpabs (r, my);
          mpz_fdiv_q_2exp (r, r, 1);
          compare = ((compare > 0) ||
                     ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
          /* if compare != 0, we need to subtract my to r, and add 1 to quo */
          if (compare)
            {
              mpz_sub (r, r, my);
              if (quo && (rnd_q == MPFR_RNDN))
                *quo += 1;
            }
        }
      /* take into account sign of x */
      if (signx < 0)
        mpz_neg (r, r);
      inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd);
    }

  if (quo)
    *quo *= sign;

  mpz_clear (mx);
  mpz_clear (my);
  mpz_clear (r);

  return inex;
}