示例#1
0
  void
PaillierAdapter::keygen( unsigned int modulusbits,
    paillier_pubkey* pub,
    paillier_prvkey* prv,
    unsigned int init_s)
{
  mpz_t p, q;

  mpz_inits(p, q, NULL);

  /* pick random (modulusbits/2)-bit primes p and q */
  do
  {
    get_prime_of_size(p, modulusbits / 2);
    get_prime_of_size(q, modulusbits / 2);

    mpz_mul(*pub->getnj(1), p, q);

  }while(mpz_sizeinbase(*pub->getnj(1), 2) != modulusbits);

  pub->setbits(modulusbits);
  pub->setinit_s(init_s);
  pub->complete_key(init_s+1); /*we don't know if it will be used beyond one level*/

  /* compute the private key lambda = lcm(p-1,q-1) */
  mpz_sub_ui(p, p, 1);
  mpz_sub_ui(q, q, 1);
  mpz_lcm(prv->d, p, q);
  mpz_invert(prv->inv_d, prv->d ,*pub->getnj(init_s));

  /* clear temporary integers */
  mpz_clears(p, q, NULL);
}
void
preprocess_generators<mpq_class, mpz_class> (
  const std::vector<std::vector<mpq_class> >& generators_in,
  std::vector<std::vector<mpz_class> >& generators_out,
  mpz_class& scaling_factor)
{
  const int d = generators_in[0].size();
  const int n = generators_in.size();
  generators_out = std::vector<std::vector<mpz_class> > (n, std::vector<mpz_class> (d) );

  mpz_class generators_den_lcm = generators_in[0][0].get_den();
  for ( const auto& v : generators_in ) {
    for ( const mpq_class& x : v ) {
      mpz_lcm ( generators_den_lcm.get_mpz_t(),
                generators_den_lcm.get_mpz_t(),
                x.get_den_mpz_t() );
    }
  }

  for ( int k = 0; k < n; ++k ) {
    for ( int i = 0; i < d; ++i ) {
      const mpq_class& x = generators_in[k][i];
      generators_out[k][i] = (generators_den_lcm * x.get_num()) / x.get_den();
    }
  }

  scaling_factor = generators_den_lcm;
}
 int_t
 lcf(const vector<int_t>& nums)
 {
   int_t result = 1;
   for (size_t i = 0; i < nums.size(); ++i)
     mpz_lcm(result.get_mpz_t(), result.get_mpz_t(), nums[i].get_mpz_t());
   return result;
 }
示例#4
0
RCP<const Integer> lcm(const Integer &a, const Integer &b)
{
    mpz_class c;

    mpz_lcm(c.get_mpz_t(), a.as_mpz().get_mpz_t(), b.as_mpz().get_mpz_t());

    return integer(c);
}
示例#5
0
/* lcm */
static int lcm(void *a, void *b, void *c)
{
   LTC_ARGCHK(a != NULL);
   LTC_ARGCHK(b != NULL);
   LTC_ARGCHK(c != NULL);
   mpz_lcm(c, a, b);
   return CRYPT_OK;
}
示例#6
0
文件: random.c 项目: ptigwe/imitation
void lcm(mpz_t l, mpz_t *num, gint n)
{
    mpz_t tmp;
    mpz_init(tmp);
    mpz_set_si(tmp, 1);
    
    mpz_lcm(l, num[0], tmp);
    
    gint i;
    for(i = 1; i < n; ++i)
    {
        mpz_set(tmp, l);
        mpz_lcm(l, tmp, num[i]);
    }
    
    mpz_clear(tmp);
}
示例#7
0
void
paillier_keygen( int modulusbits,
								 paillier_pubkey_t** pub,
								 paillier_prvkey_t** prv,
								 paillier_get_rand_t get_rand )
{
	mpz_t p;
	mpz_t q;
	gmp_randstate_t rand;

	/* allocate the new key structures */

	*pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t));
	*prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t));

	/* initialize our integers */

	mpz_init((*pub)->n);
	mpz_init((*pub)->n_squared);
	mpz_init((*pub)->n_plusone);
	mpz_init((*prv)->lambda);
	mpz_init((*prv)->x);
	mpz_init(p);
	mpz_init(q);

	/* pick random (modulusbits/2)-bit primes p and q */

	init_rand(rand, get_rand, modulusbits / 8 + 1);
	do
	{
		do
			mpz_urandomb(p, rand, modulusbits / 2);
		while( !mpz_probab_prime_p(p, 10) );

		do
			mpz_urandomb(q, rand, modulusbits / 2);
		while( !mpz_probab_prime_p(q, 10) );

		/* compute the public modulus n = p q */

		mpz_mul((*pub)->n, p, q);
	} while( !mpz_tstbit((*pub)->n, modulusbits - 1) );
	complete_pubkey(*pub);
	(*pub)->bits = modulusbits;

	/* compute the private key lambda = lcm(p-1,q-1) */

	mpz_sub_ui(p, p, 1);
	mpz_sub_ui(q, q, 1);
	mpz_lcm((*prv)->lambda, p, q);
	complete_prvkey(*prv, *pub);

	/* clear temporary integers and randstate */

	mpz_clear(p);
	mpz_clear(q);
  gmp_randclear(rand);
}
示例#8
0
文件: gmp.hpp 项目: julien-f/jfcpp
mpz_class
lcm<mpz_class>(const mpz_class &a, const mpz_class &b)
{
	mpz_class result;

	mpz_lcm(result.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());

	return result;
}
示例#9
0
文件: Qdet.c 项目: BrentBaccala/CoCoA
static void compute_col_lcm(mpz_t *col_lcm, Qmat M)
{
  int i, j, n;
  n = M->nrows;
  for (j=0; j < n; j++)
  {
    mpz_set_ui(col_lcm[j], 0);
    for (i=0; i < n; i++)
      mpz_lcm(col_lcm[j], col_lcm[j], mpq_denref(M->entry[i][j]));
  }
}
示例#10
0
static PyObject *
GMPy_MPZ_Function_LCM(PyObject *self, PyObject *args)
{
    PyObject *arg0, *arg1;
    MPZ_Object *result = NULL, *tempa = NULL, *tempb = NULL;

    if(PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("lcm() requires 'mpz','mpz' arguments");
        return NULL;
    }

    if (!(result = GMPy_MPZ_New(NULL))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    arg0 = PyTuple_GET_ITEM(args, 0);
    arg1 = PyTuple_GET_ITEM(args, 1);

    if (MPZ_Check(arg0) && MPZ_Check(arg1)) {
        mpz_lcm(result->z, MPZ(arg0), MPZ(arg1));
    }
    else {
        if (!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) ||
            !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) {

            TYPE_ERROR("lcm() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempa);
            Py_XDECREF((PyObject*)tempb);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_lcm(result->z, tempa->z, tempb->z);
        Py_DECREF((PyObject*)tempa);
        Py_DECREF((PyObject*)tempb);
    }
    return (PyObject*)result;
}
示例#11
0
void damgard_jurik::key_gen(int modulusbits) {
    mpz_t p, q;

    gmp_randstate_t rand;
    mpz_init(pubkey->n);
    mpz_init(pubkey->g);
    mpz_init(prvkey->lambda);
    mpz_init(p);
    mpz_init(q);

    init_rand(rand, modulusbits / 8 + 1);
    do
    {
        do
            mpz_urandomb(p, rand, modulusbits / 2);
        while( !mpz_probab_prime_p(p, 10) );

        do
            mpz_urandomb(q, rand, modulusbits / 2);
        while( !mpz_probab_prime_p(q, 10) );

        /* compute the public modulus n = p q */

        mpz_mul(pubkey->n, p, q);
    } while( !mpz_tstbit(pubkey->n, modulusbits - 1));
    pubkey->bits = modulusbits;

    mpz_add_ui(pubkey->g, pubkey->n, 1);
    pubkey->n_j = new mpz_t[s_max + 2];
    pubkey->k_n = new mpz_t[s_max + 2];
    mpz_init(pubkey->n_j[0]);
    mpz_set_ui(pubkey->n_j[0], 1);
    mpz_init(pubkey->k_n[0]);
    mpz_set_ui(pubkey->k_n[0], 1);
    for (int i = 1;i <= s_max + 1;i++) {
        mpz_init(pubkey->n_j[i]);
        mpz_mul(pubkey->n_j[i], pubkey->n_j[i - 1], pubkey->n);
        mpz_init(pubkey->k_n[i]);
        mpz_mul_ui(pubkey->k_n[i], pubkey->k_n[i - 1], i);
    }

    /* Compute Private Key */
    mpz_sub_ui(p, p, 1);
    mpz_sub_ui(q, q, 1);
    mpz_lcm(prvkey->lambda, p, q);

    mpz_clear(p);
    mpz_clear(q);
    gmp_randclear(rand);
}
示例#12
0
void QtGMP::lcm()
{
    //QApplication::aboutQt();
    QString s("");
    mpz_t aa,bb,cc;
    char *str=0;
    mpz_init(cc);
    mpz_init_set_str(aa,qPrintable(this->lineEdit1->text()),10);
    mpz_init_set_str(bb,qPrintable(this->lineEdit2->text()),10);
    mpz_lcm(cc,aa,bb);
    //  gmp_printf("A:\t%Zd\nB:\t%Zd\nLCM(A,B):\t%Zd\n\n\n",aa,bb,cc);
    s.sprintf("A:\t%s\nB:\t%s\nLCM(A,B):\t%s\n",mpz_get_str(str,10,aa),mpz_get_str(str,10,bb),mpz_get_str(str,10,cc));
    this->textEdit->setText(s);
    mpz_clears(aa,bb,cc,'\0');
}
示例#13
0
文件: QQ.cpp 项目: ChristineJost/M2
bool QQ::lower_associate_divisor(ring_elem &f, const ring_elem g) const
{
  gmp_QQ a = MPQ_VAL(f);
  gmp_QQ b = MPQ_VAL(g);
  int sa = mpq_sgn(a);
  int sb = mpq_sgn(b);
  int s = (sa == 0 ? sb : sa);
  gmp_QQ result = QQ::new_elem();

  mpz_gcd(mpq_numref(result), mpq_numref(a), mpq_numref(b));
  mpz_lcm(mpq_denref(result), mpq_denref(a), mpq_denref(b));
  if (s != mpq_sgn(result))
    mpq_neg(result,result);
  f = MPQ_RINGELEM(result);
  return true; // the answer could become lower, if a newer g has a larger denom
}
示例#14
0
文件: QQ.cpp 项目: ChristineJost/M2
void QQ::lower_content(ring_elem &c, const ring_elem g) const
{
  if (is_zero(c))
    {
      c = g;
      return;
    }
  gmp_QQ a = MPQ_VAL(c);
  gmp_QQ b = MPQ_VAL(g);
  int sa = mpq_sgn(a);
  gmp_QQ result = QQ::new_elem();

  mpz_gcd(mpq_numref(result), mpq_numref(a), mpq_numref(b));
  mpz_lcm(mpq_denref(result), mpq_denref(a), mpq_denref(b));
  if (sa != mpq_sgn(result))
    mpq_neg(result,result);
  c = MPQ_RINGELEM(result);
}
示例#15
0
文件: djcs.c 项目: tiehuis/libhcs
int djcs_generate_key_pair(djcs_public_key *pk, djcs_private_key *vk,
                           hcs_random *hr, unsigned long s, unsigned long bits)
{
    mpz_t p, q;

    pk->n = malloc(sizeof(mpz_t) * (s + 1));
    if (pk->n == NULL) return 1;
    vk->n = malloc(sizeof(mpz_t) * (s + 1));
    if (vk->n == NULL) return 1;

    pk->s = s;
    vk->s = s;

    mpz_init(p);
    mpz_init(q);
    mpz_init(pk->n[0]);
    mpz_init(vk->n[0]);

    mpz_random_prime(p, hr->rstate, 1 + (bits-1)/2);
    mpz_random_prime(q, hr->rstate, 1 + (bits-1)/2);
    mpz_mul(pk->n[0], p, q);
    mpz_sub_ui(vk->d, p, 1);
    mpz_sub_ui(q, q, 1);
    mpz_lcm(vk->d, vk->d, q);
    mpz_add_ui(q, q, 1);
    mpz_add_ui(pk->g, pk->n[0], 1);

    mpz_set(vk->n[0], pk->n[0]);
    for (unsigned long i = 1; i <= pk->s; ++i) {
        mpz_init_set(pk->n[i], pk->n[i-1]);
        mpz_mul(pk->n[i], pk->n[i], pk->n[0]);
        mpz_init_set(vk->n[i], pk->n[i]);
    }

    mpz_powm(vk->mu, pk->g, vk->d, vk->n[vk->s]);
    dlog_s(vk, vk->mu, vk->mu);
    mpz_invert(vk->mu, vk->mu, vk->n[vk->s-1]);

    mpz_clear(p);
    mpz_clear(q);

    return 0;
}
示例#16
0
void
mpz_lcm_ui (mpz_ptr r, mpz_srcptr u, mpir_ui v)
{
  mp_size_t      usize;
  mp_srcptr      up;
  mp_ptr         rp;
  mpir_ui         g;
  mp_limb_t      c;

#if BITS_PER_UI > GMP_NUMB_BITS  /* avoid warnings about shift amount */
  if (v > GMP_NUMB_MAX)
    {
      mpz_t vz;
      mp_limb_t vlimbs[2];
      vlimbs[0] = v & GMP_NUMB_MASK;
      vlimbs[1] = v >> GMP_NUMB_BITS;
      PTR(vz) = vlimbs;
      SIZ(vz) = 2;
      mpz_lcm (r, u, vz);
      return;
    }
示例#17
0
void damgard_jurik::key_gen(int modulusbits) {
    mpz_t p, q;

    gmp_randstate_t rand;
    mpz_init(pubkey->n);
    mpz_init(pubkey->g);
    mpz_init(prvkey->lambda);
    mpz_init(p);
    mpz_init(q);

    init_rand(rand, modulusbits / 8 + 1);
    do
    {
        do
            mpz_urandomb(p, rand, modulusbits / 2);
        while( !mpz_probab_prime_p(p, 10) );

        do
            mpz_urandomb(q, rand, modulusbits / 2);
        while( !mpz_probab_prime_p(q, 10) );

        /* compute the public modulus n = p q */

        mpz_mul(pubkey->n, p, q);
    } while( !mpz_tstbit(pubkey->n, modulusbits - 1));
    pubkey->bits = modulusbits;

    mpz_add_ui(pubkey->g, pubkey->n, 1);

    compute_cache();

    /* Compute Private Key */
    mpz_sub_ui(p, p, 1);
    mpz_sub_ui(q, q, 1);
    mpz_lcm(prvkey->lambda, p, q);

    mpz_clear(p);
    mpz_clear(q);
    gmp_randclear(rand);
}
示例#18
0
void
_fmpq_poly_set_array_mpq(fmpz * poly, fmpz_t den, const mpq_t * a, long n)
{
    long i;
    mpz_t d, t;
    
    mpz_init_set_ui(d, 1);
    mpz_init(t);
    for (i = 0; i < n; i++)
        mpz_lcm(d, d, mpq_denref(a[i]));
    
    for (i = 0; i < n; i++)
    {
        mpz_divexact(t, d, mpq_denref(a[i]));
        mpz_mul((mpz_ptr) mpq_numref(a[i]), (mpz_ptr) mpq_numref(a[i]), t);
    }
    
    for (i = 0; i < n; i++)
        fmpz_set_mpz(poly + i, (mpz_ptr) mpq_numref(a[i]));
    
    fmpz_set_mpz(den, d);
    mpz_clear(d);
    mpz_clear(t);
}
 boost::multiprecision::mpz_int PPCM<>(boost::multiprecision::mpz_int a, boost::multiprecision::mpz_int b)
 {
     boost::multiprecision::mpz_int resultat;
     mpz_lcm(resultat.backend().data(), a.backend().data(), b.backend().data());
     return resultat;
 }
示例#20
0
void
check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig)
{
  mpz_t  got, x, y;
  int    negx, negy, swap, inplace;

  mpz_init (got);
  mpz_init_set (x, x_orig);
  mpz_init_set (y, y_orig);

  for (swap = 0; swap < 2; swap++)
    {
      mpz_swap (x, y);

      for (negx = 0; negx < 2; negx++)
	{
	  mpz_neg (x, x);

	  for (negy = 0; negy < 2; negy++)
	    {
	      mpz_neg (y, y);

	      for (inplace = 0; inplace <= 1; inplace++)
		{
		  if (inplace)
		    { mpz_set (got, x); mpz_lcm (got, got, y); }
		  else
		    mpz_lcm (got, x, y);
		  MPZ_CHECK_FORMAT (got);

		  if (mpz_cmp (got, want) != 0)
		    {
		      printf ("mpz_lcm wrong, inplace=%d\n", inplace);
		    fail:
		      mpz_trace ("x", x);
		      mpz_trace ("y", y);
		      mpz_trace ("got", got);
		      mpz_trace ("want", want);
		      abort ();
		    }

		  if (mpz_fits_ulong_p (y))
		    {
		      unsigned long  yu = mpz_get_ui (y);
		      if (inplace)
			{ mpz_set (got, x); mpz_lcm_ui (got, got, yu); }
		      else
			mpz_lcm_ui (got, x, yu);

		      if (mpz_cmp (got, want) != 0)
			{
			  printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace);
			  printf    ("yu=%lu\n", yu);
			  goto fail;
			}
		    }
		}
	    }
	}
    }

  mpz_clear (got);
  mpz_clear (x);
  mpz_clear (y);
}
示例#21
0
/*
Generate Private Public Keys
*/
void keysGeneration(){
	//char* initNbChar = malloc(sizeof(char) * (initNbLength+1));
	char* initNbChar;
	//mpz_init(gcdResult);
	//mpz_init(nn);
	//mpz_init(lambda);
	do{
		 initNbChar = malloc(sizeof(char) * (initNbLength+1));
		generateInitNb(initNbChar, initNbLength);
		mpz_set_str(initNbMpz, initNbChar, 10/*decimal*/);
		mpz_nextprime (p, initNbMpz);
		
		initNbChar = malloc(sizeof(char) * (initNbLength+1));
		generateInitNb(initNbChar, initNbLength);
		mpz_set_str(initNbMpz, initNbChar, 10/*decimal*/);
		mpz_nextprime (q, initNbMpz);

//6666666666666666666666666666666666666
		//mpz_init_set_str(p,"7",10);
		//mpz_init_set_str(q,"11",10);
//6666666666666666666666666666




		mpz_sub_ui(p_1, p, 1);
		mpz_sub_ui(q_1, q, 1);
		mpz_mul(n, p, q);
		mpz_mul(tmpI, p_1, q_1);
		mpz_gcd(gcdResult, tmpI, n);
		
	}while(mpz_cmp_ui(gcdResult, 1) != 0); // check if (gcd(pq, (p-1)(q-1)) = 1
//	mpz_mul(n, p, q);
		mpz_mul(nn, n, n);
		mpz_lcm(lambda, p_1, q_1);
		
	// generate a number g within the range 0 to n*n-1 inclusive ! 
	// this way i can get rid of using mod n^2 on this step 
	gmp_randstate_t state;
	gmp_randinit_mt (state); // initiallize state with Mersenne Twister which is basically fast one !
	mpz_urandomm(g, state, nn);
//66666666666666666666666666666666
	//mpz_init_set_str(g,"5652",10);
//666666666666666666666666666666666666666
	// Now we check if g is good enough for us 
	mpz_powm(tmpI, g/*base*/, lambda/*exp*/, nn/*mod*/); // tmp = base^exp modulo mod 
	// now L(u) = (u-1)/n
	mpz_sub_ui(tmpI, tmpI, 1);
	mpz_tdiv_q(tmpI, tmpI, n);

	mpz_gcd(gcdResult, n, tmpI);
	if (mpz_cmp_ui(gcdResult, 1) != 0){
		printf("G is not proper !!!\n");
		exit(EXIT_FAILURE);
	}
	


	printf("Keys Generation Result : \n");
	printf("Start -- \n");
	printf("Public Key  : \n");
	gmp_printf ("\nn = %Zd\n", n);
	gmp_printf ("\ng= %Zd\n", g);
	printf("\nPrivate Key  : \n");
	gmp_printf ("\nlambda = %Zd\n", lambda);
	printf("Micro :3 \n");
	printf("End --  \n");
	
	
}
示例#22
0
void
hex_random_op3 (enum hex_random_op op,  unsigned long maxbits,
		char **ap, char **bp, char **rp)
{
  mpz_t a, b, r;
  unsigned long abits, bbits;
  unsigned signs;

  mpz_init (a);
  mpz_init (b);
  mpz_init (r);

  abits = gmp_urandomb_ui (state, 32) % maxbits;
  bbits = gmp_urandomb_ui (state, 32) % maxbits;

  mpz_rrandomb (a, state, abits);
  mpz_rrandomb (b, state, bbits);

  signs = gmp_urandomb_ui (state, 3);
  if (signs & 1)
    mpz_neg (a, a);
  if (signs & 2)
    mpz_neg (b, b);

  switch (op)
    {
    default:
      abort ();
    case OP_ADD:
      mpz_add (r, a, b);
      break;
    case OP_SUB:
      mpz_sub (r, a, b);
      break;
    case OP_MUL:
      mpz_mul (r, a, b);
      break;
    case OP_GCD:
      if (signs & 4)
	{
	  /* Produce a large gcd */
	  unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
	  mpz_rrandomb (r, state, gbits);
	  mpz_mul (a, a, r);
	  mpz_mul (b, b, r);
	}
      mpz_gcd (r, a, b);
      break;
    case OP_LCM:
      if (signs & 4)
	{
	  /* Produce a large gcd */
	  unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
	  mpz_rrandomb (r, state, gbits);
	  mpz_mul (a, a, r);
	  mpz_mul (b, b, r);
	}
      mpz_lcm (r, a, b);
      break;
    case OP_AND:
      mpz_and (r, a, b);
      break;
    case OP_IOR:
      mpz_ior (r, a, b);
      break;
    case OP_XOR:
      mpz_xor (r, a, b);
      break;
    }

  gmp_asprintf (ap, "%Zx", a);
  gmp_asprintf (bp, "%Zx", b);
  gmp_asprintf (rp, "%Zx", r);

  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (r);
}
示例#23
0
文件: pexpr.c 项目: AllardJ/Tomato
/* Evaluate the expression E and put the result in R.  */
void
mpz_eval_expr (mpz_ptr r, expr_t e)
{
  mpz_t lhs, rhs;

  switch (e->op)
    {
    case LIT:
      mpz_set (r, e->operands.val);
      return;
    case PLUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_add (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MINUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_sub (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MULT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_mul (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case DIV:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_q (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MOD:
      mpz_init (rhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_abs (rhs, rhs);
      mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
      mpz_clear (rhs);
      return;
    case REM:
      /* Check if lhs operand is POW expression and optimize for that case.  */
      if (e->operands.ops.lhs->op == POW)
	{
	  mpz_t powlhs, powrhs;
	  mpz_init (powlhs);
	  mpz_init (powrhs);
	  mpz_init (rhs);
	  mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
	  mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
	  mpz_eval_expr (rhs, e->operands.ops.rhs);
	  mpz_powm (r, powlhs, powrhs, rhs);
	  if (mpz_cmp_si (rhs, 0L) < 0)
	    mpz_neg (r, r);
	  mpz_clear (powlhs);
	  mpz_clear (powrhs);
	  mpz_clear (rhs);
	  return;
	}

      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_r (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION >= 2
    case INVMOD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_invert (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case POW:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmpabs_ui (lhs, 1) <= 0)
	{
	  /* For 0^rhs and 1^rhs, we just need to verify that
	     rhs is well-defined.  For (-1)^rhs we need to
	     determine (rhs mod 2).  For simplicity, compute
	     (rhs mod 2) for all three cases.  */
	  expr_t two, et;
	  two = malloc (sizeof (struct expr));
	  two -> op = LIT;
	  mpz_init_set_ui (two->operands.val, 2L);
	  makeexp (&et, MOD, e->operands.ops.rhs, two);
	  e->operands.ops.rhs = et;
	}

      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_cmp_si (rhs, 0L) == 0)
	/* x^0 is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, 0L) == 0)
	/* 0^y (where y != 0) is 0 */
	mpz_set_ui (r, 0L);
      else if (mpz_cmp_ui (lhs, 1L) == 0)
	/* 1^y is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, -1L) == 0)
	/* (-1)^y just depends on whether y is even or odd */
	mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
      else if (mpz_cmp_si (rhs, 0L) < 0)
	/* x^(-n) is 0 */
	mpz_set_ui (r, 0L);
      else
	{
	  unsigned long int cnt;
	  unsigned long int y;
	  /* error if exponent does not fit into an unsigned long int.  */
	  if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	    goto pow_err;

	  y = mpz_get_ui (rhs);
	  /* x^y == (x/(2^c))^y * 2^(c*y) */
#if __GNU_MP_VERSION >= 2
	  cnt = mpz_scan1 (lhs, 0);
#else
	  cnt = 0;
#endif
	  if (cnt != 0)
	    {
	      if (y * cnt / cnt != y)
		goto pow_err;
	      mpz_tdiv_q_2exp (lhs, lhs, cnt);
	      mpz_pow_ui (r, lhs, y);
	      mpz_mul_2exp (r, r, y * cnt);
	    }
	  else
	    mpz_pow_ui (r, lhs, y);
	}
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    pow_err:
      error = "result of `pow' operator too large";
      mpz_clear (lhs); mpz_clear (rhs);
      longjmp (errjmpbuf, 1);
    case GCD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_gcd (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case LCM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_lcm (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case AND:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_and (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case IOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_ior (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case XOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_xor (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case NEG:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_neg (r, r);
      return;
    case NOT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_com (r, r);
      return;
    case SQRT:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_sgn (lhs) < 0)
	{
	  error = "cannot take square root of negative numbers";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_sqrt (r, lhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case ROOT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_sgn (rhs) <= 0)
	{
	  error = "cannot take non-positive root orders";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}
      if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
	{
	  error = "cannot take even root orders of negative numbers";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}

      {
	unsigned long int nth = mpz_get_ui (rhs);
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    /* If we are asked to take an awfully large root order, cheat and
	       ask for the largest order we can pass to mpz_root.  This saves
	       some error prone special cases.  */
	    nth = ~(unsigned long int) 0;
	  }
	mpz_root (r, lhs, nth);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case FAC:
      mpz_eval_expr (r, e->operands.ops.lhs);
      if (mpz_size (r) > 1)
	{
	  error = "result of `!' operator too large";
	  longjmp (errjmpbuf, 1);
	}
      mpz_fac_ui (r, mpz_get_ui (r));
      return;
#if __GNU_MP_VERSION >= 2
    case POPCNT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_si (r, cnt);
      }
      return;
    case HAMDIST:
      { long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	cnt = mpz_hamdist (lhs, rhs);
	mpz_clear (lhs); mpz_clear (rhs);
	mpz_set_si (r, cnt);
      }
      return;
#endif
    case LOG2:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { unsigned long int cnt;
	if (mpz_sgn (r) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (r, 2);
	mpz_set_ui (r, cnt - 1);
      }
      return;
    case LOG:
      { unsigned long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	if (mpz_sgn (lhs) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	if (mpz_cmp_ui (rhs, 256) >= 0)
	  {
	    error = "logarithm base too large";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
	mpz_set_ui (r, cnt - 1);
	mpz_clear (lhs); mpz_clear (rhs);
      }
      return;
    case FERMAT:
      {
	unsigned long int t;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	t = (unsigned long int) 1 << mpz_get_ui (lhs);
	if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
	  {
	    error = "too large Mersenne number index";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	mpz_set_ui (r, 1);
	mpz_mul_2exp (r, r, t);
	mpz_add_ui (r, r, 1);
	mpz_clear (lhs);
      }
      return;
    case MERSENNE:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
	{
	  error = "too large Mersenne number index";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_set_ui (r, 1);
      mpz_mul_2exp (r, r, mpz_get_ui (lhs));
      mpz_sub_ui (r, r, 1);
      mpz_clear (lhs);
      return;
    case FIBONACCI:
      { mpz_t t;
	unsigned long int n, i;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "Fibonacci index out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);

#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
	mpz_fib_ui (r, n);
#else
	mpz_init_set_ui (t, 1);
	mpz_set_ui (r, 1);

	if (n <= 2)
	  mpz_set_ui (r, 1);
	else
	  {
	    for (i = 3; i <= n; i++)
	      {
		mpz_add (t, t, r);
		mpz_swap (t, r);
	      }
	  }
	mpz_clear (t);
#endif
      }
      return;
    case RANDOM:
      {
	unsigned long int n;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "random number size out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);
	mpz_urandomb (r, rstate, n);
      }
      return;
    case NEXTPRIME:
      {
	mpz_eval_expr (r, e->operands.ops.lhs);
	mpz_nextprime (r, r);
      }
      return;
    case BINOM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      {
	unsigned long int k;
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    error = "k too large in (n over k) expression";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	k = mpz_get_ui (rhs);
	mpz_bin_ui (r, lhs, k);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case TIMING:
      {
	int t0;
	t0 = cputime ();
	mpz_eval_expr (r, e->operands.ops.lhs);
	printf ("time: %d\n", cputime () - t0);
      }
      return;
    default:
      abort ();
    }
}
/* This generates p,q params using the B.3.2.2 algorithm in FIPS 186-4.
 * 
 * The hash function used is SHA384.
 * The exponent e used is the value in pub->e.
 */
int
_rsa_generate_fips186_4_keypair(struct rsa_public_key *pub,
				struct rsa_private_key *key,
				unsigned seed_length, uint8_t * seed,
				void *progress_ctx,
				nettle_progress_func * progress,
				/* Desired size of modulo, in bits */
				unsigned n_size)
{
	mpz_t t, r, p1, q1, lcm;
	int ret;
	struct dss_params_validation_seeds cert;
	unsigned l = n_size / 2;

	if (_gnutls_fips_mode_enabled() != 0) {
		if (n_size == 2048) {
			if (seed_length != 14 * 2) {
				_gnutls_debug_log("Seed length must be 28 bytes (it is %d)\n", seed_length);
				return 0;
			}
		} else if (n_size == 3072) {
			if (seed_length != 16 * 2) {
				_gnutls_debug_log("Seed length must be 32 bytes (it is %d)\n", seed_length);
				return 0;
			}
		} else {
			_gnutls_debug_log("Unsupported size for modulus\n");
			return 0;
		}
	}

	if (!mpz_tstbit(pub->e, 0)) {
		_gnutls_debug_log("Unacceptable e (it is even)\n");
		return 0;
	}

	if (mpz_cmp_ui(pub->e, 65536) <= 0) {
		_gnutls_debug_log("Unacceptable e\n");
		return 0;
	}

	mpz_init(p1);
	mpz_init(q1);
	mpz_init(lcm);
	mpz_init(t);
	mpz_init(r);

	mpz_set_ui(t, 1);
	mpz_mul_2exp(t, t, 256);

	if (mpz_cmp(pub->e, t) >= 0) {
		ret = 0;
		goto cleanup;
	}

	cert.pseed_length = sizeof(cert.pseed);
	ret = rsa_provable_prime(key->p, &cert.pseed_length, cert.pseed,
				l, seed_length,
				seed, pub->e, progress_ctx, progress);
	if (ret == 0) {
		goto cleanup;
	}

	mpz_set_ui(r, 1);
	mpz_mul_2exp(r, r, (l) - 100);

	do {
		cert.qseed_length = sizeof(cert.qseed);
		ret = rsa_provable_prime(key->q, &cert.qseed_length, cert.qseed,
					l, cert.pseed_length, cert.pseed,
					pub->e,
					progress_ctx, progress);
		if (ret == 0) {
			goto cleanup;
		}


		cert.pseed_length = cert.qseed_length;
		memcpy(cert.pseed, cert.qseed, cert.qseed_length);


		if (mpz_cmp(key->p, key->q) > 0)
			mpz_sub(t, key->p, key->q);
		else
			mpz_sub(t, key->q, key->p);
	} while (mpz_cmp(t, r) <= 0);

	memset(&cert, 0, sizeof(cert));

	mpz_mul(pub->n, key->p, key->q);

	assert(mpz_sizeinbase(pub->n, 2) == n_size);

	/* c = q^{-1} (mod p) */
	assert(mpz_invert(key->c, key->q, key->p) != 0);

	mpz_sub_ui(p1, key->p, 1);
	mpz_sub_ui(q1, key->q, 1);

	mpz_lcm(lcm, p1, q1);

	if (mpz_invert(key->d, pub->e, lcm) == 0) {
		ret = 0;
		goto cleanup;
	}

	/* Done! Almost, we must compute the auxillary private values. */
	/* a = d % (p-1) */
	mpz_fdiv_r(key->a, key->d, p1);

	/* b = d % (q-1) */
	mpz_fdiv_r(key->b, key->d, q1);

	/* c was computed earlier */

	pub->size = key->size = (n_size + 7) / 8;
	assert(pub->size >= RSA_MINIMUM_N_OCTETS);

	ret = 1;
 cleanup:
	mpz_clear(p1);
	mpz_clear(q1);
	mpz_clear(lcm);
	mpz_clear(t);
	mpz_clear(r);
	return ret;
}
示例#25
0
文件: ppl_lpsol.c 项目: hnxiao/ppl
static void
solve(char* file_name) {
  ppl_Constraint_System_t ppl_cs;
#ifndef NDEBUG
  ppl_Constraint_System_t ppl_cs_copy;
#endif
  ppl_Generator_t optimum_location;
  ppl_Linear_Expression_t ppl_le;
  int dimension, row, num_rows, column, nz, i, j, type;
  int* coefficient_index;
  double lb, ub;
  double* coefficient_value;
  mpq_t rational_lb, rational_ub;
  mpq_t* rational_coefficient;
  mpq_t* objective;
  ppl_Linear_Expression_t ppl_objective_le;
  ppl_Coefficient_t optimum_n;
  ppl_Coefficient_t optimum_d;
  mpq_t optimum;
  mpz_t den_lcm;
  int optimum_found;
  glp_mpscp glpk_mpscp;

  glpk_lp = glp_create_prob();
  glp_init_mpscp(&glpk_mpscp);

  if (verbosity == 0) {
    /* FIXME: find a way to suppress output from glp_read_mps. */
  }

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings)
    start_clock();

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  if (glp_read_mps(glpk_lp, GLP_MPS_FILE, &glpk_mpscp, file_name) != 0)
    fatal("cannot read MPS file `%s'", file_name);

#ifdef PPL_LPSOL_SUPPORTS_TIMINGS

  if (print_timings) {
    fprintf(stderr, "Time to read the input file: ");
    print_clock(stderr);
    fprintf(stderr, " s\n");
    start_clock();
  }

#endif /* defined(PPL_LPSOL_SUPPORTS_TIMINGS) */

  glpk_lp_num_int = glp_get_num_int(glpk_lp);

  if (glpk_lp_num_int > 0 && !no_mip && !use_simplex)
     fatal("the enumeration solving method can not handle MIP problems");

  dimension = glp_get_num_cols(glpk_lp);

  /* Read variables constrained to be integer. */
  if (glpk_lp_num_int > 0 && !no_mip && use_simplex) {
    if (verbosity >= 4)
      fprintf(output_file, "Integer variables:\n");
    integer_variables = (ppl_dimension_type*)
      malloc((glpk_lp_num_int + 1)*sizeof(ppl_dimension_type));
    for (i = 0, j = 0; i < dimension; ++i) {
      int col_kind = glp_get_col_kind(glpk_lp, i+1);
      if (col_kind == GLP_IV || col_kind == GLP_BV) {
        integer_variables[j] = i;
        if (verbosity >= 4) {
          ppl_io_fprint_variable(output_file, i);
          fprintf(output_file, " ");
        }
        ++j;
      }
    }
  }
  coefficient_index = (int*) malloc((dimension+1)*sizeof(int));
  coefficient_value = (double*) malloc((dimension+1)*sizeof(double));
  rational_coefficient = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t));


  ppl_new_Constraint_System(&ppl_cs);

  mpq_init(rational_lb);
  mpq_init(rational_ub);
  for (i = 1; i <= dimension; ++i)
    mpq_init(rational_coefficient[i]);

  mpz_init(den_lcm);

  if (verbosity >= 4)
    fprintf(output_file, "\nConstraints:\n");

  /* Set up the row (ordinary) constraints. */
  num_rows = glp_get_num_rows(glpk_lp);
  for (row = 1; row <= num_rows; ++row) {
    /* Initialize the least common multiple computation. */
    mpz_set_si(den_lcm, 1);
    /* Set `nz' to the number of non-zero coefficients. */
    nz = glp_get_mat_row(glpk_lp, row, coefficient_index, coefficient_value);
    for (i = 1; i <= nz; ++i) {
      set_mpq_t_from_double(rational_coefficient[i], coefficient_value[i]);
      /* Update den_lcm. */
      mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_coefficient[i]));
    }

    lb = glp_get_row_lb(glpk_lp, row);
    ub = glp_get_row_ub(glpk_lp, row);

    set_mpq_t_from_double(rational_lb, lb);
    set_mpq_t_from_double(rational_ub, ub);

    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb));
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub));

    ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension);

    for (i = 1; i <= nz; ++i) {
      mpz_mul(tmp_z, den_lcm, mpq_numref(rational_coefficient[i]));
      mpz_divexact(tmp_z, tmp_z, mpq_denref(rational_coefficient[i]));
      ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
      ppl_Linear_Expression_add_to_coefficient(ppl_le, coefficient_index[i]-1,
                                               ppl_coeff);
    }

    type = glp_get_row_type(glpk_lp, row);
    add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs);

    ppl_delete_Linear_Expression(ppl_le);
  }

  free(coefficient_value);
  for (i = 1; i <= dimension; ++i)
    mpq_clear(rational_coefficient[i]);
  free(rational_coefficient);
  free(coefficient_index);

#ifndef NDEBUG
  ppl_new_Constraint_System_from_Constraint_System(&ppl_cs_copy, ppl_cs);
#endif

  /*
    FIXME: here we could build the polyhedron and minimize it before
    adding the variable bounds.
  */

  /* Set up the columns constraints, i.e., variable bounds. */
  for (column = 1; column <= dimension; ++column) {

    lb = glp_get_col_lb(glpk_lp, column);
    ub = glp_get_col_ub(glpk_lp, column);

    set_mpq_t_from_double(rational_lb, lb);
    set_mpq_t_from_double(rational_ub, ub);

    /* Initialize the least common multiple computation. */
    mpz_set_si(den_lcm, 1);
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb));
    mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub));

    ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension);
    ppl_assign_Coefficient_from_mpz_t(ppl_coeff, den_lcm);
    ppl_Linear_Expression_add_to_coefficient(ppl_le, column-1, ppl_coeff);

    type = glp_get_col_type(glpk_lp, column);
    add_constraints(ppl_le, type, rational_lb, rational_ub, den_lcm, ppl_cs);

    ppl_delete_Linear_Expression(ppl_le);
  }

  mpq_clear(rational_ub);
  mpq_clear(rational_lb);

  /* Deal with the objective function. */
  objective = (mpq_t*) malloc((dimension+1)*sizeof(mpq_t));

  /* Initialize the least common multiple computation. */
  mpz_set_si(den_lcm, 1);

  mpq_init(objective[0]);
  set_mpq_t_from_double(objective[0], glp_get_obj_coef(glpk_lp, 0));
  for (i = 1; i <= dimension; ++i) {
    mpq_init(objective[i]);
    set_mpq_t_from_double(objective[i], glp_get_obj_coef(glpk_lp, i));
    /* Update den_lcm. */
    mpz_lcm(den_lcm, den_lcm, mpq_denref(objective[i]));
  }

  /* Set the ppl_objective_le to be the objective function. */
  ppl_new_Linear_Expression_with_dimension(&ppl_objective_le, dimension);
  /* Set value for objective function's inhomogeneous term. */
  mpz_mul(tmp_z, den_lcm, mpq_numref(objective[0]));
  mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[0]));
  ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
  ppl_Linear_Expression_add_to_inhomogeneous(ppl_objective_le, ppl_coeff);
  /* Set values for objective function's variable coefficients. */
  for (i = 1; i <= dimension; ++i) {
    mpz_mul(tmp_z, den_lcm, mpq_numref(objective[i]));
    mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[i]));
    ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
    ppl_Linear_Expression_add_to_coefficient(ppl_objective_le, i-1, ppl_coeff);
  }

  if (verbosity >= 4) {
    fprintf(output_file, "Objective function:\n");
    if (mpz_cmp_si(den_lcm, 1) != 0)
      fprintf(output_file, "(");
    ppl_io_fprint_Linear_Expression(output_file, ppl_objective_le);
  }

  for (i = 0; i <= dimension; ++i)
    mpq_clear(objective[i]);
  free(objective);

  if (verbosity >= 4) {
    if (mpz_cmp_si(den_lcm, 1) != 0) {
      fprintf(output_file, ")/");
      mpz_out_str(output_file, 10, den_lcm);
    }
    fprintf(output_file, "\n%s\n",
            (maximize ? "Maximizing." : "Minimizing."));
  }

  ppl_new_Coefficient(&optimum_n);
  ppl_new_Coefficient(&optimum_d);
  ppl_new_Generator_zero_dim_point(&optimum_location);

  optimum_found = use_simplex
    ? solve_with_simplex(ppl_cs,
                         ppl_objective_le,
                         optimum_n,
                         optimum_d,
                         optimum_location)
    : solve_with_generators(ppl_cs,
                            ppl_objective_le,
                            optimum_n,
                            optimum_d,
                            optimum_location);

  ppl_delete_Linear_Expression(ppl_objective_le);

  if (glpk_lp_num_int > 0)
      free(integer_variables);

  if (optimum_found) {
    mpq_init(optimum);
    ppl_Coefficient_to_mpz_t(optimum_n, tmp_z);
    mpq_set_num(optimum, tmp_z);
    ppl_Coefficient_to_mpz_t(optimum_d, tmp_z);
    mpz_mul(tmp_z, tmp_z, den_lcm);
    mpq_set_den(optimum, tmp_z);
    if (verbosity == 1)
      fprintf(output_file, "Optimized problem.\n");
    if (verbosity >= 2)
      fprintf(output_file, "Optimum value: %.10g\n", mpq_get_d(optimum));
    if (verbosity >= 3) {
      fprintf(output_file, "Optimum location:\n");
      ppl_Generator_divisor(optimum_location, ppl_coeff);
      ppl_Coefficient_to_mpz_t(ppl_coeff, tmp_z);
      for (i = 0; i < dimension; ++i) {
        mpz_set(mpq_denref(tmp1_q), tmp_z);
        ppl_Generator_coefficient(optimum_location, i, ppl_coeff);
        ppl_Coefficient_to_mpz_t(ppl_coeff, mpq_numref(tmp1_q));
        ppl_io_fprint_variable(output_file, i);
        fprintf(output_file, " = %.10g\n", mpq_get_d(tmp1_q));
      }
    }
#ifndef NDEBUG
    {
      ppl_Polyhedron_t ph;
      unsigned int relation;
      ppl_new_C_Polyhedron_recycle_Constraint_System(&ph, ppl_cs_copy);
      ppl_delete_Constraint_System(ppl_cs_copy);
      relation = ppl_Polyhedron_relation_with_Generator(ph, optimum_location);
      ppl_delete_Polyhedron(ph);
      assert(relation == PPL_POLY_GEN_RELATION_SUBSUMES);
    }
#endif
    maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED,
                        mpq_get_d(optimum));
    mpq_clear(optimum);
  }

  ppl_delete_Constraint_System(ppl_cs);
  ppl_delete_Coefficient(optimum_d);
  ppl_delete_Coefficient(optimum_n);
  ppl_delete_Generator(optimum_location);

  glp_delete_prob(glpk_lp);
}