Exemple #1
0
static int
mpfr_fsss (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr c, mpfr_rnd_t rnd)
{
   /* Computes z = a^2 - c^2.
      Assumes that a and c are finite and non-zero; so a squaring yielding
      an infinity is an overflow, and a squaring yielding 0 is an underflow.
      Assumes further that z is distinct from a and c. */

   int inex;
   mpfr_t u, v;

   /* u=a^2, v=c^2 exactly */
   mpfr_init2 (u, 2*mpfr_get_prec (a));
   mpfr_init2 (v, 2*mpfr_get_prec (c));
   mpfr_sqr (u, a, MPFR_RNDN);
   mpfr_sqr (v, c, MPFR_RNDN);

   /* tentatively compute z as u-v; here we need z to be distinct
      from a and c to not lose the latter */
   inex = mpfr_sub (z, u, v, rnd);

   if (mpfr_inf_p (z)) {
      /* replace by "correctly rounded overflow" */
      mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), MPFR_RNDN);
      inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd);
   }
   else if (mpfr_zero_p (u) && !mpfr_zero_p (v)) {
      /* exactly u underflowed, determine inexact flag */
      inex = (mpfr_signbit (u) ? 1 : -1);
   }
   else if (mpfr_zero_p (v) && !mpfr_zero_p (u)) {
      /* exactly v underflowed, determine inexact flag */
      inex = (mpfr_signbit (v) ? -1 : 1);
   }
   else if (mpfr_nan_p (z) || (mpfr_zero_p (u) && mpfr_zero_p (v))) {
      /* In the first case, u and v are +inf.
         In the second case, u and v are zeroes; their difference may be 0
         or the least representable number, with a sign to be determined.
         Redo the computations with mpz_t exponents */
      mpfr_exp_t ea, ec;
      mpz_t eu, ev;
         /* cheat to work around the const qualifiers */

      /* Normalise the input by shifting and keep track of the shifts in
         the exponents of u and v */
      ea = mpfr_get_exp (a);
      ec = mpfr_get_exp (c);

      mpfr_set_exp ((mpfr_ptr) a, (mpfr_prec_t) 0);
      mpfr_set_exp ((mpfr_ptr) c, (mpfr_prec_t) 0);

      mpz_init (eu);
      mpz_init (ev);
      mpz_set_si (eu, (long int) ea);
      mpz_mul_2exp (eu, eu, 1);
      mpz_set_si (ev, (long int) ec);
      mpz_mul_2exp (ev, ev, 1);

      /* recompute u and v and move exponents to eu and ev */
      mpfr_sqr (u, a, MPFR_RNDN);
      /* exponent of u is non-positive */
      mpz_sub_ui (eu, eu, (unsigned long int) (-mpfr_get_exp (u)));
      mpfr_set_exp (u, (mpfr_prec_t) 0);
      mpfr_sqr (v, c, MPFR_RNDN);
      mpz_sub_ui (ev, ev, (unsigned long int) (-mpfr_get_exp (v)));
      mpfr_set_exp (v, (mpfr_prec_t) 0);
      if (mpfr_nan_p (z)) {
         mpfr_exp_t emax = mpfr_get_emax ();
         int overflow;
         /* We have a = ma * 2^ea with 1/2 <= |ma| < 1 and ea <= emax.
            So eu <= 2*emax, and eu > emax since we have
            an overflow. The same holds for ev. Shift u and v by as much as
            possible so that one of them has exponent emax and the
            remaining exponents in eu and ev are the same. Then carry out
            the addition. Shifting u and v prevents an underflow. */
         if (mpz_cmp (eu, ev) >= 0) {
            mpfr_set_exp (u, emax);
            mpz_sub_ui (eu, eu, (long int) emax);
            mpz_sub (ev, ev, eu);
            mpfr_set_exp (v, (mpfr_exp_t) mpz_get_ui (ev));
               /* remaining common exponent is now in eu */
         }
         else {
            mpfr_set_exp (v, emax);
            mpz_sub_ui (ev, ev, (long int) emax);
            mpz_sub (eu, eu, ev);
            mpfr_set_exp (u, (mpfr_exp_t) mpz_get_ui (eu));
            mpz_set (eu, ev);
               /* remaining common exponent is now also in eu */
         }
         inex = mpfr_sub (z, u, v, rnd);
            /* Result is finite since u and v have the same sign. */
         overflow = mpfr_mul_2ui (z, z, mpz_get_ui (eu), rnd);
         if (overflow)
            inex = overflow;
      }
      else {
         int underflow;
         /* Subtraction of two zeroes. We have a = ma * 2^ea
            with 1/2 <= |ma| < 1 and ea >= emin and similarly for b.
            So 2*emin < 2*emin+1 <= eu < emin < 0, and analogously for v. */
         mpfr_exp_t emin = mpfr_get_emin ();
         if (mpz_cmp (eu, ev) <= 0) {
            mpfr_set_exp (u, emin);
            mpz_add_ui (eu, eu, (unsigned long int) (-emin));
            mpz_sub (ev, ev, eu);
            mpfr_set_exp (v, (mpfr_exp_t) mpz_get_si (ev));
         }
         else {
            mpfr_set_exp (v, emin);
            mpz_add_ui (ev, ev, (unsigned long int) (-emin));
            mpz_sub (eu, eu, ev);
            mpfr_set_exp (u, (mpfr_exp_t) mpz_get_si (eu));
            mpz_set (eu, ev);
         }
         inex = mpfr_sub (z, u, v, rnd);
         mpz_neg (eu, eu);
         underflow = mpfr_div_2ui (z, z, mpz_get_ui (eu), rnd);
         if (underflow)
            inex = underflow;
      }

      mpz_clear (eu);
      mpz_clear (ev);

      mpfr_set_exp ((mpfr_ptr) a, ea);
      mpfr_set_exp ((mpfr_ptr) c, ec);
         /* works also when a == c */
   }

   mpfr_clear (u);
   mpfr_clear (v);

   return inex;
}
Exemple #2
0
int main(int argc, char **argv) {
    mpz_t year, tmp1, tmp2, tmp3, tmp4;
    unsigned long day_of_week = 0;
    uintmax_t month_min = 1, month_max = 12;
    int_fast8_t month_days = 0;
    const int_fast8_t months_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
                                          30, 31
                                        };
    time_t t = time(NULL);
    char weekday[13] = {0}, weekdays[92] = {0}, month_name[13] = {0};
    struct tm *time_struct = localtime(&t);
    setlocale(LC_ALL, "");
    mpz_init(year);
    switch(argc) {
    case 1:
        mpz_set_ui(year, time_struct->tm_year + 1900);
        month_min = month_max = time_struct->tm_mon + 1;
        break;
    case 2:
        mpz_set_str(year, argv[1], 10);
        break;
    default:
        month_min = month_max = strtoumax(argv[1], NULL, 10);
        mpz_set_str(year, argv[2], 10);
    }
    if(mpz_sgn(year) < 1 || !month_min || month_min > 12) {
        fputs("http://opengroup.org/onlinepubs/9699919799/utilities/cal.html\n",
              stderr);
        exit(1);
    }
    for(int_fast8_t i = 0; i < 7; ++i) {
        time_struct->tm_wday = i;
        strftime(weekday, 13, "%a", time_struct);
        strcat(weekdays, weekday);
        strcat(weekdays, " ");
    }
    strcat(weekdays, "\n");
    for(uintmax_t month = month_min; month <= month_max; ++month) {
        time_struct->tm_mon = month - 1;
        strftime(month_name, 13, "%b", time_struct);
        if(month > month_min) putchar('\n');
        for(int_fast8_t i = (23 - strlen(mpz_get_str(NULL, 10, year))) / 2; i > 0; --i)
            putchar(' ');
        fputs(month_name, stdout);
        putchar(' ');
        printf("%s\n", mpz_get_str(NULL, 10, year));
        fputs(weekdays, stdout);
        if(!mpz_cmp_ui(year, 1752) && month == 9) {
            fputs("         1   2  14  15  16", stdout);
            fputs("17  18  19  20  21  22  23", stdout);
            fputs("24  25  26  27  28  29  30", stdout);
        } else {
            month_days = months_days[month - 1];
            mpz_init(tmp1);
            mpz_init(tmp2);
            mpz_init(tmp3);
            mpz_init(tmp4);
            if(mpz_cmp_ui(year, 1752) > 0 || (!mpz_cmp_ui(year, 1752) && month > 9)) {
                /* Gregorian */
                if(month == 2 && mpz_divisible_ui_p(year, 4) && (!mpz_divisible_ui_p(year,
                        100) || mpz_divisible_ui_p(year, 400))) month_days = 29;
                mpz_add_ui(tmp4, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp4, 4);
                mpz_tdiv_q_ui(tmp2, tmp4, 100);
                mpz_tdiv_q_ui(tmp3, tmp4, 400);
                mpz_mul_ui(tmp4, tmp4, 365);
                mpz_add(tmp4, tmp4, tmp1);
                mpz_sub(tmp4, tmp4, tmp2);
                mpz_add(tmp4, tmp4, tmp3);
                mpz_add_ui(tmp4, tmp4, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp4, tmp4, 32043);
                day_of_week = mpz_tdiv_ui(tmp4, 7);
            } else {
                /* Julian */
                if(month == 2 && mpz_divisible_ui_p(year, 4))
                    month_days = 29;
                mpz_add_ui(tmp2, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp2, 4);
                mpz_mul_ui(tmp2, tmp2, 365);
                mpz_add(tmp2, tmp2, tmp1);
                mpz_add_ui(tmp2, tmp2, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp2, tmp2, 32081);
                day_of_week = mpz_tdiv_ui(tmp2, 7);
            }
            mpz_clear(tmp1);
            mpz_clear(tmp2);
            mpz_clear(tmp3);
            mpz_clear(tmp4);
            for(uint_fast8_t i = 0; i < day_of_week; ++i) fputs("    ", stdout);
            for(int_fast8_t i = 1; i <= month_days; ++i) {
                printf("%2u", i);
                ++day_of_week;
                if(i < month_days)
                    fputs((day_of_week %= 7) ? "  " : "\n", stdout);
            }
        }
        putchar('\n');
    }
    mpz_clear(year);
    return 0;
}
Exemple #3
0
void
mpz_bin_ui (mpz_ptr r, mpz_srcptr n, unsigned long int k)
{
  mpz_t      ni;
  mp_limb_t  i;
  mpz_t      nacc;
  mp_limb_t  kacc;
  mp_size_t  negate;

  if (mpz_sgn (n) < 0)
    {
      /* bin(n,k) = (-1)^k * bin(-n+k-1,k), and set ni = -n+k-1 - k = -n-1 */
      mpz_init (ni);
      mpz_neg (ni, n);
      mpz_sub_ui (ni, ni, 1L);
      negate = (k & 1);   /* (-1)^k */
    }
  else
    {
      /* bin(n,k) == 0 if k>n
         (no test for this under the n<0 case, since -n+k-1 >= k there) */
      if (mpz_cmp_ui (n, k) < 0)
        {
          mpz_set_ui (r, 0L);
          return;
        }

      /* set ni = n-k */
      mpz_init (ni);
      mpz_sub_ui (ni, n, k);
      negate = 0;
    }

  /* Now wanting bin(ni+k,k), with ni positive, and "negate" is the sign (0
     for positive, 1 for negative). */
  mpz_set_ui (r, 1L);

  /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller.  In this case it's
     whether ni+k-k < k meaning ni<k, and if so change to denominator ni+k-k
     = ni, and new ni of ni+k-ni = k.  */
  if (mpz_cmp_ui (ni, k) < 0)
    {
      unsigned long  tmp;
      tmp = k;
      k = mpz_get_ui (ni);
      mpz_set_ui (ni, tmp);
    }

  kacc = 1;
  mpz_init_set_ui (nacc, 1L);

  for (i = 1; i <= k; i++)
    {
      mp_limb_t k1, k0;

#if 0
      mp_limb_t nacclow;
      int c;

      nacclow = PTR(nacc)[0];
      for (c = 0; (((kacc | nacclow) & 1) == 0); c++)
	{
	  kacc >>= 1;
	  nacclow >>= 1;
	}
      mpz_div_2exp (nacc, nacc, c);
#endif

      mpz_add_ui (ni, ni, 1L);
      mpz_mul (nacc, nacc, ni);
      umul_ppmm (k1, k0, kacc, i << GMP_NAIL_BITS);
      k0 >>= GMP_NAIL_BITS;
      if (k1 != 0)
	{
	  /* Accumulator overflow.  Perform bignum step.  */
	  mpz_mul (r, r, nacc);
	  mpz_set_ui (nacc, 1L);
          DIVIDE ();
	  kacc = i;
	}
      else
	{
	  /* Save new products in accumulators to keep accumulating.  */
	  kacc = k0;
	}
    }

  mpz_mul (r, r, nacc);
  DIVIDE ();
  SIZ(r) = (SIZ(r) ^ -negate) + negate;

  mpz_clear (nacc);
  mpz_clear (ni);
}
Exemple #4
0
static PyObject *
GMPY_mpz_is_strong_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t s, nm1, mpz_test;
    mp_bitcnt_t r = 0;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_strong_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(s);
    mpz_init(nm1);
    mpz_init(mpz_test);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_strong_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_strong_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;
    }

    /* Check gcd(a,b) */
    mpz_gcd(s, n->z, a->z);
    if (mpz_cmp_ui(s, 1) > 0) {
        VALUE_ERROR("is_strong_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(nm1, n->z);
    mpz_sub_ui(nm1, nm1, 1);

    /* Find s and r satisfying: n-1=(2^r)*s, s odd */
    r = mpz_scan1(nm1, 0);
    mpz_fdiv_q_2exp(s, nm1, r);


    /* Check a^((2^t)*s) mod n for 0 <= t < r */
    mpz_powm(mpz_test, a->z, s, n->z);
    if ((mpz_cmp_ui(mpz_test, 1) == 0) || (mpz_cmp(mpz_test, nm1) == 0)) {
        result = Py_True;
        goto cleanup;
    }

    while (--r) {
        /* mpz_test = mpz_test^2%n */
        mpz_mul(mpz_test, mpz_test, mpz_test);
        mpz_mod(mpz_test, mpz_test, n->z);

        if (mpz_cmp(mpz_test, nm1) == 0) {
            result = Py_True;
            goto cleanup;
        }
    }

    result = Py_False;
  cleanup:
    Py_XINCREF(result);
    mpz_clear(s);
    mpz_clear(nm1);
    mpz_clear(mpz_test);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Exemple #5
0
static PyObject *
GMPY_mpz_is_lucas_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p, *q;
    PyObject *result = 0;
    mpz_t zD, res, index;
    /* used for calculating the Lucas U sequence */
    mpz_t uh, vl, vh, ql, qh, tmp;
    mp_bitcnt_t s = 0, j = 0;
    int ret;

    if (PyTuple_Size(args) != 3) {
        TYPE_ERROR("is_lucas_prp() requires 3 integer arguments");
        return NULL;
    }

    mpz_init(zD);
    mpz_init(res);
    mpz_init(index);
    mpz_init(uh);
    mpz_init(vl);
    mpz_init(vh);
    mpz_init(ql);
    mpz_init(qh);
    mpz_init(tmp);

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL);
    if (!n || !p || !q) {
        TYPE_ERROR("is_lucas_prp() requires 3 integer arguments");
        goto cleanup;
    }

    /* Check if p*p - 4*q == 0. */
    mpz_mul(zD, p->z, p->z);
    mpz_mul_ui(tmp, q->z, 4);
    mpz_sub(zD, zD, tmp);
    if (mpz_sgn(zD) == 0) {
        VALUE_ERROR("invalid values for p,q in is_lucas_prp()");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_lucas_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;
    }

    /* Check GCD */
    mpz_mul(res, zD, q->z);
    mpz_mul_ui(res, res, 2);
    mpz_gcd(res, res, n->z);
    if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) {
        VALUE_ERROR("is_lucas_prp() requires gcd(n,2*q*D) == 1");
        goto cleanup;
    }

    /* index = n-(D/n), where (D/n) is the Jacobi symbol */
    mpz_set(index, n->z);
    ret = mpz_jacobi(zD, n->z);
    if (ret == -1)
        mpz_add_ui(index, index, 1);
    else if (ret == 1)
        mpz_sub_ui(index, index, 1);

    /* mpz_lucasumod(res, p, q, index, n); */
    mpz_set_si(uh, 1);
    mpz_set_si(vl, 2);
    mpz_set(vh, p->z);
    mpz_set_si(ql, 1);
    mpz_set_si(qh, 1);
    mpz_set_si(tmp,0);

    s = mpz_scan1(index, 0);
    for (j = mpz_sizeinbase(index,2)-1; j >= s+1; j--) {
        /* ql = ql*qh (mod n) */
        mpz_mul(ql, ql, qh);
        mpz_mod(ql, ql, n->z);
        if (mpz_tstbit(index,j) == 1) {
            /* qh = ql*q */
            mpz_mul(qh, ql, q->z);

            /* uh = uh*vh (mod n) */
            mpz_mul(uh, uh, vh);
            mpz_mod(uh, uh, n->z);

            /* vl = vh*vl - p*ql (mod n) */
            mpz_mul(vl, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);

            /* vh = vh*vh - 2*qh (mod n) */
            mpz_mul(vh, vh, vh);
            mpz_mul_si(tmp, qh, 2);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);
        }
        else {
            /* qh = ql */
            mpz_set(qh, ql);

            /* uh = uh*vl - ql (mod n) */
            mpz_mul(uh, uh, vl);
            mpz_sub(uh, uh, ql);
            mpz_mod(uh, uh, n->z);

            /* vh = vh*vl - p*ql (mod n) */
            mpz_mul(vh, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);

            /* vl = vl*vl - 2*ql (mod n) */
            mpz_mul(vl, vl, vl);
            mpz_mul_si(tmp, ql, 2);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);
        }
    }
    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    /* qh = ql*q */
    mpz_mul(qh, ql, q->z);

    /* uh = uh*vl - ql */
    mpz_mul(uh, uh, vl);
    mpz_sub(uh, uh, ql);

    /* vl = vh*vl - p*ql */
    mpz_mul(vl, vh, vl);
    mpz_mul(tmp, ql, p->z);
    mpz_sub(vl, vl, tmp);

    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    for (j = 1; j <= s; j++) {
        /* uh = uh*vl (mod n) */
        mpz_mul(uh, uh, vl);
        mpz_mod(uh, uh, n->z);

        /* vl = vl*vl - 2*ql (mod n) */
        mpz_mul(vl, vl, vl);
        mpz_mul_si(tmp, ql, 2);
        mpz_sub(vl, vl, tmp);
        mpz_mod(vl, vl, n->z);

        /* ql = ql*ql (mod n) */
        mpz_mul(ql, ql, ql);
        mpz_mod(ql, ql, n->z);
    }

    /* uh contains our return value */
    mpz_mod(res, uh, n->z);
    if (mpz_cmp_ui(res, 0) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(zD);
    mpz_clear(res);
    mpz_clear(index);
    mpz_clear(uh);
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    Py_XDECREF((PyObject*)p);
    Py_XDECREF((PyObject*)q);
    Py_XDECREF((PyObject*)n);
    return result;
}
Exemple #6
0
int main(void) {
  mpz_t p, q, N, d;
  mpz_t dmp1, dmq1;
  mpz_t ipmq, iqmp;
  mpz_t adq, adp;

  field_t f;
  element_t a, b;
  double t0, t1, tnaive = 0, tcrt=0;
  int i, n;

  mpz_init(p);
  mpz_init(q);
  mpz_init(N);
  mpz_init(d);
  mpz_init(dmp1);
  mpz_init(dmq1);
  mpz_init(ipmq);
  mpz_init(iqmp);
  mpz_init(adp);
  mpz_init(adq);
  pbc_mpz_randomb(p, 512);
  pbc_mpz_randomb(q, 512);
  mpz_nextprime(p, p);
  mpz_nextprime(q, q);
  mpz_mul(N, p, q);
  mpz_invert(ipmq, p, q);
  mpz_invert(iqmp, q, p);

  field_init_fp(f, N);
  element_init(a, f);
  element_init(b, f);
  n = 10;
  for (i=0; i<n; i++) {
    pbc_mpz_random(d, N);
    element_random(a);
    t0 = pbc_get_time();
    element_pow_mpz(b, a, d);
    t1 = pbc_get_time();
    tnaive += t1 - t0;

    mpz_sub_ui(p, p, 1);
    mpz_sub_ui(q, q, 1);

    mpz_mod(dmp1, d, p);
    mpz_mod(dmq1, d, q);

    mpz_add_ui(p, p, 1);
    mpz_add_ui(q, q, 1);

    element_to_mpz(adq, a);
    element_to_mpz(adp, a);

    t0 = pbc_get_time();
    mpz_powm(adp, adp, d, p);
    mpz_powm(adq, adq, d, q);

    /* textbook CRT
    mpz_mul(adp, adp, q);
    mpz_mul(adp, adp, iqmp);
    mpz_mul(adq, adq, p);
    mpz_mul(adq, adq, ipmq);
    mpz_add(adp, adp, adq);
    */
    // Garner's algorithm
    mpz_sub(adq, adq, adp);
    mpz_mul(adq, adq, ipmq);
    mpz_mod(adq, adq, q);
    mpz_mul(adq, adq, p);
    mpz_add(adp, adp, adq);

    t1 = pbc_get_time();
    tcrt += t1 - t0;
    element_set_mpz(b, adp);
  }
  printf("average RSA exp time = %lf\n", tnaive / n);
  printf("average RSA exp time (CRT) = %lf\n", tcrt / n);
  return 0;
}
Exemple #7
0
static void derive_rsa_keys(MP_INT *n, MP_INT *e, MP_INT *d, MP_INT *u,

                         MP_INT *p, MP_INT *q,

                         unsigned int ebits)

{

  MP_INT p_minus_1, q_minus_1, aux, phi, G, F;



  assert(mpz_cmp(p, q) < 0);



  mpz_init(&p_minus_1);

  mpz_init(&q_minus_1);

  mpz_init(&aux);

  mpz_init(&phi);

  mpz_init(&G);

  mpz_init(&F);



  /* Compute p-1 and q-1. */

  mpz_sub_ui(&p_minus_1, p, 1);

  mpz_sub_ui(&q_minus_1, q, 1);



  /* phi = (p - 1) * (q - 1); the number of positive integers less than p*q

     that are relatively prime to p*q. */

  mpz_mul(&phi, &p_minus_1, &q_minus_1);



  /* G is the number of "spare key sets" for a given modulus n.  The smaller

     G is, the better.  The smallest G can get is 2. */

  mpz_gcd(&G, &p_minus_1, &q_minus_1);



  if (rsa_verbose)

    {

      if (mpz_cmp_ui(&G, 100) >= 0)

       {

         fprintf(stderr, "Warning: G=");

         mpz_out_str(stdout, 10, &G);

         fprintf(stderr, " is large (many spare key sets); key may be bad!\n");

       }

    }



  /* F = phi / G; the number of relative prime numbers per spare key set. */

  mpz_div(&F, &phi, &G);



  /* Find a suitable e (the public exponent). */

  mpz_set_ui(e, 1);

  mpz_mul_2exp(e, e, ebits);

  mpz_sub_ui(e, e, 1); /* make lowest bit 1, and substract 2. */

  /* Keep adding 2 until it is relatively prime to (p-1)(q-1). */

  do

    {

      mpz_add_ui(e, e, 2);

      mpz_gcd(&aux, e, &phi);

    }

  while (mpz_cmp_ui(&aux, 1) != 0);



  /* d is the multiplicative inverse of e, mod F.  Could also be mod

     (p-1)(q-1); however, we try to choose the smallest possible d. */

  mpz_mod_inverse(d, e, &F);



  /* u is the multiplicative inverse of p, mod q, if p < q.  It is used

     when doing private key RSA operations using the chinese remainder

     theorem method. */

  mpz_mod_inverse(u, p, q);



  /* n = p * q (the public modulus). */

  mpz_mul(n, p, q);



  /* Clear auxiliary variables. */

  mpz_clear(&p_minus_1);

  mpz_clear(&q_minus_1);

  mpz_clear(&aux);

  mpz_clear(&phi);

  mpz_clear(&G);

  mpz_clear(&F);

}
Exemple #8
0
void pbc_param_init_e_gen(pbc_param_t par, int rbits, int qbits) {
  e_init(par);
  e_param_ptr p = par->data;
  //3 takes 2 bits to represent
  int hbits = (qbits - 2) / 2 - rbits;
  mpz_ptr q = p->q;
  mpz_ptr r = p->r;
  mpz_ptr h = p->h;
  mpz_t n;
  field_t Fq;
  field_t cc;
  element_t j;
  int found = 0;

  //won't find any curves is hbits is too low
  if (hbits < 3) hbits = 3;

  mpz_init(n);

  do {
    int i;
    mpz_set_ui(r, 0);

    if (rand() % 2) {
      p->exp2 = rbits - 1;
      p->sign1 = 1;
    } else {
      p->exp2 = rbits;
      p->sign1 = -1;
    }
    mpz_setbit(r, p->exp2);

    p->exp1 = (rand() % (p->exp2 - 1)) + 1;
    //use q as a temp variable
    mpz_set_ui(q, 0);
    mpz_setbit(q, p->exp1);

    if (p->sign1 > 0) {
      mpz_add(r, r, q);
    } else {
      mpz_sub(r, r, q);
    }

    if (rand() % 2) {
      p->sign0 = 1;
      mpz_add_ui(r, r, 1);
    } else {
      p->sign0 = -1;
      mpz_sub_ui(r, r, 1);
    }
    if (!mpz_probab_prime_p(r, 10)) continue;
    for (i=0; i<10; i++) {
      //use q as a temp variable
      mpz_set_ui(q, 0);
      mpz_setbit(q, hbits + 1);
      pbc_mpz_random(h, q);
      mpz_mul(h, h, h);
      mpz_mul_ui(h, h, 3);
      //finally q takes the value it should
      mpz_mul(n, r, r);
      mpz_mul(n, n, h);
      mpz_add_ui(q, n, 1);
      if (mpz_probab_prime_p(q, 10)) {
        found = 1;
        break;
      }
    }
  } while (!found);
  /*
  do {
    mpz_set_ui(r, 0);
    mpz_setbit(r, rbits);
    pbc_mpz_random(r, r);
    mpz_nextprime(r, r);
    mpz_mul(n, r, r);
    mpz_mul_ui(n, n, 3);
    mpz_add_ui(q, n, 1);
  } while (!mpz_probab_prime_p(q, 10));
  */

  field_init_fp(Fq, q);
  element_init(j, Fq);
  element_set_si(j, 1);
  field_init_curve_b(cc, j, n, NULL);
  element_clear(j);
  // We may need to twist it.
  {
    // Pick a random point P and twist the curve if P has the wrong order.
    element_t P;
    element_init(P, cc);
    element_random(P);
    element_mul_mpz(P, P, n);
    if (!element_is0(P)) field_reinit_curve_twist(cc);
    element_clear(P);
  }
  element_to_mpz(p->a, curve_field_a_coeff(cc));
  element_to_mpz(p->b, curve_field_b_coeff(cc));

  mpz_clear(n);
}
/* 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;
}
Exemple #10
0
int
main (int argc, char *argv[])
{
  char *progname = argv[0];
  mpz_t fr, to;
  mpz_t fr2, to2;
  unsigned long sieve_lim;
  unsigned long est_n_primes;
  unsigned char *s;
  mpz_t tmp;
  mpz_t siev_sqr_lim;

  while (argc != 1)
    {
      if (strcmp (argv[1], "-c") == 0)
	{
	  flag_count = 1;
	  argv++;
	  argc--;
	}
      else if (strcmp (argv[1], "-p") == 0)
	{
	  flag_print = 2;
	  argv++;
	  argc--;
	}
      else if (strcmp (argv[1], "-g") == 0)
	{
	  flag_maxgap = 1;
	  argv++;
	  argc--;
	}
      else
	break;
    }

  if (flag_count || flag_maxgap)
    flag_print--;		/* clear unless an explicit -p  */

  mpz_init (fr);
  mpz_init (to);
  mpz_init (fr2);
  mpz_init (to2);

  if (argc == 3)
    {
      mpz_set_str (fr, argv[1], 0);
      if (argv[2][0] == '+')
	{
	  mpz_set_str (to, argv[2] + 1, 0);
	  mpz_add (to, to, fr);
	}
      else
	mpz_set_str (to, argv[2], 0);
    }
  else if (argc == 2)
    {
      mpz_set_ui (fr, 0);
      mpz_set_str (to, argv[1], 0);
    }
  else
    {
      fprintf (stderr, "usage: %s [-c] [-p] [-g] [from [+]]to\n", progname);
      exit (1);
    }

  mpz_set (fr2, fr);
  if (mpz_cmp_ui (fr2, 3) < 0)
    {
      mpz_set_ui (fr2, 2);
      report (fr2);
      mpz_set_ui (fr2, 3);
    }
  mpz_setbit (fr2, 0);				/* make odd */
  mpz_sub_ui (to2, to, 1);
  mpz_setbit (to2, 0);				/* make odd */

  mpz_init (tmp);
  mpz_init (siev_sqr_lim);

  mpz_sqrt (tmp, to2);
#define SIEVE_LIMIT 10000000
  if (mpz_cmp_ui (tmp, SIEVE_LIMIT) < 0)
    {
      sieve_lim = mpz_get_ui (tmp);
    }
  else
    {
      sieve_lim = SIEVE_LIMIT;
      mpz_sub (tmp, to2, fr2);
      if (mpz_cmp_ui (tmp, sieve_lim) < 0)
	sieve_lim = mpz_get_ui (tmp);	/* limit sieving for small ranges */
    }
  mpz_set_ui (siev_sqr_lim, sieve_lim + 1);
  mpz_mul_ui (siev_sqr_lim, siev_sqr_lim, sieve_lim + 1);

  est_n_primes = (size_t) (sieve_lim / log((double) sieve_lim) * 1.13) + 10;
  primes = malloc (est_n_primes * sizeof primes[0]);
  make_primelist (sieve_lim);
  assert (est_n_primes >= n_primes);

#if DEBUG
  printf ("sieve_lim = %lu\n", sieve_lim);
  printf ("n_primes = %lu (3..%u)\n",
	  n_primes, primes[n_primes - 1].prime);
#endif

#define S (1 << 15)		/* FIXME: Figure out L1 cache size */
  s = malloc (S/2);
  while (mpz_cmp (fr2, to2) <= 0)
    {
      unsigned long rsize;
      rsize = S;
      mpz_add_ui (tmp, fr2, rsize);
      if (mpz_cmp (tmp, to2) > 0)
	{
	  mpz_sub (tmp, to2, fr2);
	  rsize = mpz_get_ui (tmp) + 2;
	}
#if DEBUG
      printf ("Sieving region ["); mpz_out_str (stdout, 10, fr2);
      printf (","); mpz_add_ui (tmp, fr2, rsize - 2);
      mpz_out_str (stdout, 10, tmp); printf ("]\n");
#endif
      sieve_region (s, fr2, rsize);
      find_primes (s, fr2, rsize / 2, siev_sqr_lim);

      mpz_add_ui (fr2, fr2, S);
    }
  free (s);

  if (flag_count)
    printf ("Pi(interval) = %lu\n", total_primes);

  if (flag_maxgap)
    printf ("max gap: %lu\n", maxgap);

  return 0;
}
Exemple #11
0
int rsa_generate_key(rsa_private_key_t *key, int key_size)
{
  mpz_t e, p, q, n, t1, t2, phi, d, u;

  /* bit_size must be even */
  if (key_size & 0x01) key_size++;
  /* we use e = 65537 */
  mpz_init_set_ui(e, 65537);
  mpz_init2(p, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(q, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(n, key_size + GMP_NUMB_BITS);
  mpz_init2(t1, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(t2, key_size / 2 + GMP_NUMB_BITS);
  mpz_init2(phi, key_size + GMP_NUMB_BITS);
  mpz_init2(d, key_size + GMP_NUMB_BITS);
  mpz_init2(u, key_size / 2 + GMP_NUMB_BITS);
  do {  
    /* get prime p */
    mpz_urandomb(p, NULL, key_size / 2);
    mpz_setbit(p, 0); 
    mpz_setbit(p, key_size / 2 - 1);
    mpz_setbit(p, key_size / 2 - 2);
    mpz_nextprime(p, p);
    mpz_sub_ui(t1, p, 1);
    mpz_gcd(phi, e, t1);
    if (mpz_cmp_ui(phi, 1) != 0) continue;
    /* get prime q */
    mpz_urandomb(q, NULL, key_size / 2);
    mpz_setbit(q, 0);
    mpz_setbit(q, key_size / 2 - 1);
    mpz_setbit(q, key_size / 2 - 2);
    mpz_nextprime(q, q);
    mpz_sub_ui(t2, q, 1); 
    mpz_gcd(phi, e, t1);
    if (mpz_cmp_ui(phi, 1) != 0) continue;
    /* p shall be smaller than q */
    if (mpz_cmp(p, q) > 0) mpz_swap(p, q);
    /* calculate the modulus */
    mpz_mul(n, p, q);
  } while (mpz_sizeinbase(n, 2) != key_size);
  /* calculate Euler totient: phi = (p-1)(q-1) */
  mpz_mul(phi, t1, t2);
  /* calculate the secret key d = e^(-1) mod phi */
  mpz_invert(d, e, phi);
  /* calculate the inverse of p and q (used for chinese remainder theorem) */
  mpz_invert(u, p, q);
  /* setup private key */
  mpz_init_set(key->n, n);
  mpz_init_set(key->e, e);
  mpz_init_set(key->p, p);
  mpz_init_set(key->q, q);
  mpz_init_set(key->d, d);
  mpz_init_set(key->u, u);  
  key->size = key_size;
  /* release helper variables */
  mpz_clear(e);
  mpz_clear(p);
  mpz_clear(q);
  mpz_clear(n);
  mpz_clear(t1);
  mpz_clear(t2);
  mpz_clear(phi);
  mpz_clear(d);
  mpz_clear(u);
  /* test key */
  if (rsa_test_key(key) != 0) {
    rsa_release_private_key(key);
    return -1;
  }
  return 0;
}
Exemple #12
0
/*-------------------------------------------------------------------*/
static uint32 get_final_sqrt(msieve_obj *obj, gmp_poly_t *alg_poly,
			gmp_poly_t *prod, gmp_poly_t *isqrt_mod_q, 
			mpz_t q) {

	/* the main q-adic Newton iteration. On input, isqrt_mod_q
	   contains the starting value of the reciprocal square
	   root R[0](x) of the polynomial prod(x). The iteration is

	   R[k](x) = R[k-1](x) * (3 - prod(x)*R[k-1](x)^2) / 2 mod (q^(2^k))

	   and at the end of iteration k, prod(x)*R[k-1](x)^2 mod (q^(2^k))
	   is 1. We keep iterating until q^(2^k) is larger than the
	   size of the coefficients of the square root (i.e. about half
	   the size of the coefficients of prod(x)). Then the square
	   root to use is R[k](x) * prod(x) mod (q^(2^k)), which is
	   written to isqrt_mod_q */

	uint32 i, j;
	uint32 prod_bits, prod_max_bits;
	uint32 num_iter;

	/* initialize */

	gmp_poly_bits(prod, &prod_bits, &prod_max_bits);

	/* since prod(x) only matters mod q^(2^(final_k)), we can
	   cut the memory use in half by changing prod(x) to this.
	   Remember final_k as well */

	i = mpz_get_ui(q);
	for (num_iter = 0; mpz_sizeinbase(q, 2) < 
				prod_max_bits / 2 + 4000; num_iter++) {
		mpz_mul(q, q, q);
	}

	gmp_poly_mod_q(prod, q, prod);
	mpz_set_ui(q, (unsigned long)i);
	mpz_realloc2(q, 33);

	/* do the main iteration */

	for (i = 0; i < num_iter; i++) {

		gmp_poly_t tmp_poly;

		/* square the previous modulus */

		mpz_mul(q, q, q);

		/* compute prod(x) * (previous R)^2 */

		gmp_poly_init(&tmp_poly);
		gmp_poly_mod_q(prod, q, &tmp_poly);
		gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 0);
		gmp_poly_mod_q(&tmp_poly, q, &tmp_poly);
		gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 0);
		gmp_poly_mod_q(&tmp_poly, q, &tmp_poly);

		/* compute ( (3 - that) / 2 ) mod q */

		mpz_sub_ui(tmp_poly.coeff[0], tmp_poly.coeff[0], 
				(unsigned long)3);

		for (j = 0; j <= tmp_poly.degree; j++) {

			mpz_t *c = tmp_poly.coeff + j;

			if (mpz_sgn(*c) != 0) {
				mpz_neg(*c, *c);
				if (mpz_tstbit(*c, (unsigned long)0))
					mpz_add(*c, *c, q);
				mpz_tdiv_q_2exp(*c, *c, (unsigned long)1);
			}
		}

		/* finally, compute the new R(x) by multiplying the
		   result above by the old R(x) */

		gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 1);
		gmp_poly_mod_q(&tmp_poly, q, isqrt_mod_q);
		gmp_poly_clear(&tmp_poly);
	}

	/* attempt to compute the square root. 
	   First multiply R(x) by prod(x), deleting prod(x) 
	   since we won't need it beyond this point */

	gmp_poly_mul(isqrt_mod_q, prod, alg_poly, 1);
	gmp_poly_mod_q(isqrt_mod_q, q, isqrt_mod_q);

	/* this is a little tricky. Up until now we've
	   been working modulo big numbers, but the coef-
	   ficients of the square root are just integers,
	   and may be negative. Negative numbers mod q
	   have a numerical value near that of +q, but we
	   want the square root to have a negative coef-
	   ficient in that case. Hence, if the top
	   few words of any coefficent of the square root
	   match the top few words of q, we assume this
	   coefficient is negative and subtract q from it.

	   Theoretically we could be wrong, and the 
	   coefficient really is supposed to be a big 
	   positive number near q in size. However, if
	   q is thousands of bits larger than the size we
	   expect for the square root coefficients, this
	   is so unlikely that it's not worth worrying about */

	for (i = 0; i <= isqrt_mod_q->degree; i++) {
		mpz_t *c = isqrt_mod_q->coeff + i;
		size_t limbs = mpz_size(*c);

		if (limbs == mpz_size(q) &&
		    mpz_getlimbn(*c, (mp_size_t)(limbs-1)) ==
			mpz_getlimbn(q, (mp_size_t)(limbs-1)) &&
		    mpz_getlimbn(*c, (mp_size_t)(limbs-2)) ==
			mpz_getlimbn(q, (mp_size_t)(limbs-2)) &&
		    mpz_getlimbn(*c, (mp_size_t)(limbs-3)) ==
			mpz_getlimbn(q, (mp_size_t)(limbs-3))) { 
			mpz_sub(*c, *c, q);
		}
	}

	/* another heuristic: we will assume the Newton
	   iteration has converged if, after applying the
	   correction above for negative square root
	   coefficients, the total number of bits in the 
	   coefficients of the resulting polynomial is
	   much smaller than we would expect from random
	   polynomials modulo q */

	gmp_poly_bits(isqrt_mod_q, &prod_bits, &i);
	if (prod_bits >= (isqrt_mod_q->degree + 1) * 
				mpz_sizeinbase(q, 2) - 100) {
		logprintf(obj, "Newton iteration failed to converge\n");
		return 0;
	}
	return 1;
}
Exemple #13
0
unsigned long tiny_evaluate_candidate(linalg_t * la_inf, QS_t * qs_inf, poly_t * poly_inf, 
                          unsigned long i, unsigned char * sieve)
{
   unsigned long bits, exp, extra_bits, modp, prime;
   unsigned long num_primes = qs_inf->num_primes;
   prime_t * factor_base = qs_inf->factor_base;
   unsigned long * soln1 = poly_inf->soln1;
   unsigned long * soln2 = poly_inf->soln2;
   unsigned long * small = la_inf->small;
   fac_t * factor = la_inf->factor;
   unsigned long A = poly_inf->A;
   unsigned long B = poly_inf->B;
   unsigned long num_factors = 0;
   unsigned long j;
   mpz_t * C = &poly_inf->C;
   unsigned long relations = 0;
   double pinv;
   
   mpz_t X, Y, res, p;
   mpz_init(X); 
   mpz_init(Y); 
   mpz_init(res); 
   mpz_init(p); 
    
#if POLYS
   printf("X = %ld\n", i);
   printf("%ldX^2+2*%ldX+%ld\n", A, B, C);
#endif

   mpz_set_ui(X, i);
   mpz_sub_ui(X, X, SIEVE_SIZE/2); //X
              
   mpz_mul_ui(Y, X, A);
   if ((long) B < 0) 
   {
      mpz_sub_ui(Y, Y, -B);  // Y = AX+B
      mpz_sub_ui(res, Y, -B);  
   }
   else 
   {
      mpz_add_ui(Y, Y, B);
      mpz_add_ui(res, Y, B);
   }
   mpz_mul(res, res, X);  
   mpz_add(res, res, *C); // res = AX^2+2BX+C
           
   bits = mpz_sizeinbase(res, 2);
   bits -= 10; 
   extra_bits = 0;
   
   mpz_set_ui(p, 2); // divide out by powers of 2
   exp = mpz_remove(res, res, p);

#if RELATIONS
   if (exp) printf("2^%ld ", exp);
#endif
   extra_bits += exp;
   small[1] = exp;
     
   if (factor_base[0].p != 1) // divide out powers of the multiplier
   {
      mpz_set_ui(p, factor_base[0].p);
      exp = mpz_remove(res, res, p);
      if (exp) extra_bits += exp*qs_inf->sizes[0];
      small[0] = exp;
#if RELATIONS
      if (exp) printf("%ld^%ld ", factor_base[0].p, exp); 
#endif
   } else small[0] = 0;
   
   
   for (j = 2; j < SMALL_PRIMES; j++) // pull out small primes
   {
      prime = factor_base[j].p;
      pinv = factor_base[j].pinv;
      modp = z_mod_64_precomp(i, prime, pinv);
      if ((modp == soln1[j]) || (modp == soln2[j]))
      {
         mpz_set_ui(p, prime);
         exp = mpz_remove(res, res, p);
         if (exp) extra_bits += qs_inf->sizes[j];
         small[j] = exp;
#if RELATIONS
         if (exp) gmp_printf("%Zd^%ld ", p, exp); 
#endif
      } else small[j] = 0;
   }
   
   if (extra_bits + sieve[i] > bits)
   {
      sieve[i] += extra_bits;
      for (j = SMALL_PRIMES; (j < num_primes) && (extra_bits < sieve[i]); j++) // pull out remaining primes
      {
         prime = factor_base[j].p;
         pinv = factor_base[j].pinv;
         modp = z_mod_64_precomp(i, prime, pinv);
         if (soln2[j] != -1L)
         {
            if ((modp == soln1[j]) || (modp == soln2[j]))
            {
               mpz_set_ui(p, prime);
               exp = mpz_remove(res, res, p);
#if RELATIONS
               if (exp) gmp_printf("%Zd^%ld ", p, exp);
#endif
               if (exp) 
               {
                  extra_bits += qs_inf->sizes[j];
                  factor[num_factors].ind = j;
                  factor[num_factors++].exp = exp; 
               }
            }
         } else
         {
            mpz_set_ui(p, prime);
            exp = mpz_remove(res, res, p);
            factor[num_factors].ind = j;
            factor[num_factors++].exp = exp+1; 
#if RELATIONS
            if (exp) gmp_printf("%Zd^%ld ", p, exp);
#endif
         }    
      }
      if (mpz_cmpabs_ui(res, 1) == 0) // We've found a relation
      {
         unsigned long * A_ind = poly_inf->A_ind;
         unsigned long i;
         for (i = 0; i < poly_inf->s; i++) // Commit any outstanding A factors
         {
            if (A_ind[i] >= j)
            {
               factor[num_factors].ind = A_ind[i];
               factor[num_factors++].exp = 1; 
            }
         }
         la_inf->num_factors = num_factors;
         relations += tiny_insert_relation(la_inf, poly_inf, Y);  // Insert the relation in the matrix
         if (la_inf->num_relations >= 2*(qs_inf->num_primes + EXTRA_RELS + 100))
         {
            printf("Error: too many duplicate relations!\n");
            abort();
         }
         goto cleanup;
      }
   }
#if RELATIONS
   printf("\n");
#endif
  
cleanup:
   mpz_clear(X);
   mpz_clear(Y);
   mpz_clear(res);
   mpz_clear(p);
      
   return relations;
}
Exemple #14
0
int
main (void)
{
  mpz_t       z;
  int         got;
  const char  *expr;
  int         error = 0;

  tests_start ();
  mpz_init (z);

  mpz_set_ui (z, 0L);
  expr = "0";
  EXPECT (mpz_fits_ulong_p, 1);
  EXPECT (mpz_fits_uint_p, 1);
  EXPECT (mpz_fits_ushort_p, 1);
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);
  EXPECT (mpz_fits_sshort_p, 1);

  mpz_set_ui (z, 1L);
  expr = "1";
  EXPECT (mpz_fits_ulong_p, 1);
  EXPECT (mpz_fits_uint_p, 1);
  EXPECT (mpz_fits_ushort_p, 1);
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);
  EXPECT (mpz_fits_sshort_p, 1);

  mpz_set_si (z, -1L);
  expr = "-1";
  EXPECT (mpz_fits_ulong_p, 0);
  EXPECT (mpz_fits_uint_p, 0);
  EXPECT (mpz_fits_ushort_p, 0);
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);
  EXPECT (mpz_fits_sshort_p, 1);

  mpz_set_ui (z, 1L);
  mpz_mul_2exp (z, z, 5L*GMP_LIMB_BITS);
  expr = "2^(5*BPML)";
  EXPECT (mpz_fits_ulong_p, 0);
  EXPECT (mpz_fits_uint_p, 0);
  EXPECT (mpz_fits_ushort_p, 0);
  EXPECT (mpz_fits_slong_p, 0);
  EXPECT (mpz_fits_sint_p, 0);
  EXPECT (mpz_fits_sshort_p, 0);


  mpz_set_ui (z, (unsigned long) USHRT_MAX);
  expr = "USHRT_MAX";
  EXPECT (mpz_fits_ulong_p, 1);
  EXPECT (mpz_fits_uint_p, 1);
  EXPECT (mpz_fits_ushort_p, 1);

  mpz_set_ui (z, (unsigned long) USHRT_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "USHRT_MAX + 1";
  EXPECT (mpz_fits_ushort_p, 0);


  mpz_set_ui (z, (unsigned long) UINT_MAX);
  expr = "UINT_MAX";
  EXPECT (mpz_fits_ulong_p, 1);
  EXPECT (mpz_fits_uint_p, 1);

  mpz_set_ui (z, (unsigned long) UINT_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "UINT_MAX + 1";
  EXPECT (mpz_fits_uint_p, 0);


  mpz_set_ui (z, ULONG_MAX);
  expr = "ULONG_MAX";
  EXPECT (mpz_fits_ulong_p, 1);

  mpz_set_ui (z, ULONG_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "ULONG_MAX + 1";
  EXPECT (mpz_fits_ulong_p, 0);


  mpz_set_si (z, (long) SHRT_MAX);
  expr = "SHRT_MAX";
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);
  EXPECT (mpz_fits_sshort_p, 1);

  mpz_set_si (z, (long) SHRT_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "SHRT_MAX + 1";
  EXPECT (mpz_fits_sshort_p, 0);


  mpz_set_si (z, (long) INT_MAX);
  expr = "INT_MAX";
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);

  mpz_set_si (z, (long) INT_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "INT_MAX + 1";
  EXPECT (mpz_fits_sint_p, 0);


  mpz_set_si (z, LONG_MAX);
  expr = "LONG_MAX";
  EXPECT (mpz_fits_slong_p, 1);

  mpz_set_si (z, LONG_MAX);
  mpz_add_ui (z, z, 1L);
  expr = "LONG_MAX + 1";
  EXPECT (mpz_fits_slong_p, 0);


  mpz_set_si (z, (long) SHRT_MIN);
  expr = "SHRT_MIN";
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);
  EXPECT (mpz_fits_sshort_p, 1);

  mpz_set_si (z, (long) SHRT_MIN);
  mpz_sub_ui (z, z, 1L);
  expr = "SHRT_MIN + 1";
  EXPECT (mpz_fits_sshort_p, 0);


  mpz_set_si (z, (long) INT_MIN);
  expr = "INT_MIN";
  EXPECT (mpz_fits_slong_p, 1);
  EXPECT (mpz_fits_sint_p, 1);

  mpz_set_si (z, (long) INT_MIN);
  mpz_sub_ui (z, z, 1L);
  expr = "INT_MIN + 1";
  EXPECT (mpz_fits_sint_p, 0);


  mpz_set_si (z, LONG_MIN);
  expr = "LONG_MIN";
  EXPECT (mpz_fits_slong_p, 1);

  mpz_set_si (z, LONG_MIN);
  mpz_sub_ui (z, z, 1L);
  expr = "LONG_MIN + 1";
  EXPECT (mpz_fits_slong_p, 0);


  if (error)
    abort ();

  mpz_clear (z);
  tests_end ();
  exit (0);
}
int
main (int argc, char **argv)
{
    mpz_t op1, op2, r1, r2;
    mp_size_t op1n, op2n;
    unsigned long int op2long;
    int i;
    int reps = 100000;
    gmp_randstate_ptr rands;
    mpz_t bs;
    unsigned long bsi, size_range;

    tests_start ();
    rands = RANDS;

    mpz_init (bs);

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

    mpz_init (op1);
    mpz_init (op2);
    mpz_init (r1);
    mpz_init (r2);

    for (i = 0; i < reps; i++)
    {
        mpz_urandomb (bs, rands, 32);
        size_range = mpz_get_ui (bs) % 10 + 2;

        mpz_urandomb (bs, rands, size_range);
        op1n = mpz_get_ui (bs);
        mpz_rrandomb (op1, rands, op1n);

        mpz_urandomb (bs, rands, size_range);
        op2n = mpz_get_ui (bs);
        mpz_rrandomb (op2, rands, op2n);

        mpz_urandomb (bs, rands, 2);
        bsi = mpz_get_ui (bs);
        if ((bsi & 1) != 0)
            mpz_neg (op1, op1);
        if ((bsi & 2) != 0)
            mpz_neg (op2, op2);

        /* printf ("%ld %ld\n", SIZ (multiplier), SIZ (multiplicand)); */

        mpz_add (r1, op1, op2);
        mpz_sub (r2, r1, op2);
        if (mpz_cmp (r2, op1) != 0)
            dump_abort (i, "mpz_add or mpz_sub incorrect", op1, op2);

        if (mpz_fits_ulong_p (op2))
        {
            op2long = mpz_get_ui (op2);
            mpz_add_ui (r1, op1, op2long);
            mpz_sub_ui (r2, r1, op2long);
            if (mpz_cmp (r2, op1) != 0)
                dump_abort (i, "mpz_add_ui or mpz_sub_ui incorrect", op1, op2);

            mpz_ui_sub (r1, op2long, op1);
            mpz_sub_ui (r2, op1, op2long);
            mpz_neg (r2, r2);
            if (mpz_cmp (r1, r2) != 0)
                dump_abort (i, "mpz_add_ui or mpz_ui_sub incorrect", op1, op2);
        }
    }

    mpz_clear (bs);
    mpz_clear (op1);
    mpz_clear (op2);
    mpz_clear (r1);
    mpz_clear (r2);

    tests_end ();
    exit (0);
}
static int
rsa_provable_prime (mpz_t p,
			  unsigned *prime_seed_length, void *prime_seed,
			  unsigned bits,
			  unsigned seed_length, const void *seed,
			  mpz_t e,
			  void *progress_ctx, nettle_progress_func * progress)
{
mpz_t x, t, s, r1, r2, p0, sq;
int ret;
unsigned pcounter = 0;
unsigned iterations;
unsigned storage_length = 0, i;
uint8_t *storage = NULL;
uint8_t pseed[MAX_PVP_SEED_SIZE+1];
unsigned pseed_length = sizeof(pseed), tseed_length;
unsigned max = bits*5;

	mpz_init(p0);
	mpz_init(sq);
	mpz_init(x);
	mpz_init(t);
	mpz_init(s);
	mpz_init(r1);
	mpz_init(r2);

	/* p1 = p2 = 1 */

	ret = st_provable_prime(p0, &pseed_length, pseed,
				NULL, 1+div_ceil(bits,2), seed_length,
				seed, progress_ctx, progress);
	if (ret == 0) {
		goto cleanup;
	}

	iterations = div_ceil(bits, DIGEST_SIZE*8);
	mpz_set_ui(x, 0);

	if (iterations > 0) {
		storage_length = iterations * DIGEST_SIZE;
		storage = malloc(storage_length);
		if (storage == NULL) {
			goto fail;
		}

		nettle_mpz_set_str_256_u(s, pseed_length, pseed);
		for (i = 0; i < iterations; i++) {
			tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
			if (tseed_length > sizeof(pseed))
				goto fail;
			nettle_mpz_get_str_256(tseed_length, pseed, s);

			hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
			     tseed_length, pseed);
			mpz_add_ui(s, s, 1);
		}

		nettle_mpz_set_str_256_u(x, storage_length, storage);
	}

	/* x = sqrt(2)*2^(bits-1) + (x mod 2^(bits) - sqrt(2)*2(bits-1)) */

	/* sq = sqrt(2)*2^(bits-1) */
	mpz_set_ui(r1, 1);
	mpz_mul_2exp(r1, r1, 2*bits-1);
	mpz_sqrt(sq, r1);

	/* r2 = 2^bits - sq */
	mpz_set_ui(r2, 1);
	mpz_mul_2exp(r2, r2, bits);
	mpz_sub(r2, r2, sq);

	/* x =  sqrt(2)*2^(bits-1) + (x mod (2^L - sqrt(2)*2^(bits-1)) */
	mpz_mod(x, x, r2);
	mpz_add(x, x, sq);

	/* y = p2 = p1 = 1 */

	/* r1 = (2 y p0 p1) */
	mpz_mul_2exp(r1, p0, 1);

	/* r2 = 2 p0 p1 p2 (p2=y=1) */
	mpz_set(r2, r1);

	/* r1 = (2 y p0 p1) + x */
	mpz_add(r1, r1, x);

	/* t = ((2 y p0 p1) + x) / (2 p0 p1 p2) */
	mpz_cdiv_q(t, r1, r2);

 retry:
	/* p = t p2 - y = t - 1 */
	mpz_sub_ui(p, t, 1);

	/* p = 2(tp2-y)p0p1 */
	mpz_mul(p, p, p0);
	mpz_mul_2exp(p, p, 1);

	/* p = 2(tp2-y)p0p1 + 1*/
	mpz_add_ui(p, p, 1);

	mpz_set_ui(r2, 1);
	mpz_mul_2exp(r2, r2, bits);

	if (mpz_cmp(p, r2) > 0) {
		/* t = (2 y p0 p1) + sqrt(2)*2^(bits-1) / (2p0p1p2) */
		mpz_set(r1, p0);
		/* r1 = (2 y p0 p1) */
		mpz_mul_2exp(r1, r1, 1);

		/* sq =  sqrt(2)*2^(bits-1) */

		/* r1 = (2 y p0 p1) + sq */
		mpz_add(r1, r1, sq);

		/* r2 = 2 p0 p1 p2 */
		mpz_mul_2exp(r2, p0, 1);

		/* t = ((2 y p0 p1) + sq) / (2 p0 p1 p2) */
		mpz_cdiv_q(t, r1, r2);
	}

	pcounter++;

	/* r2 = p - 1 */
	mpz_sub_ui(r2, p, 1);

	/* r1 = GCD(p1, e) */
	mpz_gcd(r1, e, r2);

	if (mpz_cmp_ui(r1, 1) == 0) {
		mpz_set_ui(x, 0); /* a = 0 */
		if (iterations > 0) {
			for (i = 0; i < iterations; i++) {
				tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
				if (tseed_length > sizeof(pseed))
					goto fail;
				nettle_mpz_get_str_256(tseed_length, pseed, s);

				hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
				     tseed_length, pseed);
				mpz_add_ui(s, s, 1);
			}

			nettle_mpz_set_str_256_u(x, storage_length, storage);
		}

		/* a = 2 + a mod p-3 */
		mpz_sub_ui(r1, p, 3);	/* p is too large to worry about negatives */
		mpz_mod(x, x, r1);
		mpz_add_ui(x, x, 2);

		/* z = a^(2(tp2-y)p1) mod p */

		/* r1 = (tp2-y) */
		mpz_sub_ui(r1, t, 1);
		/* r1 = 2(tp2-y)p1 */
		mpz_mul_2exp(r1, r1, 1);

		/* z = r2 = a^r1 mod p */
		mpz_powm(r2, x, r1, p);

		mpz_sub_ui(r1, r2, 1);
		mpz_gcd(x, r1, p);

		if (mpz_cmp_ui(x, 1) == 0) {
			mpz_powm(r1, r2, p0, p);
			if (mpz_cmp_ui(r1, 1) == 0) {
				if (prime_seed_length != NULL) {
					tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
					if (tseed_length > sizeof(pseed))
						goto fail;

					nettle_mpz_get_str_256(tseed_length, pseed, s);

					if (*prime_seed_length < tseed_length) {
						*prime_seed_length = tseed_length;
						goto fail;
					}
					*prime_seed_length = tseed_length;
					if (prime_seed != NULL)
						memcpy(prime_seed, pseed, tseed_length);
				}
				ret = 1;
				goto cleanup;
			}
		}
	}

	if (pcounter >= max) {
		goto fail;
	}

	mpz_add_ui(t, t, 1);
	goto retry;

fail:
	ret = 0;
cleanup:
	free(storage);
	mpz_clear(p0);
	mpz_clear(sq);
	mpz_clear(r1);
	mpz_clear(r2);
	mpz_clear(x);
	mpz_clear(t);
	mpz_clear(s);

	return ret;
}
int main(long argc, char *argv[])
{
  if(argc != 4)
  {
      printf("three arguments required\n");
      exit(1);
  }
  mpz_t n, buffer1, buffer2;
  mpz_init(n); mpz_init(buffer1); mpz_init(buffer2);
  mpz_ui_pow_ui(n, atol(argv[2]), atol(argv[3]));
  mpz_mul_ui(n, n, atol(argv[1]));

  uint64_t crn = lpow(n, 1, 3);
  uint64_t srn = lpow(n, 1, 2);
  uint64_t ttrn = lpow(n, 2, 3);
  uint64_t start_block = 1;
  uint64_t finish_block = ttrn/crn;

  size_t psize = (size_t)(((1.26*crn)/log(crn) + 1) * sizeof(uint64_t));
  uint64_t* primes = (uint64_t*)malloc(psize);
  assert(primes!=NULL);
  uint64_t pi_crn = sieve(crn, primes);

  int8_t* mu = malloc(sizeof(int8_t) * (crn+1));                            //mu will run from 1 to crn with s[0] not used
  assert(mu != NULL);
  memset(mu, 1, sizeof(int8_t) * (crn+1));

  uint64_t* lpf = malloc(sizeof(uint64_t) * (crn+1));                        //lpf will run from 1 to crn with s[0] not used
  assert(lpf != NULL);
  memset(lpf, 0, sizeof(uint64_t) * (crn+1));

  uint64_t i, j;

  for(i=1; i<=pi_crn; i++)
    for(j=primes[i]; j<=crn; j+=primes[i])
      {
	mu[j] = -mu[j];
	if(lpf[j] == 0) lpf[j] = primes[i];
      }
  for(i=1; i<=pi_crn; i++)
    for(j=sqr(primes[i]); j<=crn; j+=sqr(primes[i])) mu[j]=0;               //remove numbers that are not squarefree

  uint64_t blocksize = crn;
  uint64_t num_blocks = ttrn/blocksize;
  assert(start_block <= finish_block);
  assert(finish_block <= num_blocks);

  mpz_t S2_result;
  mpz_init(S2_result);

  uint64_t* s = malloc((crn/64+2)*sizeof(uint64_t));
  assert(s != NULL);

  uint64_t* phi = malloc((pi_crn+1)*sizeof(uint64_t));
  memset(phi, 0, (pi_crn+1)*sizeof(uint64_t));

  int64_t* cum_mu = malloc((pi_crn+1)*sizeof(int64_t));
  memset(cum_mu, 0, (pi_crn+1)*sizeof(int64_t));

  uint64_t p, f, m, k, start, q, block_id, first_m, last_m, L, U, first_f;

  //Experimental mod 30 sieve
  uint64_t wheel_size = (crn  + PREV[crn % MOD])/MOD * GROUPS + POS[crn % MOD];
  uint64_t* s2 = malloc((wheel_size/64 + 2) * sizeof(uint64_t));

  for(block_id = start_block; block_id <= finish_block; block_id++)
    {
      memset(s, ~0, sizeof(uint64_t) * (crn/64+2));
      memset(s2, ~0, sizeof(uint64_t) * (wheel_size/64+2));
      L = (block_id -1)*blocksize + 1;
      U = L + blocksize;
      for(i=1; i<=pi_crn; i++)
	{
	  p = primes[i];
	  mpz_fdiv_q_ui(buffer1, n, L*p);
	  mpz_fdiv_q_ui(buffer2, n, U*p);
	  first_m = mpz_get_ui(buffer1);
	  last_m = mpz_get_ui(buffer2);
	  if(first_m > crn) first_m = crn;
	  if(last_m > first_m) last_m = first_m;
	  if(p > first_m) break;
	  start = L;
	  for(m = first_m; m > last_m && p*m > crn ; m--)
	    {
	      if(mu[m] != 0 && p < lpf[m] && p*m > crn && m <= crn)
		{
		  cum_mu[i] += -mu[m];
		  mpz_fdiv_q_ui(buffer1, n, p*m);
		  q = mpz_get_ui(buffer1);
		  assert(q>=L);
		  assert(q<=U);
		  phi[i] += sieve_count(s, i, start, q, L, U, s2);
		  start = q+1;
		  if(mu[m] > 0) mpz_sub_ui(S2_result, S2_result, mu[m] * phi[i]);
		  else mpz_add_ui(S2_result, S2_result, -mu[m] * phi[i]);
		}
	    }
	  phi[i] += sieve_count(s, i, start, U - 1, L, U, s2);
	  sieve_step(s, U,  L, p, s2);
	}
    }

  uint64_t short_block_length = ttrn % blocksize;

  if(short_block_length>0)
    {
      //short block
      L = L + blocksize;
      U = L + short_block_length; 

      memset(s, ~0, sizeof(uint64_t) * (crn/64+2));
      for(i=1; i<=pi_crn; i++)
	{
	  start = L;
	  p = primes[i];
	  mpz_fdiv_q_ui(buffer1, n, L*p);
	  mpz_fdiv_q_ui(buffer2, n, U*p);
	  first_m = mpz_get_ui(buffer1);
	  last_m = mpz_get_ui(buffer2);
	  if(first_m > crn) first_m = crn;
	  if(last_m > first_m) last_m = first_m;
	  if(p > first_m) break;
	  for(m=first_m; m>last_m && p*m>crn ; m--)
	  {
	      if(mu[m]!=0 && p<lpf[m] && p*m>crn && m<=crn)
	      {
		  mpz_fdiv_q_ui(buffer1, n, p*m);
		  q = mpz_get_ui(buffer1);
		  assert(q>=L);
		  assert(q<=U);
		  phi[i] += count_bits(s, start - L, q - L);
		  start = q+1;
		  if(mu[m] > 0) mpz_sub_ui(S2_result, S2_result, mu[m]*phi[i]);
		  else mpz_add_ui(S2_result, S2_result, -mu[m]*phi[i]);
	      }
	  }
	  sieve_step(s, U,  L, p, s2);
	}
    }

  mpz_out_str (stdout, 10, S2_result);
  printf("\n");
  mpz_clears(buffer1, buffer2, n, S2_result, NULL);
  free(s); free(phi);
  free(primes); free(mu);
  free(lpf); free(cum_mu);
  free(s2);
  return(0);
}
Exemple #18
0
// x in Z_r, g, h in some group of order r
// finds x such that g^x = h
void element_dlog_pollard_rho(element_t x, element_t g, element_t h) {
// see Blake, Seroussi and Smart
// only one snark for this implementation
  int i, s = 20;
  field_ptr Zr = x->field, G = g->field;
  element_t asum;
  element_t bsum;
  element_t *a = _alloca(s * sizeof(element_t));
  element_t *b = _alloca(s * sizeof(element_t));
  element_t *m = _alloca(s * sizeof(element_t));
  element_t g0, snark;
  darray_t hole;
  int interval = 5;
  mpz_t counter;
  int found = 0;

  mpz_init(counter);
  element_init(g0, G);
  element_init(snark, G);
  element_init(asum, Zr);
  element_init(bsum, Zr);
  darray_init(hole);
  //set up multipliers
  for (i = 0; i < s; i++) {
    element_init(a[i], Zr);
    element_init(b[i], Zr);
    element_init(m[i], G);
    element_random(a[i]);
    element_random(b[i]);
    element_pow_zn(g0, g, a[i]);
    element_pow_zn(m[i], h, b[i]);
    element_mul(m[i], m[i], g0);
  }

  element_random(asum);
  element_random(bsum);
  element_pow_zn(g0, g, asum);
  element_pow_zn(snark, h, bsum);
  element_mul(snark, snark, g0);

  record(asum, bsum, snark, hole, counter);
  for (;;) {
    int len = element_length_in_bytes(snark);
    unsigned char *buf = pbc_malloc(len);
    unsigned char hash = 0;

    element_to_bytes(buf, snark);
    for (i = 0; i < len; i++) {
      hash += buf[i];
    }
    i = hash % s;
    pbc_free(buf);

    element_mul(snark, snark, m[i]);
    element_add(asum, asum, a[i]);
    element_add(bsum, bsum, b[i]);

    for (i = 0; i < hole->count; i++) {
      snapshot_ptr ss = hole->item[i];
      if (!element_cmp(snark, ss->snark)) {
        element_sub(bsum, bsum, ss->b);
        element_sub(asum, ss->a, asum);
        //answer is x such that x * bsum = asum
        //complications arise if gcd(bsum, r) > 1
        //which can happen if r is not prime
        if (!mpz_probab_prime_p(Zr->order, 10)) {
          mpz_t za, zb, zd, zm;

          mpz_init(za);
          mpz_init(zb);
          mpz_init(zd);
          mpz_init(zm);

          element_to_mpz(za, asum);
          element_to_mpz(zb, bsum);
          mpz_gcd(zd, zb, Zr->order);
          mpz_divexact(zm, Zr->order, zd);
          mpz_divexact(zb, zb, zd);
          //if zd does not divide za there is no solution
          mpz_divexact(za, za, zd);
          mpz_invert(zb, zb, zm);
          mpz_mul(zb, za, zb);
          mpz_mod(zb, zb, zm);
          do {
            element_pow_mpz(g0, g, zb);
            if (!element_cmp(g0, h)) {
              element_set_mpz(x, zb);
              break;
            }
            mpz_add(zb, zb, zm);
            mpz_sub_ui(zd, zd, 1);
          } while (mpz_sgn(zd));
          mpz_clear(zm);
          mpz_clear(za);
          mpz_clear(zb);
          mpz_clear(zd);
        } else {
          element_div(x, asum, bsum);
        }
        found = 1;
        break;
      }
    }
    if (found) break;

    mpz_add_ui(counter, counter, 1);
    if (mpz_tstbit(counter, interval)) {
      record(asum, bsum, snark, hole, counter);
      interval++;
    }
  }

  for (i = 0; i < s; i++) {
    element_clear(a[i]);
    element_clear(b[i]);
    element_clear(m[i]);
  }
  element_clear(g0);
  element_clear(snark);
  for (i = 0; i < hole->count; i++) {
    snapshot_ptr ss = hole->item[i];
    element_clear(ss->a);
    element_clear(ss->b);
    element_clear(ss->snark);
    pbc_free(ss);
  }
  darray_clear(hole);
  element_clear(asum);
  element_clear(bsum);
  mpz_clear(counter);
}
Exemple #19
0
void rsa_private(MP_INT *output, MP_INT *input, RSAPrivateKey *prv)

{

  MP_INT dp, dq, p2, q2, k;



  /* Initialize temporary variables. */

  mpz_init(&dp);

  mpz_init(&dq);

  mpz_init(&p2);

  mpz_init(&q2);

  mpz_init(&k);



  /* Compute dp = d mod p-1. */

  mpz_sub_ui(&dp, &prv->p, 1);

  mpz_mod(&dp, &prv->d, &dp);



  /* Compute dq = d mod q-1. */

  mpz_sub_ui(&dq, &prv->q, 1);

  mpz_mod(&dq, &prv->d, &dq);



  /* Compute p2 = (input mod p) ^ dp mod p. */

  mpz_mod(&p2, input, &prv->p);

  mpz_powm(&p2, &p2, &dp, &prv->p);



  /* Compute q2 = (input mod q) ^ dq mod q. */

  mpz_mod(&q2, input, &prv->q);

  mpz_powm(&q2, &q2, &dq, &prv->q);



  /* Compute k = ((q2 - p2) mod q) * u mod q. */

  mpz_sub(&k, &q2, &p2);

  mpz_mul(&k, &k, &prv->u);

  mpz_mmod(&k, &k, &prv->q);



  /* Compute output = p2 + p * k. */

  mpz_mul(output, &prv->p, &k);

  mpz_add(output, output, &p2);



  /* Clear temporary variables. */

  mpz_clear(&dp);

  mpz_clear(&dq);

  mpz_clear(&p2);

  mpz_clear(&q2);

  mpz_clear(&k);

}
Exemple #20
0
int
_dsa_validate_dss_pq(struct dsa_params *pub,
		     struct dss_params_validation_seeds *cert)
{
	int ret;
	unsigned p_bits, q_bits;
	struct dsa_params pub2;
	struct dss_params_validation_seeds cert2;
	mpz_t r, s;

	p_bits = mpz_sizeinbase(pub->p, 2);
	q_bits = mpz_sizeinbase(pub->q, 2);

	ret = _dsa_check_qp_sizes(q_bits, p_bits, 0);
	if (ret == 0) {
		return 0;
	}

	mpz_init(r);
	mpz_init(s);
	dsa_params_init(&pub2);

	nettle_mpz_set_str_256_u(s, cert->seed_length, cert->seed);

	/* firstseed < 2^(N-1) */
	mpz_set_ui(r, 1);
	mpz_mul_2exp(r, r, q_bits - 1);

	if (mpz_cmp(s, r) < 0) {
		goto fail;
	}

	/* 2^N <= q */
	mpz_set_ui(r, 1);
	mpz_mul_2exp(r, r, q_bits);

	if (mpz_cmp(r, pub->q) <= 0) {
		goto fail;
	}

	/* 2^L <= p */
	mpz_set_ui(r, 1);
	mpz_mul_2exp(r, r, p_bits);

	if (mpz_cmp(r, pub->p) <= 0) {
		goto fail;
	}

	/* p-1 mod q != 0 */
	mpz_set(r, pub->p);
	mpz_sub_ui(r, r, 1);

	mpz_mod(r, r, pub->q);
	if (mpz_cmp_ui(r, 0) != 0) {
		goto fail;
	}

	/* replay the construction */
	ret = _dsa_generate_dss_pq(&pub2, &cert2, cert->seed_length, cert->seed,
				   NULL, NULL, p_bits, q_bits);
	if (ret == 0) {
		goto fail;
	}

	if ((cert->pseed_length > 0 && cert->pseed_length != cert2.pseed_length)
	    || (cert->qseed_length > 0
		&& cert->qseed_length != cert2.qseed_length)
	    || (cert->pgen_counter > 0
		&& cert->pgen_counter != cert2.pgen_counter)
	    || (cert->qgen_counter > 0
		&& cert->qgen_counter != cert2.qgen_counter)
	    || (cert->qseed_length > 0
		&& memcmp(cert->qseed, cert2.qseed, cert2.qseed_length) != 0)
	    || (cert->pseed_length > 0
		&& memcmp(cert->pseed, cert2.pseed, cert2.pseed_length) != 0)) {
		goto fail;
	}

	if (mpz_cmp(pub->q, pub2.q) != 0) {
		goto fail;
	}

	if (mpz_cmp(pub->p, pub2.p) != 0) {
		goto fail;
	}

	if (mpz_sizeinbase(s, 2) < q_bits - 1) {
		goto fail;
	}

	ret = 1;
	goto finish;

 fail:
	ret = 0;

 finish:
	dsa_params_clear(&pub2);
	mpz_clear(r);
	mpz_clear(s);

	return ret;
}
Exemple #21
0
static PyObject *
GMPY_mpz_is_euler_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t res, exp;
    int ret;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_euler_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(res);
    mpz_init(exp);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_euler_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_euler_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;
    }

    /* Check gcd(a,b) */
    mpz_gcd(res, n->z, a->z);
    if (mpz_cmp_ui(res, 1) > 0) {
        VALUE_ERROR("is_euler_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(exp, n->z);
    mpz_sub_ui(exp, exp, 1);
    mpz_divexact_ui(exp, exp, 2);
    mpz_powm(res, a->z, exp, n->z);

    /* reuse exp to calculate jacobi(a,n) mod n */
    ret = mpz_jacobi(a->z,n->z);
    mpz_set(exp, n->z);
    if (ret == -1)
        mpz_sub_ui(exp, exp, 1);
    else if (ret == 1)
        mpz_add_ui(exp, exp, 1);
    mpz_mod(exp, exp, n->z);

    if (mpz_cmp(res, exp) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(res);
    mpz_clear(exp);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Exemple #22
0
int
_dsa_validate_dss_g(struct dsa_params *pub,
		    unsigned domain_seed_size, const uint8_t *domain_seed, unsigned index)
{
	int ret;
	unsigned p_bits, q_bits;
	struct dsa_params pub2;
	mpz_t r;

	p_bits = mpz_sizeinbase(pub->p, 2);
	q_bits = mpz_sizeinbase(pub->q, 2);

	ret = _dsa_check_qp_sizes(q_bits, p_bits, 0);
	if (ret == 0) {
		return 0;
	}

	mpz_init(r);
	dsa_params_init(&pub2);

	mpz_set(pub2.p, pub->p);
	mpz_set(pub2.q, pub->q);

	/* verify g */
	if (index > 255) {
		goto fail;
	}

	/* 2<= g <= p-1 */
	mpz_set(r, pub->p);
	mpz_sub_ui(r, r, 1);
	if (mpz_cmp_ui(pub->g, 2) < 0 || mpz_cmp(pub->g, r) >= 0) {
		goto fail;
	}

	/* g^q == 1 mod p */
	mpz_powm(r, pub->g, pub->q, pub->p);
	if (mpz_cmp_ui(r, 1) != 0) {
		goto fail;
	}

	/* repeat g generation */
	ret = _dsa_generate_dss_g(&pub2,
				  domain_seed_size, domain_seed,
				  NULL, NULL, index);
	if (ret == 0) {
		goto fail;
	}

	if (mpz_cmp(pub->g, pub2.g) != 0) {
		goto fail;
	}

	/* everything looks ok */
	ret = 1;
	goto finish;

 fail:
	ret = 0;

 finish:
	dsa_params_clear(&pub2);
	mpz_clear(r);

	return ret;
}
Exemple #23
0
static PyObject *
GMPY_mpz_is_fermat_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t res, nm1;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_fermat_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(res);
    mpz_init(nm1);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_fermat_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_fermat_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. */
    /* Should n even raise an exception? */
    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;
    }

    /* Check gcd(a,n) */
    mpz_gcd(res, n->z, a->z);
    if (mpz_cmp_ui(res, 1) > 0) {
        VALUE_ERROR("is_fermat_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(nm1, n->z);
    mpz_sub_ui(nm1, nm1, 1);
    mpz_powm(res, a->z, nm1, n->z);

    if (mpz_cmp_ui(res, 1) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(res);
    mpz_clear(nm1);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Exemple #24
0
/* 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);
      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);
      { unsigned long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_ui (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;
    default:
      abort ();
    }
}
Exemple #25
0
static PyObject *
GMPY_mpz_is_extrastronglucas_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p;
    PyObject *result = 0;
    mpz_t zD, s, nmj, nm2, res;
    /* these are needed for the LucasU and LucasV part of this function */
    mpz_t uh, vl, vh, ql, qh, tmp;
    mp_bitcnt_t r = 0, j = 0;
    int ret = 0;

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

    mpz_init(zD);
    mpz_init(s);
    mpz_init(nmj);
    mpz_init(nm2);
    mpz_init(res);
    mpz_init(uh);
    mpz_init(vl);
    mpz_init(vh);
    mpz_init(ql);
    mpz_init(qh);
    mpz_init(tmp);

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!n || !p) {
        TYPE_ERROR("is_extra_strong_lucas_prp() requires 2 integer arguments");
        goto cleanup;
    }

    /* Check if p*p - 4 == 0. */
    mpz_mul(zD, p->z, p->z);
    mpz_sub_ui(zD, zD, 4);
    if (mpz_sgn(zD) == 0) {
        VALUE_ERROR("invalid value for p in is_extra_strong_lucas_prp()");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_extra_strong_lucas_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;
    }

    /* Check GCD */
    mpz_mul_ui(res, zD, 2);
    mpz_gcd(res, res, n->z);
    if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) {
        VALUE_ERROR("is_extra_strong_lucas_prp() requires gcd(n,2*D) == 1");
        goto cleanup;
    }

    /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */
    mpz_set(nmj, n->z);
    ret = mpz_jacobi(zD, n->z);
    if (ret == -1)
        mpz_add_ui(nmj, nmj, 1);
    else if (ret == 1)
        mpz_sub_ui(nmj, nmj, 1);

    r = mpz_scan1(nmj, 0);
    mpz_fdiv_q_2exp(s, nmj, r);

    mpz_set(nm2, n->z);
    mpz_sub_ui(nm2, nm2, 2);

    /* make sure that either U_s == 0 mod n or V_s == +/-2 mod n, or */
    /* V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1           */
    mpz_set_si(uh, 1);
    mpz_set_si(vl, 2);
    mpz_set(vh, p->z);
    mpz_set_si(ql, 1);
    mpz_set_si(qh, 1);
    mpz_set_si(tmp,0);

    for (j = mpz_sizeinbase(s,2)-1; j >= 1; j--) {
        /* ql = ql*qh (mod n) */
        mpz_mul(ql, ql, qh);
        mpz_mod(ql, ql, n->z);
        if (mpz_tstbit(s,j) == 1) {
            /* qh = ql*q */
            mpz_set(qh, ql);

            /* uh = uh*vh (mod n) */
            mpz_mul(uh, uh, vh);
            mpz_mod(uh, uh, n->z);

            /* vl = vh*vl - p*ql (mod n) */
            mpz_mul(vl, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);

            /* vh = vh*vh - 2*qh (mod n) */
            mpz_mul(vh, vh, vh);
            mpz_mul_si(tmp, qh, 2);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);
        }
        else {
            /* qh = ql */
            mpz_set(qh, ql);

            /* uh = uh*vl - ql (mod n) */
            mpz_mul(uh, uh, vl);
            mpz_sub(uh, uh, ql);
            mpz_mod(uh, uh, n->z);

            /* vh = vh*vl - p*ql (mod n) */
            mpz_mul(vh, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);

            /* vl = vl*vl - 2*ql (mod n) */
            mpz_mul(vl, vl, vl);
            mpz_mul_si(tmp, ql, 2);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);
        }
    }
    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    /* qh = ql*q */
    mpz_set(qh, ql);

    /* uh = uh*vl - ql */
    mpz_mul(uh, uh, vl);
    mpz_sub(uh, uh, ql);

    /* vl = vh*vl - p*ql */
    mpz_mul(vl, vh, vl);
    mpz_mul(tmp, ql, p->z);
    mpz_sub(vl, vl, tmp);

    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    mpz_mod(uh, uh, n->z);
    mpz_mod(vl, vl, n->z);

    /* uh contains LucasU_s and vl contains LucasV_s */
    if ((mpz_cmp_ui(uh, 0) == 0) || (mpz_cmp_ui(vl, 0) == 0) ||
        (mpz_cmp(vl, nm2) == 0) || (mpz_cmp_si(vl, 2) == 0)) {
        result = Py_True;
        goto cleanup;
    }

    for (j = 1; j < r-1; j++) {
        /* vl = vl*vl - 2*ql (mod n) */
        mpz_mul(vl, vl, vl);
        mpz_mul_si(tmp, ql, 2);
        mpz_sub(vl, vl, tmp);
        mpz_mod(vl, vl, n->z);

        /* ql = ql*ql (mod n) */
        mpz_mul(ql, ql, ql);
        mpz_mod(ql, ql, n->z);

        if (mpz_cmp_ui(vl, 0) == 0) {
            result = Py_True;
            goto cleanup;
        }
    }

    result = Py_False;
  cleanup:
    Py_XINCREF(result);
    mpz_clear(zD);
    mpz_clear(s);
    mpz_clear(nmj);
    mpz_clear(nm2);
    mpz_clear(res);
    mpz_clear(uh);
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    Py_XDECREF((PyObject*)p);
    Py_XDECREF((PyObject*)n);
    return result;
}
Exemple #26
0
void
generate_mod (int limb_bits, int nail_bits)
{
  int    numb_bits = limb_bits - nail_bits;
  int    i, divisor;

  mpz_init_set_ui (pp, 0L);
  mpz_init_set_ui (pp_norm, 0L);
  mpz_init_set_ui (pp_inverted, 0L);

  /* no more than limb_bits many factors in a one limb modulus (and of
     course in reality nothing like that many) */
  factor_alloc = limb_bits;
  factor = xmalloc (factor_alloc * sizeof (*factor));
  rawfactor = xmalloc (factor_alloc * sizeof (*rawfactor));

  if (numb_bits % 4 != 0)
    {
      strcpy (mod34_excuse, "GMP_NUMB_BITS % 4 != 0");
      goto use_pp;
    }

  max_divisor = 2*limb_bits;
  max_divisor_bits = log2_ceil (max_divisor);

  if (numb_bits / 4 < max_divisor_bits)
    {
      /* Wind back to one limb worth of max_divisor, if that will let us use
         mpn_mod_34lsub1.  */
      max_divisor = limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      if (numb_bits / 4 < max_divisor_bits)
        {
          strcpy (mod34_excuse, "GMP_NUMB_BITS / 4 too small");
          goto use_pp;
        }
    }

  {
    /* Can use mpn_mod_34lsub1, find small factors of 2^mod34_bits-1. */
    mpz_t  m, q, r;
    int    multiplicity;

    mod34_bits = (numb_bits / 4) * 3;

    /* mpn_mod_34lsub1 returns a full limb value, PERFSQR_MOD_34 folds it at
       the mod34_bits mark, adding the two halves for a remainder of at most
       mod34_bits+1 many bits */
    mod_bits = mod34_bits + 1;

    mpz_init_set_ui (m, 1L);
    mpz_mul_2exp (m, m, mod34_bits);
    mpz_sub_ui (m, m, 1L);

    mpz_init (q);
    mpz_init (r);

    for (i = 3; i <= max_divisor; i++)
      {
        if (! isprime (i))
          continue;

        mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
        if (mpz_sgn (r) != 0)
          continue;

        /* if a repeated prime is found it's used as an i^n in one factor */
        divisor = 1;
        multiplicity = 0;
        do
          {
            if (divisor > max_divisor / i)
              break;
            multiplicity++;
            mpz_set (m, q);
            mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
          }
        while (mpz_sgn (r) == 0);

        assert (nrawfactor < factor_alloc);
        rawfactor[nrawfactor].divisor = i;
        rawfactor[nrawfactor].multiplicity = multiplicity;
        nrawfactor++;
      }

    mpz_clear (m);
    mpz_clear (q);
    mpz_clear (r);
  }

  if (nrawfactor <= 2)
    {
      mpz_t  new_pp;

      sprintf (mod34_excuse, "only %d small factor%s",
               nrawfactor, nrawfactor == 1 ? "" : "s");

    use_pp:
      /* reset to two limbs of max_divisor, in case the mpn_mod_34lsub1 code
         tried with just one */
      max_divisor = 2*limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      mpz_init (new_pp);
      nrawfactor = 0;
      mod_bits = MIN (numb_bits, limb_bits - max_divisor_bits);

      /* one copy of each small prime */
      mpz_set_ui (pp, 1L);
      for (i = 3; i <= max_divisor; i++)
        {
          if (! isprime (i))
            continue;

          mpz_mul_ui (new_pp, pp, (unsigned long) i);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            break;
          mpz_set (pp, new_pp);

          assert (nrawfactor < factor_alloc);
          rawfactor[nrawfactor].divisor = i;
          rawfactor[nrawfactor].multiplicity = 1;
          nrawfactor++;
        }

      /* Plus an extra copy of one or more of the primes selected, if that
         still fits in max_divisor and the total in mod_bits.  Usually only
         3 or 5 will be candidates */
      for (i = nrawfactor-1; i >= 0; i--)
        {
          if (rawfactor[i].divisor > max_divisor / rawfactor[i].divisor)
            continue;
          mpz_mul_ui (new_pp, pp, (unsigned long) rawfactor[i].divisor);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            continue;
          mpz_set (pp, new_pp);

          rawfactor[i].multiplicity++;
        }

      mod_bits = mpz_sizeinbase (pp, 2);

      mpz_set (pp_norm, pp);
      while (mpz_sizeinbase (pp_norm, 2) < numb_bits)
        mpz_add (pp_norm, pp_norm, pp_norm);

      mpz_preinv_invert (pp_inverted, pp_norm, numb_bits);

      mpz_clear (new_pp);
    }

  /* start the factor array */
  for (i = 0; i < nrawfactor; i++)
    {
      int  j;
      assert (nfactor < factor_alloc);
      factor[nfactor].divisor = 1;
      for (j = 0; j < rawfactor[i].multiplicity; j++)
        factor[nfactor].divisor *= rawfactor[i].divisor;
      nfactor++;
    }

 combine:
  /* Combine entries in the factor array.  Combine the smallest entry with
     the biggest one that will fit with it (ie. under max_divisor), then
     repeat that with the new smallest entry. */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_divisor);
  for (i = nfactor-1; i >= 1; i--)
    {
      if (factor[i].divisor <= max_divisor / factor[0].divisor)
        {
          factor[0].divisor *= factor[i].divisor;
          COLLAPSE_ELEMENT (factor, i, nfactor);
          goto combine;
        }
    }

  total_fraction = 1.0;
  for (i = 0; i < nfactor; i++)
    {
      mpz_init (factor[i].inverse);
      mpz_invert_ui_2exp (factor[i].inverse,
                          (unsigned long) factor[i].divisor,
                          (unsigned long) mod_bits);

      mpz_init (factor[i].mask);
      square_mask (factor[i].mask, factor[i].divisor);

      /* fraction of possible squares */
      factor[i].fraction = (double) mpz_popcount (factor[i].mask)
        / factor[i].divisor;

      /* total fraction of possible squares */
      total_fraction *= factor[i].fraction;
    }

  /* best tests first (ie. smallest fraction) */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_fraction);
}
Exemple #27
0
void
table (int limb_bits, int nail_bits)
{
  int  numb_bits = limb_bits - nail_bits;
  int  base;
  mpz_t r, t, logb2, log2b;

  mpz_init (r);
  mpz_init (t);
  mpz_init (logb2);
  mpz_init (log2b);

  printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
  printf ("\n");
  printf ("#include \"gmp.h\"\n");
  printf ("#include \"gmp-impl.h\"\n");
  printf ("\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
  printf ("Error, error, this data is for %d bits\n", numb_bits);
  printf ("#endif\n");
  printf ("\n");
  puts ("const struct bases mp_bases[257] =\n{");
  puts ("  /*   0 */ { 0, 0, 0, 0, 0 },");
  puts ("  /*   1 */ { 0, 0, 0, 0, 0 },");
  for (base = 2; base <= 256; base++)
    {
      generate (limb_bits, nail_bits, base);
      mp_2logb (r, base, limb_bits + 8);
      mpz_tdiv_q_2exp (logb2, r, 8);
      mpz_set_ui (t, 1);
      mpz_mul_2exp (t, t, 2*limb_bits + 5);
      mpz_sub_ui (t, t, 1);
      mpz_add_ui (r, r, 1);
      mpz_tdiv_q (log2b, t, r);

      printf ("  /* %3u */ { ", base);
      if (POW2_P (base))
	{
          mpz_set_ui (big_base, ulog2 (base) - 1);
	  mpz_set_ui (big_base_inverted, 0);
	}

      printf ("%u,", chars_per_limb);
      printf (" CNST_LIMB(0x");
      mpz_out_str (stdout, 16, logb2);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, log2b);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, big_base);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, big_base_inverted);
      printf (") },\n");
    }

  puts ("};");

  mpz_clear (r);
  mpz_clear (t);
  mpz_clear (logb2);
  mpz_clear (log2b);

}
Exemple #28
0
bool bbp_pi(bool const & abortTask,
            std::string const & digitIndex,
            uint32_t const digitStep,
            std::string & piSequence)
{
    unsigned long const mantissa_bits = 132;
    unsigned long const count_offset = 7;
    // settings above gives 32 hexadecimal digits
    unsigned long count = static_cast<unsigned long>(
        floor(log10(pow(2.0, static_cast<double>(mantissa_bits)))));
    count -= count_offset;

    // starting digit
    mpz_t digit;
    mpz_init(digit);
    if (mpz_set_str(digit, digitIndex.c_str(), 10) < 0)
        return false;
    mpz_sub_ui(digit, digit, 1); // subtract the 3 digit
    mpz_add_ui(digit, digit, digitStep);
    
    mpz_t tmpI[TEMPORARY_INTEGERS];
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_init(tmpI[i]);
    mpf_t tmpF[TEMPORARY_FLOATS];
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_init2(tmpF[i], mantissa_bits);
    
    // determine epsilon based on the number of digits required
    mpf_t epsilon;
    mpf_init2(epsilon, mantissa_bits);
    mpf_set_ui(epsilon, 10);
    mpf_pow_ui(epsilon, epsilon, count + count_offset);
    mpf_ui_div(epsilon, 1, epsilon);

    // integer constant
    mpz_t sixteen;
    mpz_init(sixteen);
    mpz_set_ui(sixteen, 16);

    // determine the series
    mpf_t s1, s2, s3, s4;
    mpf_init2(s1, mantissa_bits);
    mpf_init2(s2, mantissa_bits);
    mpf_init2(s3, mantissa_bits);
    mpf_init2(s4, mantissa_bits);
    series(abortTask, s1, 1, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s2, 4, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s3, 5, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s4, 6, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;

    // pid = 4. * s1 - 2. * s2 - s3 - s4;
    mpf_mul_ui(s1, s1, 4);
    mpf_mul_ui(s2, s2, 2);
    mpf_t result;
    mpf_init2(result, mantissa_bits);
    mpf_sub(result, s1, s2);
    mpf_sub(result, result, s3);
    mpf_sub(result, result, s4);

    // pid = pid - (int) pid + 1.;
    mpf_t & tmp1 = tmpF[0];
    mpf_floor(tmp1, result);
    mpf_sub(result, result, tmp1);
    mpf_add_ui(result, result, 1);
    mpf_abs(result, result);

    // output the result
    char resultStr[256];
    mp_exp_t exponent;
    mpf_get_str(resultStr, &exponent, 16, 254, result);
    resultStr[count + 1] = '\0'; // cut off any erroneous bits
    piSequence.assign(&resultStr[1]);

    // cleanup
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_clear(tmpI[i]);
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_clear(tmpF[i]);
    mpz_clear(digit);
    mpf_clear(epsilon);
    mpz_clear(sixteen);
    mpf_clear(s1);
    mpf_clear(s2);
    mpf_clear(s3);
    mpf_clear(s4);
    mpf_clear(result);
    return true;
}
Exemple #29
0
static int generator_rule_TYPE(Generator *gen) {
        GeneratorState *next, *state = gen->tip;
        unsigned long val;
        int res;

        /*
         * TYPE ::= basic
         *          | 'v'
         *          | '(' ')'
         *          | 'm' TYPE
         *          | 'a' TYPE
         *          | '(' TUPLE ')'
         *          | '{' PAIR '}'
         */

        res = mpz_cmp_ui(state->seed, _GENERATOR_BASIC_N + 2);
        if (res < 0) {
                /*
                 * TYPE ::= basic | 'v' | '(' ')'
                 */
                val = mpz_get_ui(state->seed);
                switch (val) {
                case _GENERATOR_BASIC_N + 0:
                        /*
                         * TYPE ::= 'v'
                         */
                        generator_pop(gen);
                        return 'v';
                case _GENERATOR_BASIC_N + 1:
                        /*
                         * TYPE ::= '(' ')'
                         */
                        state->rule = GENERATOR_RULE_TUPLE_CLOSE;
                        return '(';
                default:
                        /*
                         * TYPE ::= basic
                         */
                        generator_pop(gen);
                        return generator_map_basic(val);
                }
        } else {
                /*
                 * TYPE ::= 'm' TYPE | 'a' TYPE | '(' TUPLE ')' | '{' PAIR '}'
                 */
                mpz_sub_ui(state->seed, state->seed, _GENERATOR_BASIC_N + 2);
                val = mpz_fdiv_q_ui(state->seed, state->seed, _GENERATOR_COMPOUND_N);
                switch (val) {
                case GENERATOR_COMPOUND_m:
                        /*
                         * TYPE ::= 'm' TYPE
                         */
                        state->rule = GENERATOR_RULE_TYPE;
                        return 'm';
                case GENERATOR_COMPOUND_a:
                        /*
                         * TYPE ::= 'a' TYPE
                         */
                        state->rule = GENERATOR_RULE_TYPE;
                        return 'a';
                case GENERATOR_COMPOUND_r:
                        /*
                         * TYPE ::= '(' TUPLE ')'
                         */
                        state->rule = GENERATOR_RULE_TUPLE_CLOSE;
                        next = generator_push(gen);
                        next->rule = GENERATOR_RULE_TUPLE;
                        mpz_set(next->seed, state->seed);
                        return '(';
                case GENERATOR_COMPOUND_e:
                        /*
                         * TYPE ::= '{' PAIR '}'
                         */
                        state->rule = GENERATOR_RULE_PAIR_CLOSE;
                        next = generator_push(gen);
                        next->rule = GENERATOR_RULE_PAIR;
                        mpz_set(next->seed, state->seed);
                        return '{';
                default:
                        assert(0);
                        return 0;
                }
        }
}
Exemple #30
0
int main(int argc, char** argv)
{
	int 		my_rank,
				procs;

	MPI_Status	status;

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

	mpz_t			*k;

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

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


	begin = MPI_Wtime();

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

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

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


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

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

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





	int counter=0;


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

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


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

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

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

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



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



	time_spent = (double)(end - begin);





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

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


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

	}


	
	free(k);

	MPI_Finalize();
	return 0;
}