Esempio n. 1
0
int RingZZ::is_positive(const ring_elem f) const
{
  mpz_ptr a = f.get_mpz();
  return mpz_sgn(a) > 0;
}
Esempio n. 2
0
static PyObject *
GMPY_mpz_is_fibonacci_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p, *q;
    PyObject *result = 0;
    mpz_t pmodn, zP;
    /* used for calculating the Lucas V sequence */
    mpz_t vl, vh, ql, qh, tmp;
    mp_bitcnt_t s = 0, j = 0;

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

    mpz_init(pmodn);
    mpz_init(zP);
    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_fibonacci_prp() requires 3 integer arguments");
        goto cleanup;
    }

    /* Check if p*p - 4*q == 0. */

    mpz_mul(tmp, p->z, p->z);
    mpz_mul_ui(qh, q->z, 4);
    mpz_sub(tmp, tmp, qh);
    if (mpz_sgn(tmp) == 0) {
        VALUE_ERROR("invalid values for p,q in is_fibonacci_prp()");
        goto cleanup;
    }

    /* Verify q = +/-1 */

    if ((mpz_cmp_si(q->z, 1) && mpz_cmp_si(q->z, -1)) || (mpz_sgn(p->z) <= 0)) {
        VALUE_ERROR("invalid values for p,q in is_fibonacci_prp()");
        goto cleanup;
    }

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

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

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

    mpz_set(zP, p->z);
    mpz_mod(pmodn, zP, n->z);

    /* mpz_lucasvmod(res, p, q, n, n); */
    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(n->z, 0);
    for (j = mpz_sizeinbase(n->z,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(n->z,j) == 1) {
            /* qh = ql*q */
            mpz_mul(qh, ql, q->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);

            /* 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);

    /* 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++) {
        /* 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);
    }

    /* vl contains our return value */
    mpz_mod(vl, vl, n->z);

    if (mpz_cmp(vl, pmodn) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(pmodn);
    mpz_clear(zP);
    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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
static PyObject *
GMPY_mpz_is_strongselfridge_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n;
    PyObject *result = 0, *temp = 0;
    long d = 5, p = 1, q = 0, max_d = 1000000;
    int jacobi = 0;
    mpz_t zD;

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

    mpz_init(zD);

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

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

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

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


    mpz_set_ui(zD, d);

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

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

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

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

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

        mpz_set_si(zD, d);
    }

    q = (1-d)/4;

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

  cleanup:
    Py_XINCREF(result);
  return_result:
    mpz_clear(zD);
    Py_DECREF((PyObject*)n);
    return result;
}
Esempio n. 5
0
static PyObject *
GMPY_mpz_is_strongbpsw_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n;
    PyObject *result = 0, *temp = 0;

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

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

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

    /* "O" is used to increment the reference to n so deleting temp won't
     * delete n.
     */
    temp = Py_BuildValue("Oi", n, 2);
    if (!temp)
        goto cleanup;
    result = GMPY_mpz_is_strong_prp(NULL, temp);
    Py_DECREF(temp);
    if (result == Py_False)
        goto return_result;
    /* Remember to ignore the preceding result */
    Py_DECREF(result);

    temp = Py_BuildValue("O", n);
    if (!temp)
        goto cleanup;
    result = GMPY_mpz_is_selfridge_prp(NULL, temp);
    Py_DECREF(temp);
    goto return_result;

  cleanup:
    Py_XINCREF(result);
  return_result:
    Py_DECREF((PyObject*)n);
    return result;
}
Esempio n. 6
0
/* can't be bothered doing the english version ...
 * we often just use the american version anyway. */
static size_t words_conv(Vstr_base *s1, size_t pos, const mpz_t num,
                         int cap, int del)
{
  size_t orig_pos = pos;
  struct Words_conv
  {
   const char *num;
   const char *str;
   const size_t len;
   mpz_t bignum;
  };
  static struct Words_conv conv_m[] =
    {
#if 0
     WORDS_MAKE("1" VAL0_300() VAL0_3(),           "centillion"),
     WORDS_MAKE("1" VAL0_60() VAL0_3(),            "vigintillion"),
     WORDS_MAKE("1" VAL0_60(),                     "novemdecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_12(), "octodecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_9(),  "septendecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_6(),  "sexdecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15() VAL0_3(),  "quindecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_15(),           "quattuordecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_12(),           "tredecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_9(),            "duodecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_6(),            "undecillion"),
     WORDS_MAKE("1" VAL0_30() VAL0_3(),            "decillion"),
     WORDS_MAKE("1" VAL0_30(),                     "nonillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_12(),           "octillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_9(),            "septillion"),
     WORDS_MAKE("1" VAL0_15() VAL0_6(),            "sextillion"),
#endif
     WORDS_MAKE("1" VAL0_15() VAL0_3(),            "quintillion"),
     WORDS_MAKE("1" VAL0_15(),                     "quadrillion"),
     WORDS_MAKE("1" VAL0_12(),                     "trillion"),
     WORDS_MAKE("1" VAL0_9(),                      "billion"),
     WORDS_MAKE("1" VAL0_6(),                      "million"),
     WORDS_MAKE("1" VAL0_3(),                      "thousand"),
     WORDS_MAKE("100",                             "hundred"),
    };
  static struct Words_conv conv_and =
     WORDS_MAKE("&",                               "and");
  static struct Words_conv conv_a[] =
    {
     WORDS_MAKE("90",                              "ninety"),
     WORDS_MAKE("80",                              "eighty"),
     WORDS_MAKE("70",                              "seventy"),
     WORDS_MAKE("60",                              "sixty"),
     WORDS_MAKE("50",                              "fifty"),
     WORDS_MAKE("40",                              "forty"),
     WORDS_MAKE("30",                              "thirty"),
     WORDS_MAKE("20",                              "twenty"),
     WORDS_MAKE("19",                              "nineteen"),
     WORDS_MAKE("18",                              "eighteen"),
     WORDS_MAKE("17",                              "seventeen"),
     WORDS_MAKE("16",                              "sixteen"),
     WORDS_MAKE("15",                              "fifteen"),
     WORDS_MAKE("14",                              "fourteen"),
     WORDS_MAKE("13",                              "thirteen"),
     WORDS_MAKE("12",                              "twelve"),
     WORDS_MAKE("11",                              "eleven"),
     WORDS_MAKE("10",                              "ten"),
     WORDS_MAKE("9",                               "nine"),
     WORDS_MAKE("8",                               "eight"),
     WORDS_MAKE("7",                               "seven"),
     WORDS_MAKE("6",                               "six"),
     WORDS_MAKE("5",                               "five"),
     WORDS_MAKE("4",                               "four"),
     WORDS_MAKE("3",                               "three"),
     WORDS_MAKE("2",                               "two"),
     WORDS_MAKE("1",                               "one"),
    };
  static struct Words_conv conv_zero =
     WORDS_MAKE("0",                               "zero");
  static struct Words_conv conv_minus =
     WORDS_MAKE("-",                               "minus");  
  static int done = FALSE;
  struct Words_conv *scan = conv_m;
  unsigned int alen = sizeof(conv_m) / sizeof(conv_m[0]);
  size_t ret = 0;
  mpz_t tmp;

  if (!done)
  {
    while (alen)
    {
      mpz_init_set_str(scan->bignum, scan->num, 10);
      
      --alen;
      ++scan;
    }
    scan = conv_a;
    alen = sizeof(conv_a) / sizeof(conv_a[0]);
    while (alen)
    {
      mpz_init_set_str(scan->bignum, scan->num, 10);
      
      --alen;
      ++scan;
    }
    
    scan = conv_m;
    alen = sizeof(conv_m) / sizeof(conv_m[0]);
    
    done = TRUE;
  }
  
  mpz_init_set(tmp, num);
  mpz_abs(tmp, tmp);

  if (mpz_cmp_ui(num, 0) == 0)
  {
    scan = &conv_zero;
    WORDS_ADD_WORD();
  }
  else
  {
    while (alen)
    {
      mpz_t quo;

      mpz_init(quo);
      
      while (mpz_cmp(tmp, scan->bignum) >= 0)
      {
        size_t front = 0;
        
        mpz_tdiv_qr(quo, tmp, tmp, scan->bignum);

        if (!(front = words_conv(s1, pos, quo, FALSE, FALSE)))
          return (0);
        ret += front;
        pos += front;

        WORDS_ADD_WORD();
      }
      
      --alen;
      ++scan;
    }

    if (ret && (mpz_cmp_ui(tmp, 0) != 0))
    {
      scan = &conv_and;
      WORDS_ADD_WORD();
    }

    scan = conv_a;
    alen = sizeof(conv_a) / sizeof(conv_a[0]);
    while (alen)
    {
      while (mpz_cmp(tmp, scan->bignum) >= 0)
      {
        mpz_mod(tmp, tmp, scan->bignum);
        WORDS_ADD_WORD();
      }
      
      --alen;
      ++scan;
    }
  }
  
  ASSERT(ret >= 2);
  
  if (mpz_sgn(num) == -1)
  {
    scan = &conv_minus;
    pos  = orig_pos;
    WORDS_ADD_WORD();
  }
  
  ASSERT(ret >= 2);

  ++orig_pos;
  if (del)
  { /* get rid of space */
    if (s1) vstr_del(s1, orig_pos, 1);
    --ret;
  }
  
  if (cap && s1 && !vstr_conv_uppercase(s1, orig_pos, 1)) /* capitalize */
    return (0);
  
  return (ret);
}
Esempio n. 7
0
static PyObject *
GMPy_Integer_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPZ_Object *result;

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

    if (CHECK_MPZANY(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            native_si temp = GMPy_Integer_AsNative_siAndError(y, &error);

            if (!error) {
                if (temp > 0) {
                    mpz_fdiv_q_ui(result->z, MPZ(x), temp);
                }
                else if (temp == 0) {
                    ZERO_ERROR("division or modulo by zero");
                    Py_DECREF((PyObject*)result);
                    return NULL;
                }
                else {
                    mpz_cdiv_q_ui(result->z, MPZ(x), -temp);
                    mpz_neg(result->z, result->z);
                }
            }
            else {
                mpz_set_PyIntOrLong(global.tempz, y);
                mpz_fdiv_q(result->z, MPZ(x), global.tempz);
            }
            return (PyObject*)result;
        }

        if (CHECK_MPZANY(y)) {
            if (mpz_sgn(MPZ(y)) == 0) {
                ZERO_ERROR("division or modulo by zero");
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpz_fdiv_q(result->z, MPZ(x), MPZ(y));
            return (PyObject*)result;
        }
    }

    if (CHECK_MPZANY(y)) {
        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_DECREF((PyObject*)result);
            return NULL;
        }

        if (PyIntOrLong_Check(x)) {
            mpz_set_PyIntOrLong(global.tempz, x);
            mpz_fdiv_q(result->z, global.tempz, MPZ(y));
            return (PyObject*)result;
        }
    }

    if (IS_INTEGER(x) && IS_INTEGER(y)) {
        MPZ_Object *tempx, *tempy;

        tempx = GMPy_MPZ_From_Integer(x, context);
        tempy = GMPy_MPZ_From_Integer(y, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        if (mpz_sgn(tempy->z) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }

        mpz_fdiv_q(result->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;
}
Esempio n. 8
0
void input_poly(mpz_t N, mpz_t ** A, i32_t *adeg, mpz_t ** B,
                i32_t *bdeg, mpz_t m, FILE *fp)
/*******************************************************/
{ char  token[256], value[512], thisLine[1024];
  int   i, j, cont=1, have_m=0;
  mpz_t tmpA, tmpB;

  *adeg = *bdeg = 0;                                                    
  *A = xmalloc(9*sizeof(**A)); /* plenty o' room. */
  *B = xmalloc(9*sizeof(**B));
  for (i=0; i<9; i++) {
    mpz_init_set_ui((*A)[i], 0);
    mpz_init_set_ui((*B)[i], 0);
  }
  while (cont) {
    thisLine[0] = 0;
    fgets(thisLine, 1023, fp);
    if ((sscanf(thisLine, "%255s %511s", token, value)==2) &&
                (thisLine[0] != '#')) {
	  token[sizeof(token)-1] = 0;
      if (strncmp(token, "n:", 2)==0) {
        mpz_set_str(N, value, 10);
      } else if (strncmp(token, "m:", 2)==0) {
        mpz_set_str(m, value, 10);
        have_m=1;
      } else if ((token[0]=='c') && (token[1] >= '0') && (token[1] <= '8')) {
        mpz_set_str((*A)[token[1]-'0'], value, 10);
        *adeg = MAX(*adeg, token[1]-'0');
      } else if ((token[0]=='Y') && (token[1] >= '0') && (token[1] <= '8')) {
        mpz_set_str((*B)[token[1]-'0'], value, 10);
        *bdeg = MAX(*bdeg, token[1]-'0');
      } else if (strncmp(token, "END_POLY", 8)==0) {
        cont=0;
      }
    }
    if (feof(fp)) cont=0;
  }

  if (have_m == 0) { /* recover m from the linear poly */
    if (*bdeg == 1) { /* assume *B is linear (it usually is) */
      mpz_invert(m, (*B)[1], N);
      mpz_mul(m, m, (*B)[0]);
      mpz_neg(m, m);
      mpz_mod(m, m, N);
    } else {
      complain("could not find m\n");
    }
  } else if (*bdeg == 0) { /* monic linear poly may be omitted */
    mpz_set_ui((*B)[1], 1);
    mpz_neg((*B)[0], m);
    *bdeg=1;
  }

  /* Verify the polynomials: */
  mpz_init_set(tmpA, (*A)[*adeg]);
  for (i = *adeg - 1; i >= 0; i--) {
    mpz_mul(tmpA, tmpA, m);
    mpz_add(tmpA, tmpA, (*A)[i]);
    mpz_mod(tmpA, tmpA, N);
  }
  mpz_init_set(tmpB, (*B)[*bdeg]);
  for (i = *bdeg - 1; i >= 0; i--) {
    mpz_mul(tmpB, tmpB, m);
    mpz_add(tmpB, tmpB, (*B)[i]);
    mpz_mod(tmpB, tmpB, N);
  }
  if (mpz_sgn(tmpA) || mpz_sgn(tmpB)) {
    printf("Error: m is not a common root of the polynomials:\n");
    for (i=0; i<=*adeg; i++) 
      printf("c%d: %s\n", i, mpz_get_str(value, 10, (*A)[i]));
    for (i=0; i<=*bdeg; i++) 
      printf("Y%d: %s\n", i, mpz_get_str(value, 10, (*B)[i]));
    printf("n: ");
    mpz_out_str(NULL,10,N);
    exit(-1);
  }
  mpz_clear(tmpA); mpz_clear(tmpB);
}
Esempio n. 9
0
void input_poly(mpz_t N, mpz_t ** A, i32_t * adeg_ptr, mpz_t ** B,
                i32_t * bdeg_ptr, mpz_t m, FILE * input_file)
/*******************************************************/
{
  char *input_line = NULL;
  size_t input_line_alloc = 0;
  i32_t have_m = 0;

  if (mpz_inp_str(N, input_file, 10) == 0)
    complain("Cannot read number which is to be factored: %m\n");

  *adeg_ptr = -1;
  *bdeg_ptr = -1;
  while (have_m == 0) {
    i32_t grad;
    char *field;

    if (skip_blanks_comments(&input_line, &input_line_alloc, input_file) <= 0)
      complain
        ("Cannot read common root of NFS polynomials from input file\n");
    switch (*input_line) {
      case 'X':
        if (sscanf(input_line + 1, "%d", &grad) == 0)
          complain("Cannot understand input line %s\n", input_line);
        if (grad > *adeg_ptr) {
          i32_t i;

          if (*adeg_ptr >= 0)
            *A = xrealloc(*A, (grad + 1) * sizeof(**A));
          else
            *A = xmalloc((grad + 1) * sizeof(**A));
          for (i = *adeg_ptr + 1; i <= grad; i++)
            mpz_init_set_ui((*A)[i], 0);
          *adeg_ptr = grad;
        }
        strtok(input_line, " \t");
        field = strtok(NULL, " \t");
        if (string2mpz((*A)[grad], field, 10) != 0)
          complain("Cannot understand number %s\n", field);
        break;
      case 'Y':
        if (sscanf(input_line + 1, "%d", &grad) == 0)
          complain("Cannot understand input line %s\n", input_line);
        if (grad > *bdeg_ptr) {
          i32_t i;

          if (*bdeg_ptr >= 0)
            *B = xrealloc(*B, (grad + 1) * sizeof(**B));
          else
            *B = xmalloc((grad + 1) * sizeof(**B));
          for (i = *bdeg_ptr + 1; i <= grad; i++)
            mpz_init_set_ui((*B)[i], 0);
          *bdeg_ptr = grad;
        }
        strtok(input_line, " \t");
        field = strtok(NULL, " \t");
        if (string2mpz((*B)[grad], field, 10) != 0)
          complain("Cannot understand number %s\n", field);
        break;
      case 'M':
        strtok(input_line, " \t");
        field = strtok(NULL, " \t");
        if (string2mpz(m, field, 10) != 0)
          complain("Cannot understand number %s\n", field);
        have_m = 1;
        break;
    }
  }
  if (*adeg_ptr == -1) {
    *adeg_ptr = 1;
    *A = xmalloc(2 * sizeof(**A));
    mpz_init_set_ui((*A)[1], 1);
    mpz_init((*A)[0]);
    mpz_neg((*A)[0], m);
  }
  if (*bdeg_ptr == -1) {
    *bdeg_ptr = 1;
    *B = xmalloc(2 * sizeof(**B));
    mpz_init_set_ui((*B)[1], 1);
    mpz_init((*B)[0]);
    mpz_neg((*B)[0], m);
  }
  if (*adeg_ptr == 0 || *bdeg_ptr == 0)
    complain("Polynomials of degree zero are not allowed\n");

  {
    mpz_t x;
    i32_t i;

    if (mpz_sgn(*(*A + *adeg_ptr)) == 0) {
      complain("Leading coefficient (degree %u) vanishes\n", *adeg_ptr);
    }
    if (mpz_sgn(*(*B + *bdeg_ptr)) == 0) {
      complain("Leading coefficient (degree %u) vanishes\n", *bdeg_ptr);
    }
    for (i = 1, mpz_init_set(x, (*A)[*adeg_ptr]); i <= *adeg_ptr; i++) {
      mpz_mul(x, x, m);
      mpz_add(x, x, (*A)[*adeg_ptr - i]);
    }
    mpz_fdiv_r(x, x, N);
    if (mpz_sgn(x) != 0) {
      mpz_out_str(stderr, 10, m);
      complain(" not a root of first poly\n");
    }
    for (i = 1, mpz_set(x, (*B)[*bdeg_ptr]); i <= *bdeg_ptr; i++) {
      mpz_mul(x, x, m);
      mpz_add(x, x, (*B)[*bdeg_ptr - i]);
    }
    mpz_fdiv_r(x, x, N);
    if (mpz_sgn(x) != 0) {
      mpz_out_str(stderr, 10, m);
      complain(" not a root of second poly\n");
    }
    mpz_clear(x);
  }

  free(input_line);
}
Esempio n. 10
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;
}
Esempio n. 11
0
void
check_one (mpz_srcptr a, unsigned long d)
{
  mpz_t  q, r, p, d2exp;
  int    inplace;

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

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

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

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

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


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

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


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

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

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


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

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

  abort ();
}
Esempio n. 12
0
/*-------------------------------------------------------------------*/
static void gmp_poly_mul(gmp_poly_t *p1, gmp_poly_t *p2,
			gmp_poly_t *mod, uint32 free_p2) {

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

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

	/* initialize */

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

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

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

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

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

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

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

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

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

		/* recalculate the degree of the result */

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

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

		if (prod_degree <= d)
			continue;

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

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

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

	/* recalculate the degree */

	i = prod_degree;
	while (i > 0 && mpz_sgn(p1->coeff[i]) == 0) {
		mpz_realloc2(p1->coeff[i], 1);
		i--;
	}
	p1->degree = i;
}
Esempio n. 13
0
void eval_block(code *block, map* vars) {
  while (true) {
    code_skip_whitespace(block);

    if (block->source[block->pos] == '?') {
      uint8_t brackets = 0;
      size_t start, length = 0;
      mpz_t value;
      mpz_init(value);

      block->pos++;

      code_skip_whitespace(block);
      _parse_value(block, value, vars);
      code_skip_whitespace(block);

      start = block->pos + 1;

      while (true) {
        length++;

        if (block->source[block->pos] == '{') {
          brackets++;
          block->pos++;
        } else if (block->source[block->pos] == '}') {
          brackets--;
          block->pos++;
          if (brackets == 0) break;
        } else {
          block->pos++;
        }
      }

      if (mpz_sgn(value) == 0) {
        code subblock;

        code_init(&subblock);
        code_append(&subblock, block->source + start * sizeof(char), length - 2);
        eval_block(&subblock, vars);
        code_free(&subblock);
      }

      mpz_clear(value);
    } else if (block->source[block->pos] == '!') {
      mpz_t value;
      mpz_init(value);

      block->pos++;
      code_skip_whitespace(block);
      _parse_value(block, value, vars);

      mpz_out_str(stdout, 10, value);
      printf("\n");

      mpz_clear(value);
    } else {
      char *var = malloc(1024 * sizeof(char));
      mpz_t value;
      mpz_init(value);

      _parse_variable_name(block, var);

      code_skip_whitespace(block);
      switch (block->source[block->pos]) {
        case '=':
          block->pos++;
          code_skip_whitespace(block);

          _parse_value(block, value, vars);
          map_set(vars, var, value, false);

          break;

        case '+':
          block->pos += 2;
          code_skip_whitespace(block);

          _parse_value(block, value, vars);
          map_set(vars, var, value, true);

          break;

        case '-':
          block->pos += 2;
          code_skip_whitespace(block);

          _parse_value(block, value, vars);
          mpz_neg(value, value);
          map_set(vars, var, value, true);

          break;

        default:
          fprintf(stderr, "Parse error\n");
      }

      free(var);
      mpz_clear(value);
    }

    code_skip_whitespace(block);

    if (block->pos >= block->length) return;

    if (block->source[block->pos] == ';') {
      block->pos++;
    } else {
      fprintf(stderr, "Missing ;\n");
      return;
    }
  }
}
Esempio n. 14
0
static int
GMPy_XMPZ_NonZero_Slot(XMPZ_Object *x)
{
    return mpz_sgn(x->z) != 0;
}
Esempio n. 15
0
int chpl_mpz_sgn(const mpz_t op) {
  return mpz_sgn(op);
}
Esempio n. 16
0
static PyObject *
GMPy_MPZ_unpack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, guard_bit, extra_bits, temp_bits;
    Py_ssize_t index = 0, lst_count, i, lst_ptr = 0;
    PyObject *result;
    mpz_t temp;
    mp_limb_t extra = 0;
    MPZ_Object *item, *tempx = NULL;
    CTXT_Object *context = NULL;

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

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), context))) {
        TYPE_ERROR("unpack() requires 'int','int' arguments");
        return NULL;
    }

    if (mpz_sgn(tempx->z) < 0) {
        VALUE_ERROR("unpack() requires x >= 0");
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        total_bits = 0;
    }
    else {
        total_bits = mpz_sizeinbase(tempx->z, 2);
    }

    lst_count = total_bits / nbits;
    if ((total_bits % nbits) || !lst_count) {
        lst_count += 1;
    }

    if (!(result = PyList_New(lst_count))) {
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        if (!(item = GMPy_MPZ_New(context))) {
            Py_DECREF((PyObject*)tempx);
            Py_DECREF(result);
            return NULL;
        }
        mpz_set_ui(item->z, 0);
        PyList_SET_ITEM(result, 0, (PyObject*)item);
        Py_DECREF((PyObject*)tempx);
        return result;
    }

    mpz_init(temp);
    guard_bit = nbits + (2 * mp_bits_per_limb);
    extra_bits = 0;
    index = 0;

    while (lst_ptr < lst_count) {
        i = 0;
        temp_bits = 0;
        mpz_set_ui(temp, 0);
        mpz_setbit(temp, guard_bit);
        while (temp_bits + extra_bits < nbits) {
            temp->_mp_d[i++] = mpz_getlimbn(tempx->z, index++);
            temp_bits += mp_bits_per_limb;
        }
        mpz_clrbit(temp, guard_bit);
        mpz_mul_2exp(temp, temp, extra_bits);
        if (mpz_sgn(temp) == 0 && extra != 0) {
            mpz_set_ui(temp, 1);
            temp->_mp_d[0] = extra;
        }
        else {
           mpn_add_1(temp->_mp_d, temp->_mp_d, mpz_size(temp), extra);
        }
        temp_bits += extra_bits;

        while ((lst_ptr < lst_count) && (temp_bits >= nbits)) {
            if(!(item = GMPy_MPZ_New(context))) {
                mpz_clear(temp);
                Py_DECREF((PyObject*)tempx);
                Py_DECREF(result);
                return NULL;
            }
            mpz_tdiv_r_2exp(item->z, temp, nbits);
            PyList_SET_ITEM(result, lst_ptr++, (PyObject*)item);
            mpz_tdiv_q_2exp(temp, temp, nbits);
            temp_bits -= nbits;
        }
        extra = mpz_getlimbn(temp, 0);
        extra_bits = temp_bits;
    }
    Py_DECREF((PyObject*)tempx);
    mpz_clear(temp);
    return result;
}
Esempio n. 17
0
static int
pol_expand(curr_poly_t *c, mpz_t gmp_N, mpz_t high_coeff,
		mpz_t gmp_p, mpz_t gmp_d, 
		double coeff_bound, uint32 degree)
{
	uint32 i, j;

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

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

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

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

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

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

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

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

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

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

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

		if (j == MAX_CORRECT_STEPS)
			return 0;
	}

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

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

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

	if (mpz_cmpabs_d(c->gmp_a[degree - 2], coeff_bound) > 0) {
		return 1;
	}
	return 2;
}
Esempio n. 18
0
static PyObject *
GMPy_MPZ_pack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, tempx_bits;
    Py_ssize_t index, lst_count, i, temp_bits, limb_count;
    PyObject *lst;
    mpz_t temp;
    MPZ_Object *result, *tempx = 0;
    CTXT_Object *context = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!PyList_Check(PyTuple_GET_ITEM(args, 0))) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

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

    lst = PyTuple_GET_ITEM(args, 0);
    lst_count = PyList_GET_SIZE(lst);
    total_bits = nbits * lst_count;

    if ((total_bits / lst_count) != nbits) {
        VALUE_ERROR("result too large to store in an 'mpz'");
        return NULL;
    }

    mpz_set_ui(result->z, 0);
    mpz_setbit(result->z, total_bits + (mp_bits_per_limb * 2));

    mpz_init(temp);
    mpz_set_ui(temp, 0);
    limb_count = 0;
    tempx_bits = 0;

    for (index = 0; index < lst_count; index++) {
        if (!(tempx = GMPy_MPZ_From_Integer(PyList_GetItem(lst, index), context))
            || (mpz_sgn(tempx->z) < 0)
            || (mpz_sizeinbase(tempx->z,2) > (size_t)nbits)) {
            TYPE_ERROR("pack() requires list elements be positive integers < 2^n bits");
            mpz_clear(temp);
            Py_XDECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_mul_2exp(tempx->z, tempx->z, tempx_bits);
        mpz_add(temp, temp, tempx->z);
        tempx_bits += nbits;
        i = 0;
        temp_bits = mpz_sizeinbase(temp, 2) * mpz_sgn(temp);
        while (tempx_bits >= (mp_bitcnt_t)mp_bits_per_limb) {
            if (temp_bits > 0) {
                result->z->_mp_d[limb_count] = mpz_getlimbn(temp, i);
            }
            i += 1;
            tempx_bits -= mp_bits_per_limb;
            limb_count += 1;
            temp_bits -= mp_bits_per_limb;
        }
        if (temp_bits > 0) {
            mpz_tdiv_q_2exp(temp, temp, mp_bits_per_limb * i);
        }
        else {
            mpz_set_ui(temp, 0);
        }
        Py_DECREF((PyObject*)tempx);
    }
    result->z->_mp_d[limb_count] = mpz_getlimbn(temp, 0);
    mpz_clrbit(result->z, total_bits + (mp_bits_per_limb * 2));
    mpz_clear(temp);
    return (PyObject*)result;
}
Esempio n. 19
0
/* If x = p/2^r, put in y an approximation of atan(x)/x using 2^m terms
   for the series expansion, with an error of at most 1 ulp.
   Assumes |x| < 1.

   If X=x^2, we want 1 - X/3 + X^2/5 - ... + (-1)^k*X^k/(2k+1) + ...

   Assume p is non-zero.

   When we sum terms up to x^k/(2k+1), the denominator Q[0] is
   3*5*7*...*(2k+1) ~ (2k/e)^k.
*/
static void
mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
{
  mpz_t *S, *Q, *ptoj;
  unsigned long n, i, k, j, l;
  mpfr_exp_t diff, expo;
  int im, done;
  mpfr_prec_t mult, *accu, *log2_nb_terms;
  mpfr_prec_t precy = MPFR_PREC(y);

  MPFR_ASSERTD(mpz_cmp_ui (p, 0) != 0);

  accu = (mpfr_prec_t*) (*__gmp_allocate_func) ((2 * m + 2) * sizeof (mpfr_prec_t));
  log2_nb_terms = accu + m + 1;

  /* Set Tables */
  S    = tab;           /* S */
  ptoj = S + 1*(m+1);   /* p^2^j Precomputed table */
  Q    = S + 2*(m+1);   /* Product of Odd integer  table  */

  /* From p to p^2, and r to 2r */
  mpz_mul (p, p, p);
  MPFR_ASSERTD (2 * r > r);
  r = 2 * r;

  /* Normalize p */
  n = mpz_scan1 (p, 0);
  mpz_tdiv_q_2exp (p, p, n); /* exact */
  MPFR_ASSERTD (r > n);
  r -= n;
  /* since |p/2^r| < 1, and p is a non-zero integer, necessarily r > 0 */

  MPFR_ASSERTD (mpz_sgn (p) > 0);
  MPFR_ASSERTD (m > 0);

  /* check if p=1 (special case) */
  l = 0;
  /*
    We compute by binary splitting, with X = x^2 = p/2^r:
    P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise
    Q(a,b) = (2a+1)*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise
    S(a,b) = p*(2a+1) if a+1=b, Q(c,b)*S(a,c)+Q(a,c)*P(a,c)*S(c,b) otherwise
    Then atan(x)/x ~ S(0,i)/Q(0,i) for i so that (p/2^r)^i/i is small enough.
    The factor 2^(r*(b-a)) in Q(a,b) is implicit, thus we have to take it
    into account when we compute with Q.
  */
  accu[0] = 0; /* accu[k] = Mult[0] + ... + Mult[k], where Mult[j] is the
                  number of bits of the corresponding term S[j]/Q[j] */
  if (mpz_cmp_ui (p, 1) != 0)
    {
      /* p <> 1: precompute ptoj table */
      mpz_set (ptoj[0], p);
      for (im = 1 ; im <= m ; im ++)
        mpz_mul (ptoj[im], ptoj[im - 1], ptoj[im - 1]);
      /* main loop */
      n = 1UL << m;
      /* the ith term being X^i/(2i+1) with X=p/2^r, we can stop when
         p^i/2^(r*i) < 2^(-precy), i.e. r*i > precy + log2(p^i) */
      for (i = k = done = 0; (i < n) && (done == 0); i += 2, k ++)
        {
          /* initialize both S[k],Q[k] and S[k+1],Q[k+1] */
          mpz_set_ui (Q[k+1], 2 * i + 3); /* Q(i+1,i+2) */
          mpz_mul_ui (S[k+1], p, 2 * i + 1); /* S(i+1,i+2) */
          mpz_mul_2exp (S[k], Q[k+1], r);
          mpz_sub (S[k], S[k], S[k+1]); /* S(i,i+2) */
          mpz_mul_ui (Q[k], Q[k+1], 2 * i + 1); /* Q(i,i+2) */
          log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */
          for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l ++, j >>= 1, k --)
            {
              /* invariant: S[k-1]/Q[k-1] and S[k]/Q[k] correspond
                 to 2^l terms each. We combine them into S[k-1]/Q[k-1] */
              MPFR_ASSERTD (k > 0);
              mpz_mul (S[k], S[k], Q[k-1]);
              mpz_mul (S[k], S[k], ptoj[l]);
              mpz_mul (S[k-1], S[k-1], Q[k]);
              mpz_mul_2exp (S[k-1], S[k-1], r << l);
              mpz_add (S[k-1], S[k-1], S[k]);
              mpz_mul (Q[k-1], Q[k-1], Q[k]);
              log2_nb_terms[k-1] = l + 1;
              /* now S[k-1]/Q[k-1] corresponds to 2^(l+1) terms */
              MPFR_MPZ_SIZEINBASE2(mult, ptoj[l+1]);
              /* FIXME: precompute bits(ptoj[l+1]) outside the loop? */
              mult = (r << (l + 1)) - mult - 1;
              accu[k-1] = (k == 1) ? mult : accu[k-2] + mult;
              if (accu[k-1] > precy)
                done = 1;
            }
        }
    }
Esempio n. 20
0
/*-------------------------------------------------------------------------*/
static int
pol_expand(curr_poly_t *c, mpz_t gmp_N)
{
    /* compute coefficients */
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[5]);
    mpz_sub(c->gmp_help3, gmp_N, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    if (mpz_cmp_ui(c->gmp_p, 1) == 0)
        mpz_set_ui(c->gmp_help2, 1);
    else {
        if (!mpz_invert(c->gmp_help2, c->gmp_d, c->gmp_p))
            return 0;
    }
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_a[4], c->gmp_help4, c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[4]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[3], c->gmp_help3, c->gmp_help4);
    mpz_fdiv_q(c->gmp_a[3], c->gmp_a[3], c->gmp_p);
    mpz_mul(c->gmp_a[3], c->gmp_a[3], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[3]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[2], c->gmp_help3, c->gmp_help4);
    mpz_fdiv_q(c->gmp_a[2], c->gmp_a[2], c->gmp_p);
    mpz_mul(c->gmp_a[2], c->gmp_a[2], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[2], c->gmp_a[2], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d);
    mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[2]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_fdiv_q(c->gmp_a[1], c->gmp_help3, c->gmp_d);
    mpz_fdiv_q(c->gmp_a[1], c->gmp_a[1], c->gmp_p);
    mpz_mul(c->gmp_a[1], c->gmp_a[1], c->gmp_p);
    mpz_mul(c->gmp_help4, c->gmp_help3, c->gmp_help2);
    mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p);
    mpz_add(c->gmp_a[1], c->gmp_a[1], c->gmp_help1);
    mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_a[1]);
    mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4);
    mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p);
    if (mpz_sgn(c->gmp_help1))
        return 0;

    mpz_set(c->gmp_a[0], c->gmp_help3);

    mpz_fdiv_qr(c->gmp_help1, c->gmp_a[3], c->gmp_a[3], c->gmp_d);
    mpz_add(c->gmp_help2, c->gmp_a[3], c->gmp_a[3]);
    if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) {
        mpz_sub(c->gmp_a[3], c->gmp_a[3], c->gmp_d);
        mpz_add_ui(c->gmp_help1, c->gmp_help1, 1);
    }
    mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p);
    mpz_add(c->gmp_a[4], c->gmp_a[4], c->gmp_help1);

    mpz_fdiv_qr(c->gmp_help1, c->gmp_a[2], c->gmp_a[2], c->gmp_d);
    mpz_add(c->gmp_help2, c->gmp_a[2], c->gmp_a[2]);
    if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) {
        mpz_sub(c->gmp_a[2], c->gmp_a[2], c->gmp_d);
        mpz_add_ui(c->gmp_help1, c->gmp_help1, 1);
    }
    mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p);
    mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1);

    mpz_set(c->gmp_lina[1], c->gmp_p);
    mpz_neg(c->gmp_lina[0], c->gmp_d);
    mpz_invert(c->gmp_m, c->gmp_p, gmp_N);
    mpz_mul(c->gmp_m, c->gmp_m, c->gmp_d);
    mpz_mod(c->gmp_m, c->gmp_m, gmp_N);

    if (verbose > 2) {
        int i;

        printf("pol-expand\npol0: ");
        for (i = 5; i >= 0; i--) {
            mpz_out_str(stdout, 10, c->gmp_a[i]);
            printf(" ");
        }
        printf("\npol1: ");
        mpz_out_str(stdout, 10, c->gmp_lina[1]);
        printf(" ");
        mpz_out_str(stdout, 10, c->gmp_lina[0]);
        printf("\n\n");
    }

    return 1;
}
Esempio n. 21
0
static int
Pyxmpz_nonzero(PyxmpzObject *x)
{
    return mpz_sgn(x->z) != 0;
}
Esempio n. 22
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);
}
Esempio n. 23
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;
}
Esempio n. 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 ();
    }
}
Esempio n. 25
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;
}
Esempio n. 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);
}
Esempio n. 27
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;
}
Esempio n. 28
0
void
print (int limb_bits, int nail_bits)
{
  int    i;
  mpz_t  mhi, mlo;

  printf ("/* This file generated by gen-psqr.c - DO NOT EDIT. */\n");
  printf ("\n");

  printf ("#if GMP_LIMB_BITS != %d || GMP_NAIL_BITS != %d\n",
          limb_bits, nail_bits);
  printf ("Error, error, this data is for %d bit limb and %d bit nail\n",
          limb_bits, nail_bits);
  printf ("#endif\n");
  printf ("\n");

  printf ("/* Non-zero bit indicates a quadratic residue mod 0x100.\n");
  printf ("   This test identifies %.2f%% as non-squares (%d/256). */\n",
          (1.0 - sq_res_0x100_fraction) * 100.0,
          0x100 - sq_res_0x100_num);
  printf ("static const mp_limb_t\n");
  printf ("sq_res_0x100[%d] = {\n", nsq_res_0x100);
  for (i = 0; i < nsq_res_0x100; i++)
    {
      printf ("  CNST_LIMB(0x");
      mpz_out_str (stdout, 16, sq_res_0x100[i]);
      printf ("),\n");
    }
  printf ("};\n");
  printf ("\n");

  if (mpz_sgn (pp) != 0)
    {
      printf ("/* mpn_mod_34lsub1 not used due to %s */\n", mod34_excuse);
      printf ("/* PERFSQR_PP = ");
    }
  else
    printf ("/* 2^%d-1 = ", mod34_bits);
  for (i = 0; i < nrawfactor; i++)
    {
      if (i != 0)
        printf (" * ");
      printf ("%d", rawfactor[i].divisor);
      if (rawfactor[i].multiplicity != 1)
        printf ("^%d", rawfactor[i].multiplicity);
    }
  printf (" %s*/\n", mpz_sgn (pp) == 0 ? "... " : "");

  printf ("#define PERFSQR_MOD_BITS  %d\n", mod_bits);
  if (mpz_sgn (pp) != 0)
    {
      printf ("#define PERFSQR_PP            CNST_LIMB(0x");
      mpz_out_str (stdout, 16, pp);
      printf (")\n");
      printf ("#define PERFSQR_PP_NORM       CNST_LIMB(0x");
      mpz_out_str (stdout, 16, pp_norm);
      printf (")\n");
      printf ("#define PERFSQR_PP_INVERTED   CNST_LIMB(0x");
      mpz_out_str (stdout, 16, pp_inverted);
      printf (")\n");
    }
  printf ("\n");

  mpz_init (mhi);
  mpz_init (mlo);

  printf ("/* This test identifies %.2f%% as non-squares. */\n",
          (1.0 - total_fraction) * 100.0);
  printf ("#define PERFSQR_MOD_TEST(up, usize) \\\n");
  printf ("  do {                              \\\n");
  printf ("    mp_limb_t  r;                   \\\n");
  if (mpz_sgn (pp) != 0)
    printf ("    PERFSQR_MOD_PP (r, up, usize);  \\\n");
  else
    printf ("    PERFSQR_MOD_34 (r, up, usize);  \\\n");

  for (i = 0; i < nfactor; i++)
    {
      printf ("                                    \\\n");
      printf ("    /* %5.2f%% */                    \\\n",
              (1.0 - factor[i].fraction) * 100.0);

      printf ("    PERFSQR_MOD_%d (r, CNST_LIMB(%2d), CNST_LIMB(0x",
              factor[i].divisor <= limb_bits ? 1 : 2,
              factor[i].divisor);
      mpz_out_str (stdout, 16, factor[i].inverse);
      printf ("), \\\n");
      printf ("                   CNST_LIMB(0x");

      if ( factor[i].divisor <= limb_bits)
        {
          mpz_out_str (stdout, 16, factor[i].mask);
        }
      else
        {
          mpz_tdiv_r_2exp (mlo, factor[i].mask, (unsigned long) limb_bits);
          mpz_tdiv_q_2exp (mhi, factor[i].mask, (unsigned long) limb_bits);
          mpz_out_str (stdout, 16, mhi);
          printf ("), CNST_LIMB(0x");
          mpz_out_str (stdout, 16, mlo);
        }
      printf (")); \\\n");
    }

  printf ("  } while (0)\n");
  printf ("\n");

  printf ("/* Grand total sq_res_0x100 and PERFSQR_MOD_TEST, %.2f%% non-squares. */\n",
          (1.0 - (total_fraction * 44.0/256.0)) * 100.0);
  printf ("\n");

  printf ("/* helper for tests/mpz/t-perfsqr.c */\n");
  printf ("#define PERFSQR_DIVISORS  { 256,");
  for (i = 0; i < nfactor; i++)
      printf (" %d,", factor[i].divisor);
  printf (" }\n");


  mpz_clear (mhi);
  mpz_clear (mlo);
}
Esempio n. 29
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;
}
Esempio n. 30
0
bool RingZZ::is_zero(const ring_elem f) const
{
  mpz_ptr a = f.get_mpz();
  return mpz_sgn(a) == 0;
}