示例#1
0
static int
rsa_private_calculate(mpz_t in, mpz_t p,  mpz_t q,
		      mpz_t dmp1, mpz_t dmq1, mpz_t iqmp,
		      mpz_t out)
{
    mpz_t vp, vq, u;
    mpz_init(vp); mpz_init(vq); mpz_init(u);

    /* vq = c ^ (d mod (q - 1)) mod q */
    /* vp = c ^ (d mod (p - 1)) mod p */
    mpz_fdiv_r(vp, in, p);
    mpz_powm(vp, vp, dmp1, p);
    mpz_fdiv_r(vq, in, q);
    mpz_powm(vq, vq, dmq1, q);

    /* C2 = 1/q mod p  (iqmp) */
    /* u = (vp - vq)C2 mod p. */
    mpz_sub(u, vp, vq);
#if 0
    if (mp_int_compare_zero(&u) < 0)
	mp_int_add(&u, p, &u);
#endif
    mpz_mul(u, iqmp, u);
    mpz_fdiv_r(u, u, p);

    /* c ^ d mod n = vq + u q */
    mpz_mul(u, q, u);
    mpz_add(out, u, vq);

    mpz_clear(vp);
    mpz_clear(vq);
    mpz_clear(u);

    return 0;
}
示例#2
0
文件: reesa.c 项目: hylje/tira-reesa
void exp_modulo(mpz_t rop, const mpz_t base, const mpz_t exponent, const mpz_t modulus) {
  /* fast exp-modulo */
  mpz_t c;
  mpz_init_set_ui(c, 1);
  mpz_t ex;
  mpz_init_set(ex, exponent);
  mpz_t b;
  mpz_init_set(b, base);
  mpz_t temp;
  mpz_init(temp);

  while (mpz_cmp_ui(ex, 0) > 0) {
    /* ex mod 2 == 1 */
    mpz_fdiv_r_ui(temp, ex, 2);
    if (mpz_cmp_ui(temp, 1) == 0) {
      mpz_mul(temp, c, b);
      mpz_fdiv_r(c, temp, modulus);
    }

    /* right shift by 1 */
    mpz_fdiv_q_2exp(ex, ex, 1);

    /* b^2 mod modulus */
    mpz_mul(b, b, b);
    mpz_fdiv_r(b, b, modulus);
  }

  mpz_set(rop, c);

  mpz_clear(c);
  mpz_clear(ex);
  mpz_clear(temp);
  mpz_clear(b);
}
示例#3
0
文件: copri.c 项目: jamella/copri
// Algorithm 19.2  [PDF page 24](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [reduce test](test-reduce.html) for basic usage.
void reduce(mpz_t i, mpz_t pai, const mpz_t p, const mpz_t a) {
	mpz_t r, j, b, p2, a2;

	// **Sep 1**
	//
	//  If p does not divide a: Print (0,a) and stop.
	mpz_init(r);
	mpz_fdiv_r(r, a, p);
	if (mpz_cmp_ui(r, 0) != 0) {
		mpz_clear(r);
		mpz_set_ui(i, 0);
		mpz_set(pai, a);
		return;
	}

	// **Sep 2**
	//
	//  Compute (j,b) ← reduce(p^2 ,a/p)
	mpz_init(j);
	mpz_init(b);
	mpz_init(p2);
	mpz_init(a2);
	mpz_mul(p2, p, p);
	mpz_fdiv_q(a2, a, p);
	reduce(j, b, p2, a2);
	mpz_clear(p2);
	mpz_clear(a2);

	// **Sep 3**
	//
	//  If p divides b: Print (2 j +2,b/p) and stop.
	mpz_fdiv_r(r, b, p);
	if (mpz_cmp_ui(r, 0) == 0) {
		mpz_mul_ui(j, j, 2);
		mpz_add_ui(j, j, 2);
		mpz_set(i, j);

		mpz_fdiv_q(b, b, p);
		mpz_set(pai, b);

		mpz_clear(r);
		mpz_clear(b);
		mpz_clear(j);
		return;
	}
	mpz_clear(r);

	// **Sep 4**
	//
	//  Print (2 j +1,b).
	mpz_mul_ui(j, j, 2);
	mpz_add_ui(j, j, 1);
	mpz_set(i, j);
	mpz_set(pai, b);

	// Free the memory.
	mpz_clear(b);
	mpz_clear(j);
}
示例#4
0
/* Computing an rsa root. */
void
rsa_compute_root(const struct rsa_private_key *key,
		 mpz_t x, const mpz_t m)
{
  mpz_t xp; /* modulo p */
  mpz_t xq; /* modulo q */

  mpz_init(xp); mpz_init(xq);    

  /* Compute xq = m^d % q = (m%q)^b % q */
  mpz_fdiv_r(xq, m, key->q);
  mpz_powm(xq, xq, key->b, key->q);

  /* Compute xp = m^d % p = (m%p)^a % p */
  mpz_fdiv_r(xp, m, key->p);
  mpz_powm(xp, xp, key->a, key->p);

  /* Set xp' = (xp - xq) c % p. */
  mpz_sub(xp, xp, xq);
  mpz_mul(xp, xp, key->c);
  mpz_fdiv_r(xp, xp, key->p);

  /* Finally, compute x = xq + q xp'
   *
   * To prove that this works, note that
   *
   *   xp  = x + i p,
   *   xq  = x + j q,
   *   c q = 1 + k p
   *
   * for some integers i, j and k. Now, for some integer l,
   *
   *   xp' = (xp - xq) c + l p
   *       = (x + i p - (x + j q)) c + l p
   *       = (i p - j q) c + l p
   *       = (i c + l) p - j (c q)
   *       = (i c + l) p - j (1 + kp)
   *       = (i c + l - j k) p - j
   *
   * which shows that xp' = -j (mod p). We get
   *
   *   xq + q xp' = x + j q + (i c + l - j k) p q - j q
   *              = x + (i c + l - j k) p q
   *
   * so that
   *
   *   xq + q xp' = x (mod pq)
   *
   * We also get 0 <= xq + q xp' < p q, because
   *
   *   0 <= xq < q and 0 <= xp' < p.
   */
  mpz_mul(x, key->q, xp);
  mpz_add(x, x, xq);

  mpz_clear(xp); mpz_clear(xq);
}
示例#5
0
void
check_random (int argc, char *argv[])
{
  gmp_randstate_ptr rands = RANDS;
  mpz_t   a, c, d, ra, rc;
  int     i;
  int     want;
  int     reps = 50000;

  if (argc >= 2)
    reps = atoi (argv[1]);

  mpz_init (a);
  mpz_init (c);
  mpz_init (d);
  mpz_init (ra);
  mpz_init (rc);

  for (i = 0; i < reps; i++)
    {
      mpz_errandomb (a, rands, 8*BITS_PER_MP_LIMB);
      MPZ_CHECK_FORMAT (a);
      mpz_errandomb (c, rands, 8*BITS_PER_MP_LIMB);
      MPZ_CHECK_FORMAT (c);
      mpz_errandomb_nonzero (d, rands, 8*BITS_PER_MP_LIMB);

      mpz_negrandom (a, rands);
      MPZ_CHECK_FORMAT (a);
      mpz_negrandom (c, rands);
      MPZ_CHECK_FORMAT (c);
      mpz_negrandom (d, rands);

      mpz_fdiv_r (ra, a, d);
      mpz_fdiv_r (rc, c, d);

      want = (mpz_cmp (ra, rc) == 0);
      check_one (a, c, d, want);

      mpz_sub (ra, ra, rc);
      mpz_sub (a, a, ra);
      MPZ_CHECK_FORMAT (a);
      check_one (a, c, d, 1);

      if (! mpz_pow2abs_p (d))
        {
          refmpz_combit (a, urandom() % (8*BITS_PER_MP_LIMB));
          check_one (a, c, d, 0);
        }
    }

  mpz_clear (a);
  mpz_clear (c);
  mpz_clear (d);
  mpz_clear (ra);
  mpz_clear (rc);
}
示例#6
0
int
_dsa_sign(const struct dsa_public_key *pub,
	  const struct dsa_private_key *key,
	  void *random_ctx, nettle_random_func *random,
	  unsigned digest_size,
	  const uint8_t *digest,
	  struct dsa_signature *signature)
{
  mpz_t k;
  mpz_t h;
  mpz_t tmp;

  /* Require precise match of bitsize of q and hash size. The general
     description of DSA in FIPS186-3 allows both larger and smaller q;
     in the the latter case, the hash must be truncated to the right
     number of bits. */
  if (mpz_sizeinbase(pub->q, 2) != 8 * digest_size)
    return 0;

  /* Select k, 0<k<q, randomly */
  mpz_init_set(tmp, pub->q);
  mpz_sub_ui(tmp, tmp, 1);

  mpz_init(k);
  nettle_mpz_random(k, random_ctx, random, tmp);
  mpz_add_ui(k, k, 1);

  /* Compute r = (g^k (mod p)) (mod q) */
  mpz_powm(tmp, pub->g, k, pub->p);
  mpz_fdiv_r(signature->r, tmp, pub->q);

  /* Compute hash */
  mpz_init(h);
  nettle_mpz_set_str_256_u(h, digest_size, digest);

  /* Compute k^-1 (mod q) */
  if (!mpz_invert(k, k, pub->q))
    /* What do we do now? The key is invalid. */
    return 0;

  /* Compute signature s = k^-1 (h + xr) (mod q) */
  mpz_mul(tmp, signature->r, key->x);
  mpz_fdiv_r(tmp, tmp, pub->q);
  mpz_add(tmp, tmp, h);
  mpz_mul(tmp, tmp, k);
  mpz_fdiv_r(signature->s, tmp, pub->q);

  mpz_clear(k);
  mpz_clear(h);
  mpz_clear(tmp);

  return 1;
}
示例#7
0
文件: sqrt_a.c 项目: coolpraku/msieve
/*-------------------------------------------------------------------*/
static void gmp_poly_mod_q(gmp_poly_t *p, mpz_t q, gmp_poly_t *res) {

	uint32 i;
	uint32 pbits, resbits;

	/* also trim aggressively the memory use of the
	   computed remainders; the algebraic square root has
	   comparatively few arithmetic operations but the
	   memory use for large problems is a concern */

	for (i = 0; i <= p->degree; i++) {
		pbits = mpz_sizeinbase(p->coeff[i], 2);
		mpz_fdiv_r(res->coeff[i], p->coeff[i], q);
		resbits = mpz_sizeinbase(res->coeff[i], 2);

		if (pbits > resbits + 1000)
			mpz_realloc2(res->coeff[i], resbits + 500);
	}

	/* recalculate the degree */

	for (i = p->degree; i; i--) {
		if (mpz_sgn(res->coeff[i]) != 0)
			break;
	}
	res->degree = i;
}
示例#8
0
void
test_dsa_key(struct dsa_public_key *pub,
	     struct dsa_private_key *key,
	     unsigned q_size)
{
  mpz_t t;

  mpz_init(t);

  ASSERT(mpz_sizeinbase(pub->q, 2) == q_size);
  ASSERT(mpz_sizeinbase(pub->p, 2) >= DSA_SHA1_MIN_P_BITS);
  
  ASSERT(mpz_probab_prime_p(pub->p, 10));

  ASSERT(mpz_probab_prime_p(pub->q, 10));

  mpz_fdiv_r(t, pub->p, pub->q);

  ASSERT(0 == mpz_cmp_ui(t, 1));

  ASSERT(mpz_cmp_ui(pub->g, 1) > 0);
  
  mpz_powm(t, pub->g, pub->q, pub->p);
  ASSERT(0 == mpz_cmp_ui(t, 1));
  
  mpz_powm(t, pub->g, key->x, pub->p);
  ASSERT(0 == mpz_cmp(t, pub->y));

  mpz_clear(t);
}
示例#9
0
文件: rsa-blind.c 项目: gnutls/nettle
/* Blinds the c, by computing c *= r^e (mod n), for a random r. Also
   returns the inverse (ri), for use by rsa_unblind. */
void
_rsa_blind (const struct rsa_public_key *pub,
	    void *random_ctx, nettle_random_func *random,
	    mpz_t c, mpz_t ri)
{
  mpz_t r;

  mpz_init(r);

  /* c = c*(r^e)
   * ri = r^(-1)
   */
  do 
    {
      nettle_mpz_random(r, random_ctx, random, pub->n);
      /* invert r */
    }
  while (!mpz_invert (ri, r, pub->n));

  /* c = c*(r^e) mod n */
  mpz_powm_sec(r, r, pub->e, pub->n);
  mpz_mul(c, c, r);
  mpz_fdiv_r(c, c, pub->n);

  mpz_clear(r);
}
示例#10
0
static PyObject *
Pygmpy_f_mod(PyObject *self, PyObject *args)
{
    PyObject *x, *y;
    PympzObject *r, *tempx, *tempy;

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

    x = PyTuple_GET_ITEM(args, 0);
    y = PyTuple_GET_ITEM(args, 1);
    if (!(r = Pympz_new()))
        return NULL;

    if(CHECK_MPZANY(x) && CHECK_MPZANY(y)) {
        if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) {
            ZERO_ERROR("f_mod() division by 0");
            Py_DECREF((PyObject*)r);
            return NULL;
        }
        mpz_fdiv_r(r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y));
    }
    else {
        tempx = Pympz_From_Integer(x);
        tempy = Pympz_From_Integer(y);
        if (!tempx || !tempy) {
            TYPE_ERROR("f_mod() requires 'mpz','mpz' arguments");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)r);
            return NULL;
        }
        if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) {
            ZERO_ERROR("f_mod() division by 0");
            Py_DECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)r);
            return NULL;
        }
        mpz_fdiv_r(r->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
    }
    return (PyObject*)r;
}
示例#11
0
static Variant HHVM_FUNCTION(gmp_div_r,
                             const Variant& dataA,
                             const Variant& dataB,
                             int64_t round = GMP_ROUND_ZERO) {
  mpz_t gmpDataA, gmpDataB, gmpReturn;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_R, gmpDataA, dataA)) {
    return false;
  }
  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_R, gmpDataB, dataB)) {
    mpz_clear(gmpDataA);
    return false;
  }

  if (mpz_sgn(gmpDataB) == 0) {
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);

    raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO,
                  cs_GMP_FUNC_NAME_GMP_DIV_R);
    return false;
  }

  mpz_init(gmpReturn);
  switch (round) {
  case GMP_ROUND_ZERO:
    mpz_tdiv_r(gmpReturn, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_PLUSINF:
    mpz_cdiv_r(gmpReturn, gmpDataA, gmpDataB);
    break;

  case GMP_ROUND_MINUSINF:
    mpz_fdiv_r(gmpReturn, gmpDataA, gmpDataB);
    break;

  default:
    mpz_clear(gmpDataA);
    mpz_clear(gmpDataB);
    mpz_clear(gmpReturn);
    return null_variant;
  }

  mpz_clear(gmpDataA);
  mpz_clear(gmpDataB);

  Variant ret;

  if (dataB.isInteger() && dataB.getInt64() >= 0) {
    ret = (int64_t)mpz_get_ui(gmpReturn);
  } else {
    ret = NEWOBJ(GMPResource)(gmpReturn);
  }

  mpz_clear(gmpReturn);

  return ret;
}
示例#12
0
static PyObject *
GMPy_MPZ_IRem_Slot(PyObject *self, PyObject *other)
{
    MPZ_Object *rz;

    if (!(rz =  GMPy_MPZ_New(NULL)))
        return NULL;

     if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("mpz modulo by zero");
            return NULL;
        }
        mpz_fdiv_r(rz->z, MPZ(self), MPZ(other));
        return (PyObject*)rz;
    }

   if (PyIntOrLong_Check(other)) {
        int error;
        long temp = GMPy_Integer_AsLongAndError(other, &error);

        if (!error) {
            if (temp > 0) {
                mpz_fdiv_r_ui(rz->z, MPZ(self), temp);
            }
            else if (temp == 0) {
                ZERO_ERROR("mpz modulo by zero");
                return NULL;
            }
            else {
                mpz_cdiv_r_ui(rz->z, MPZ(self), -temp);
            }
        }
        else {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, other);
            mpz_fdiv_r(rz->z, MPZ(self), tempz);
            mpz_cloc(tempz);
        }
        return (PyObject*)rz;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
示例#13
0
文件: mpi.c 项目: gnutls/gnutls
static int
wrap_nettle_mpi_mulm(bigint_t w, const bigint_t a, const bigint_t b,
		     const bigint_t m)
{
	mpz_mul(TOMPZ(w), TOMPZ(a), TOMPZ(b));
	mpz_fdiv_r(TOMPZ(w), TOMPZ(w), TOMPZ(m));

	return 0;
}
示例#14
0
int mpz_divisible_p (mpz_t N, mpz_t D)
{
    int d;
    mpz_t r;
    mpz_init(r);
    mpz_fdiv_r(r, N, D);
    d = mpz_sgn(r) == 0;
    mpz_clear(r);
    return d;
}
示例#15
0
static PyObject *
Pyxmpz_inplace_rem(PyObject *a, PyObject *b)
{
    mpz_t tempz;
    mpir_si temp_si;
    int overflow;

    if (PyIntOrLong_Check(b)) {
        temp_si = PyLong_AsSIAndOverflow(b, &overflow);
        if (overflow) {
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, b);
            mpz_fdiv_r(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz);
            mpz_cloc(tempz);
        }
        else if(temp_si > 0) {
            mpz_fdiv_r_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si);
        }
        else if(temp_si == 0) {
            ZERO_ERROR("xmpz modulo by zero");
            return NULL;
        }
        else {
            mpz_cdiv_r_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), -temp_si);
        }
        Py_INCREF(a);
        return a;
    }

    if (CHECK_MPZANY(b)) {
        if(mpz_sgn(Pyxmpz_AS_MPZ(b)) == 0) {
            ZERO_ERROR("xmpz modulo by zero");
            return NULL;
        }
        mpz_fdiv_r(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(b));
        Py_INCREF(a);
        return a;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
void init_montgomery_R2(mpz_t n)
{
  size_t i;

  mpz_set_ui(montgomery_gmp_help,1);
  mpz_mul_2exp(montgomery_gmp_help,montgomery_gmp_help,2*mp_bits_per_limb*montgomery_ulongs);
  mpz_fdiv_r(montgomery_gmp_help,montgomery_gmp_help,n);
  montgomery_modulo_R2[0]=mpz_get_ui(montgomery_gmp_help);
  for (i=1; i<montgomery_ulongs; i++) {
    mpz_fdiv_q_2exp(montgomery_gmp_help,montgomery_gmp_help,mp_bits_per_limb);
    montgomery_modulo_R2[i]=mpz_get_ui(montgomery_gmp_help);
  }
}
示例#17
0
static PyObject *
GMPy_XMPZ_IRem_Slot(PyObject *self, PyObject *other)
{
    if (PyIntOrLong_Check(other)) {
        int error;
        native_si temp = GMPy_Integer_AsNative_siAndError(other, &error);

        if (!error) {
            if (temp > 0) {
                mpz_fdiv_r_ui(MPZ(self), MPZ(self), temp);
            }
            else if (temp == 0) {
                ZERO_ERROR("xmpz modulo by zero");
                return NULL;
            }
            else {
                mpz_cdiv_r_ui(MPZ(self), MPZ(self), -temp);
            }
        }
        else {
            mpz_set_PyIntOrLong(global.tempz, other);
            mpz_fdiv_r(MPZ(self), MPZ(self), global.tempz);
        }
        Py_INCREF(self);
        return self;
    }

    if (CHECK_MPZANY(other)) {
        if(mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("xmpz modulo by zero");
            return NULL;
        }
        mpz_fdiv_r(MPZ(self), MPZ(self), MPZ(other));
        Py_INCREF(self);
        return self;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
示例#18
0
void gcd( mpz_t g, mpz_t a, mpz_t b ) {
  mpz_t temp;
  mpz_init (temp);
  while ( mpz_cmp_ui (b, 0) > 0 ) {

    mpz_set (temp, b);
    mpz_fdiv_r (b, a, b);
    mpz_set (a, temp);

  }

  mpz_mul_ui (a, a, mpz_sgn (a));
  mpz_set (g, a);
  mpz_clear (temp);
  return;
}
示例#19
0
bool Rational::isInteger(const Rational& tolerance) const
{  
   // if denominator is 1, then it is an integer for sure
   if (mpz_cmp_ui(mpq_denref(number), 1) == 0) return true;
   // otherwise, we must check w.r.t. the given tolerance
   // first calculate the fractional part 
   Rational viol(*this);
   viol.abs();
   mpz_t r;
   mpz_init(r);
   mpz_fdiv_r(r, mpq_numref(viol.number), mpq_denref(viol.number));
   mpq_set_num(viol.number, r);
   mpz_clear(r);
   // then integrality violation
   if( viol > Rational(1, 2) )
      sub(viol, Rational(1,1), viol);
   return !(viol > tolerance);
}
示例#20
0
void Rational::integralityViolation(Rational& violation) const
{
   // if denominator is 1, then there is no integrality violation for sure
   if( mpz_cmp_ui(mpq_denref(number), 1) == 0 )
   {
      violation.toZero();
      return;
   }
   // otherwise, we must check w.r.t. the given tolerance
   // first calculate the fractional part 
   violation = (*this);
   violation.abs();
   mpz_t r;
   mpz_init(r);
   mpz_fdiv_r(r, mpq_numref(violation.number), mpq_denref(violation.number));
   mpq_set_num(violation.number, r);
   mpz_clear(r);
   // then integrality violation
   if( violation > Rational(1, 2) )
      sub(violation, Rational(1,1), violation);
}
示例#21
0
int compute(mw_work_t *work, mw_result_t **res) {
  // printf("lower_bound: %s, upper_bound: %s\n", 
  //   work->lower_bound, work->upper_bound);
  mpz_t start, end, object;  
  mpz_init_set_str(start, work->lower_bound, 10);
  mpz_init_set_str(end, work->upper_bound, 10);
  mpz_init_set_str(object, work->object, 10);
  mpz_add_ui(end, end, 1);

  node *head = NULL;
  node *prev = NULL;
  int size = 0;
  mpz_t remain;
  mpz_init(remain);
  while(mpz_cmp(start,end)){
    mpz_fdiv_r(remain, object, start);
    if(!mpz_cmp_ui(remain,0)){
      node *curr = init_node(start);
      if(head==NULL){
        head = curr;
        prev = curr;
      } else {
        prev->next = curr;
        prev = prev->next;
      }
      size++; 
    }
    mpz_add_ui(start, start, 1);
  }

  *res = (mw_result_t *) malloc((size+1) * sizeof(mw_result_t));
  int i = 0;
  for(i = 0;i < size; ++i) {
    mpz_get_str ((*res)[i].factor, 10, head->val);
    head = head->next;
  }
  
  return size;
}
示例#22
0
void
check_random (int reps)
{
  gmp_randstate_t rands;
  mpz_t   a, d, r;
  int     i;
  int     want;
 
  gmp_randinit_default(rands);
  mpz_init (a);
  mpz_init (d);
  mpz_init (r);

  for (i = 0; i < reps; i++)
    {
      mpz_erandomb (a, rands, 512);
      mpz_erandomb_nonzero (d, rands, 512);

      mpz_fdiv_r (r, a, d);

      want = (mpz_sgn (r) == 0);
      check_one (a, d, want);

      mpz_sub (a, a, r);
      check_one (a, d, 1);

      if (mpz_cmpabs_ui (d, 1L) == 0)
        continue;

      mpz_add_ui (a, a, 1L);
      check_one (a, d, 0);
    }

  mpz_clear (a);
  mpz_clear (d);
  mpz_clear (r);
  gmp_randclear(rands);
}
示例#23
0
void
check_random (int reps)
{
  gmp_randstate_ptr rands = RANDS;
  mpz_t   a, d, r;
  int     i;
  int     want;

  mpz_init (a);
  mpz_init (d);
  mpz_init (r);

  for (i = 0; i < reps; i++)
    {
      mpz_erandomb (a, rands, 1 << 19);
      mpz_erandomb_nonzero (d, rands, 1 << 18);

      mpz_fdiv_r (r, a, d);

      want = (mpz_sgn (r) == 0);
      check_one (a, d, want);

      mpz_sub (a, a, r);
      check_one (a, d, 1);

      if (mpz_cmpabs_ui (d, 1L) == 0)
        continue;

      mpz_add_ui (a, a, 1L);
      check_one (a, d, 0);
    }

  mpz_clear (a);
  mpz_clear (d);
  mpz_clear (r);
}
示例#24
0
extern void _jl_mpz_rem(mpz_t* rop, mpz_t* op1, mpz_t* op2) {
  mpz_fdiv_r(*rop, *op1, *op2);
}
示例#25
0
static gfc_dependency
gfc_check_section_vs_section (gfc_ref *lref, gfc_ref *rref, int n)
{
  gfc_array_ref l_ar;
  gfc_expr *l_start;
  gfc_expr *l_end;
  gfc_expr *l_stride;
  gfc_expr *l_lower;
  gfc_expr *l_upper;
  int l_dir;

  gfc_array_ref r_ar;
  gfc_expr *r_start;
  gfc_expr *r_end;
  gfc_expr *r_stride;
  gfc_expr *r_lower;
  gfc_expr *r_upper;
  int r_dir;

  l_ar = lref->u.ar;
  r_ar = rref->u.ar;
  
  /* If they are the same range, return without more ado.  */
  if (gfc_is_same_range (&l_ar, &r_ar, n, 0))
    return GFC_DEP_EQUAL;

  l_start = l_ar.start[n];
  l_end = l_ar.end[n];
  l_stride = l_ar.stride[n];

  r_start = r_ar.start[n];
  r_end = r_ar.end[n];
  r_stride = r_ar.stride[n];

  /* If l_start is NULL take it from array specifier.  */
  if (NULL == l_start && IS_ARRAY_EXPLICIT (l_ar.as))
    l_start = l_ar.as->lower[n];
  /* If l_end is NULL take it from array specifier.  */
  if (NULL == l_end && IS_ARRAY_EXPLICIT (l_ar.as))
    l_end = l_ar.as->upper[n];

  /* If r_start is NULL take it from array specifier.  */
  if (NULL == r_start && IS_ARRAY_EXPLICIT (r_ar.as))
    r_start = r_ar.as->lower[n];
  /* If r_end is NULL take it from array specifier.  */
  if (NULL == r_end && IS_ARRAY_EXPLICIT (r_ar.as))
    r_end = r_ar.as->upper[n];

  /* Determine whether the l_stride is positive or negative.  */
  if (!l_stride)
    l_dir = 1;
  else if (l_stride->expr_type == EXPR_CONSTANT
	   && l_stride->ts.type == BT_INTEGER)
    l_dir = mpz_sgn (l_stride->value.integer);
  else if (l_start && l_end)
    l_dir = gfc_dep_compare_expr (l_end, l_start);
  else
    l_dir = -2;

  /* Determine whether the r_stride is positive or negative.  */
  if (!r_stride)
    r_dir = 1;
  else if (r_stride->expr_type == EXPR_CONSTANT
	   && r_stride->ts.type == BT_INTEGER)
    r_dir = mpz_sgn (r_stride->value.integer);
  else if (r_start && r_end)
    r_dir = gfc_dep_compare_expr (r_end, r_start);
  else
    r_dir = -2;

  /* The strides should never be zero.  */
  if (l_dir == 0 || r_dir == 0)
    return GFC_DEP_OVERLAP;

  /* Determine LHS upper and lower bounds.  */
  if (l_dir == 1)
    {
      l_lower = l_start;
      l_upper = l_end;
    }
  else if (l_dir == -1)
    {
      l_lower = l_end;
      l_upper = l_start;
    }
  else
    {
      l_lower = NULL;
      l_upper = NULL;
    }

  /* Determine RHS upper and lower bounds.  */
  if (r_dir == 1)
    {
      r_lower = r_start;
      r_upper = r_end;
    }
  else if (r_dir == -1)
    {
      r_lower = r_end;
      r_upper = r_start;
    }
  else
    {
      r_lower = NULL;
      r_upper = NULL;
    }

  /* Check whether the ranges are disjoint.  */
  if (l_upper && r_lower && gfc_dep_compare_expr (l_upper, r_lower) == -1)
    return GFC_DEP_NODEP;
  if (r_upper && l_lower && gfc_dep_compare_expr (r_upper, l_lower) == -1)
    return GFC_DEP_NODEP;

  /* Handle cases like x:y:1 vs. x:z:-1 as GFC_DEP_EQUAL.  */
  if (l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == 0)
    {
      if (l_dir == 1 && r_dir == -1)
	return GFC_DEP_EQUAL;
      if (l_dir == -1 && r_dir == 1)
	return GFC_DEP_EQUAL;
    }

  /* Handle cases like x:y:1 vs. z:y:-1 as GFC_DEP_EQUAL.  */
  if (l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == 0)
    {
      if (l_dir == 1 && r_dir == -1)
	return GFC_DEP_EQUAL;
      if (l_dir == -1 && r_dir == 1)
	return GFC_DEP_EQUAL;
    }

  /* Handle cases like x:y:2 vs. x+1:z:4 as GFC_DEP_NODEP.
     There is no dependency if the remainder of
     (l_start - r_start) / gcd(l_stride, r_stride) is
     nonzero.
     TODO:
       - Handle cases where x is an expression.
       - Cases like a(1:4:2) = a(2:3) are still not handled.
  */

#define IS_CONSTANT_INTEGER(a) ((a) && ((a)->expr_type == EXPR_CONSTANT) \
			      && (a)->ts.type == BT_INTEGER)

  if (IS_CONSTANT_INTEGER(l_start) && IS_CONSTANT_INTEGER(r_start)
      && IS_CONSTANT_INTEGER(l_stride) && IS_CONSTANT_INTEGER(r_stride))
    {
      mpz_t gcd, tmp;
      int result;

      mpz_init (gcd);
      mpz_init (tmp);

      mpz_gcd (gcd, l_stride->value.integer, r_stride->value.integer);
      mpz_sub (tmp, l_start->value.integer, r_start->value.integer);

      mpz_fdiv_r (tmp, tmp, gcd);
      result = mpz_cmp_si (tmp, 0L);

      mpz_clear (gcd);
      mpz_clear (tmp);

      if (result != 0)
	return GFC_DEP_NODEP;
    }

#undef IS_CONSTANT_INTEGER

  /* Check for forward dependencies x:y vs. x+1:z.  */
  if (l_dir == 1 && r_dir == 1
      && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == -1
      && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == -1)
    {
      /* Check that the strides are the same.  */
      if (!l_stride && !r_stride)
	return GFC_DEP_FORWARD;
      if (l_stride && r_stride
	  && gfc_dep_compare_expr (l_stride, r_stride) == 0)
	return GFC_DEP_FORWARD;
    }

  /* Check for forward dependencies x:y:-1 vs. x-1:z:-1.  */
  if (l_dir == -1 && r_dir == -1
      && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == 1
      && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == 1)
    {
      /* Check that the strides are the same.  */
      if (!l_stride && !r_stride)
	return GFC_DEP_FORWARD;
      if (l_stride && r_stride
	  && gfc_dep_compare_expr (l_stride, r_stride) == 0)
	return GFC_DEP_FORWARD;
    }

  /* Check for backward dependencies:
     Are the strides the same?.  */
  if ((!l_stride && !r_stride)
	||
      (l_stride && r_stride
	&& gfc_dep_compare_expr (l_stride, r_stride) == 0))
    {
      /* x:y vs. x+1:z.  */
      if (l_dir == 1 && r_dir == 1
	    && l_start && r_start
	    && gfc_dep_compare_expr (l_start, r_start) == 1
	    && l_end && r_end
	    && gfc_dep_compare_expr (l_end, r_end) == 1)
	return GFC_DEP_BACKWARD;

      /* x:y:-1 vs. x-1:z:-1.  */
      if (l_dir == -1 && r_dir == -1
	    && l_start && r_start
	    && gfc_dep_compare_expr (l_start, r_start) == -1
	    && l_end && r_end
	    && gfc_dep_compare_expr (l_end, r_end) == -1)
	return GFC_DEP_BACKWARD;
    }

  return GFC_DEP_OVERLAP;
}
示例#26
0
/* p-adic logarithm */
void padiclog(mpz_t ans, const mpz_t a, unsigned long p, unsigned long prec, const mpz_t modulo) {
    /*  Compute the p-adic logarithm of a,
        which is supposed to be congruent to 1 mod p

        Algorithm:
         1. we raise a at the power p^(v-1) (for a suitable v) in order
            to make it closer to 1
         2. we write the new a as a product
              1/a = (1 - a_0*p^v) (1 - a_1*p^(2*v) (1 - a_2*p^(4*v) ...
            with 0 <= a_i < p^(v*2^i).
         3. we compute each log(1 - a_i*p^(v*2^i)) using Taylor expansion
            and a binary spliting strategy.                                */

    unsigned long i, v, e, N, saveN, Np, tmp, trunc, step;
    double den = log(p);
    mpz_t f, arg, trunc_mod, h, hpow, mpz_tmp, mpz_tmp2, d, inv, mod2;
    mpz_t *num, *denom;

    mpz_init(mpz_tmp);
    mpz_init(mpz_tmp2);
    mpz_init(arg);
    mpz_set_ui(ans, 0);

    mpz_fdiv_r_ui(mpz_tmp, a, p);
    mpz_set(arg, a);

    /* First we make the argument closer to 1 by raising it to the p^(v-1) */
    if (prec < p) {
        v = 0; e = 1;
    } else {
        v = (unsigned long)(log(prec)/den);  // v here is v-1
        e = pow(p,v);
        mpz_mul_ui(mpz_tmp, modulo, e);
        mpz_powm_ui(arg, arg, e, mpz_tmp);
        prec += v;
    }

    /* Where do we need to truncate the Taylor expansion */
    N = prec+v; N /= ++v;                 // note the ++v
    Np = N;
    den *= v;
    while(1) {
        tmp = Np + (unsigned long)(log(N)/den);
        if (tmp == N) break;
        N = tmp;
    }

    /* We allocate memory and initialize variables */
    mpz_init(f); mpz_init(mod2);
    mpz_init(h); mpz_init(hpow);
    mpz_init(d); mpz_init(inv);
    sig_block();
    num = (mpz_t*)malloc(N*sizeof(mpz_t));
    denom = (mpz_t*)malloc(N*sizeof(mpz_t));
    sig_unblock();
    for (i = 0; i < N; i++) {
        mpz_init(num[i]);
        mpz_init(denom[i]);
    }

    trunc = v << 1;
    mpz_init(trunc_mod);
    mpz_ui_pow_ui(trunc_mod, p, trunc);
    while(1) {
        /* We compute f = 1 - a_i*p^((v+1)*2^i)
           trunc_mod is p^((v+1)*2^(i+1)) */
        mpz_fdiv_r(f, arg, trunc_mod);

        if (mpz_cmp_ui(f, 1) != 0) {

            mpz_ui_sub(f, 2, f);
            mpz_mul(arg, arg, f);

            /* We compute the Taylor expansion of log(f)
               For now, computations are carried out over the rationals */
            for (i = 0; i < N; i++) {
                mpz_set_ui(num[i], 1);
                mpz_set_ui(denom[i], i+1);
            }
            step = 1;
            mpz_ui_sub(h, 1, f);   // we write f = 1 - h, i.e. h = a_i*p^(2^i)
            mpz_set(hpow, h);
            while(step < N) {
                for (i = 0; i < N - step; i += step << 1) {
                    mpz_mul(mpz_tmp2, hpow, num[i+step]);
                    mpz_mul(mpz_tmp, mpz_tmp2, denom[i]);
                    mpz_mul(num[i], num[i], denom[i+step]);
                    mpz_add(num[i], num[i], mpz_tmp);
                    mpz_mul(denom[i], denom[i], denom[i+step]);
                }
                step <<= 1;
                mpz_mul(hpow, hpow, hpow);
            }

            /* We simplify the fraction */
            Np = N; tmp = 0;
            while(Np > 0) { Np /= p; tmp += Np; }
            mpz_ui_pow_ui(d, p, tmp);
            mpz_divexact(mpz_tmp, num[0], d);
            mpz_divexact(denom[0], denom[0], d);

            mpz_divexact_ui(h, h, e);
            mpz_mul(mpz_tmp, h, mpz_tmp);

            /* We coerce the result from Q to Zp */
            mpz_gcdext(d, inv, NULL, denom[0], modulo);
            mpz_mul(mpz_tmp, mpz_tmp, inv);

            /* We add this contribution to log(f) */
            mpz_add(ans, ans, mpz_tmp);

        }

        if (trunc > prec) break;

        /* We update the variables for the next step */
        mpz_mul(trunc_mod, trunc_mod, trunc_mod);
        trunc <<= 1;
        for (i = N >> 1; i < N; i++) {
            mpz_clear(num[i]);
            mpz_clear(denom[i]);
        }
        N >>= 1;
    }

    mpz_fdiv_r(ans, ans, modulo);

    /* We clear memory */
    mpz_clear(arg);
    mpz_clear(f);
    mpz_clear(trunc_mod);
    mpz_clear(h);
    mpz_clear(hpow);
    mpz_clear(mpz_tmp);
    mpz_clear(d);
    mpz_clear(inv);
    mpz_clear(mod2);
    for (i = 0; i < N; i++) {
        mpz_clear(num[i]);
        mpz_clear(denom[i]);
    }
    sig_block();
    free(num);
    free(denom);
    sig_unblock();
}
示例#27
0
static PyObject *
GMPy_Integer_Mod(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPZ_Object *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPZ_New(context)))
        return NULL;

    if (CHECK_MPZANY(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            long temp = GMPy_Integer_AsLongAndError(y, &error);
            
            if (!error) {
                if (temp > 0) {
                    mpz_fdiv_r_ui(result->z, MPZ(x), temp);
                }
                else if (temp == 0) {
                    ZERO_ERROR("division or modulo by zero");
                    Py_DECREF((PyObject*)result);
                    return NULL;
                }
                else {
                    mpz_cdiv_r_ui(result->z, MPZ(x), -temp);
                }
            }
            else {
                mpz_t tempz;
                mpz_inoc(tempz);
                mpz_set_PyIntOrLong(tempz, y);
                mpz_fdiv_r(result->z, MPZ(x), tempz);
                mpz_cloc(tempz);
            }
            return (PyObject*)result;
        }
        
        if (CHECK_MPZANY(y)) {
            if (mpz_sgn(MPZ(y)) == 0) {
                ZERO_ERROR("division or modulo by zero");
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpz_fdiv_r(result->z, MPZ(x), MPZ(y));
            return (PyObject*)result;
        }
    }

    if (CHECK_MPZANY(y)) {
        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        
        if (PyIntOrLong_Check(x)) {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, x);
            mpz_fdiv_r(result->z, tempz, MPZ(y));
            mpz_cloc(tempz);
            return (PyObject*)result;
        }
    }

    if (IS_INTEGER(x) && IS_INTEGER(y)) {
        MPZ_Object *tempx, *tempy;
        
        tempx = GMPy_MPZ_From_Integer(x, context);
        tempy = GMPy_MPZ_From_Integer(y, context);
        if (!tempx || !tempy) {
            SYSTEM_ERROR("could not convert Integer to mpz");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        if (mpz_sgn(tempy->z) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_fdiv_r(result->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;
}
示例#28
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;
}
示例#30
0
void ConstFoldBinop(BinopKind kind,
                    const mpz_t left_val, const mpz_t right_val, mpz_t res)
{
  switch (kind) {

  case B_Plus:
    mpz_add(res, left_val, right_val);
    break;

  case B_Minus:
  case B_MinusPP: // TODO: include scaling here?
    mpz_sub(res, left_val, right_val);
    break;

  case B_Mult:
    mpz_mul(res, left_val, right_val);
    break;

  case B_Div:
  case B_DivExact:  // treat like regular division during folding.
    // leave zero value for division by zero.
    if (mpz_cmp_si(right_val, 0) != 0)
      mpz_fdiv_q(res, left_val, right_val);
    break;

  case B_Mod:
    // ditto for modulus by zero or negative values.
    if (mpz_cmp_si(right_val, 0) > 0)
      mpz_fdiv_r(res, left_val, right_val);
    break;

  case B_ShiftLeft:
    // ditto for left shifts by negative or large values.
    if (mpz_cmp_si(right_val, 0) >= 0 &&
        mpz_cmp_si(right_val, 64) <= 0)
      mpz_mul_2exp(res, left_val, mpz_get_ui(right_val));
    break;

  case B_ShiftRight:
    // ditto for right shifts by negative values or large values.
    if (mpz_cmp_si(right_val, 0) >= 0 &&
        mpz_cmp_si(right_val, 64) <= 0)
      mpz_tdiv_q_2exp(res, left_val, mpz_get_ui(right_val));
    break;

  case B_BitwiseAnd:
    mpz_and(res, left_val, right_val);
    break;

  case B_BitwiseOr:
    mpz_ior(res, left_val, right_val);
    break;

  case B_BitwiseXOr:
    mpz_xor(res, left_val, right_val);
    break;

  case B_Min:
    if (mpz_cmp(left_val, right_val) < 0)
      mpz_set(res, left_val);
    else
      mpz_set(res, right_val);
    break;

  case B_Max:
    if (mpz_cmp(left_val, right_val) > 0)
      mpz_set(res, left_val);
    else
      mpz_set(res, right_val);
    break;

  case B_LessThan:
  case B_LessThanP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) < 0);
    break;

  case B_GreaterThan:
  case B_GreaterThanP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) > 0);
    break;

  case B_LessEqual:
  case B_LessEqualP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) <= 0);
    break;

  case B_GreaterEqual:
  case B_GreaterEqualP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) >= 0);
    break;

  case B_Equal:
  case B_EqualP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) == 0);
    break;

  case B_NotEqual:
  case B_NotEqualP:
    FoldBoolean(res, mpz_cmp(left_val, right_val) != 0);
    break;

  case B_LogicalAnd:
    FoldBoolean(res, mpz_cmp_si(left_val, 0) != 0 &&
                     mpz_cmp_si(right_val, 0) != 0);
    break;

  case B_LogicalOr:
    FoldBoolean(res, mpz_cmp_si(left_val, 0) != 0 ||
                     mpz_cmp_si(right_val, 0) != 0);
    break;

  default:
    logout << "ERROR: ConstFoldBinop: Unexpected "
           << BinopString(kind)
           << " " << left_val << " " << right_val << endl;
    Assert(false);
  }
}