示例#1
0
static PyObject *
GMPy_MPZ_c_div_2exp(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits;
    MPZ_Object *result, *tempx;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("c_div_2exp() requires 'mpz','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;
    }

    tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    result = GMPy_MPZ_New(NULL);
    if (!tempx || !result) {
        Py_XDECREF((PyObject*)result);
        Py_XDECREF((PyObject*)tempx);
        return NULL;
    }

    mpz_cdiv_q_2exp(result->z, tempx->z, nbits);
    Py_DECREF((PyObject*)tempx);
    return (PyObject*)result;
}
示例#2
0
/*-----------------------------------------------------------------------------*/
void node_red(tree_t tree)
{
  if(mpz_tstbit(tree->M, 0))
  {
    mpz_set(tree->M_red, tree->M);
    tree->shift = 0;
  }
  else
  {
    tree->shift = mpz_scan1(tree->M,0);
    mpz_cdiv_q_2exp(tree->M_red, tree->M, tree->shift);  
  }
}
示例#3
0
void
hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
		   char **ap, unsigned long *b, char **rp)
{
  mpz_t a, r;
  unsigned long abits, bbits;
  unsigned signs;

  mpz_init (a);
  mpz_init (r);

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

  mpz_rrandomb (a, state, abits);

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

  switch (op)
    {
    default:
      abort ();

    case OP_SETBIT:
      mpz_set (r, a);
      mpz_setbit (r, bbits);
      break;
    case OP_CLRBIT:
      mpz_set (r, a);
      mpz_clrbit (r, bbits);
      break;
    case OP_COMBIT:
      mpz_set (r, a);
      mpz_combit (r, bbits);
      break;
    case OP_CDIV_Q_2:
      mpz_cdiv_q_2exp (r, a, bbits);
      break;
    case OP_CDIV_R_2:
      mpz_cdiv_r_2exp (r, a, bbits);
      break;
    case OP_FDIV_Q_2:
      mpz_fdiv_q_2exp (r, a, bbits);
      break;
    case OP_FDIV_R_2:
      mpz_fdiv_r_2exp (r, a, bbits);
      break;
    case OP_TDIV_Q_2:
      mpz_tdiv_q_2exp (r, a, bbits);
      break;
    case OP_TDIV_R_2:
      mpz_tdiv_r_2exp (r, a, bbits);
      break;
    }

  gmp_asprintf (ap, "%Zx", a);
  *b = bbits;
  gmp_asprintf (rp, "%Zx", r);

  mpz_clear (a);
  mpz_clear (r);
}
示例#4
0
static PyObject *
Pympz_mpmath_normalize(PyObject *self, PyObject *args)
{
    long sign = 0;
    mpir_si bc = 0, prec = 0, shift, zbits, carry = 0;
    PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0, *rndstr = 0;
    PympzObject *man = 0, *upper = 0, *lower = 0;
    char rnd = 0;

    if (PyTuple_GET_SIZE(args) == 6) {
        /* Need better error-checking here. Under Python 3.0, overflow into
           C-long is possible. */
        sign = clong_From_Integer(PyTuple_GET_ITEM(args, 0));
        man = (PympzObject *)PyTuple_GET_ITEM(args, 1);
        exp = PyTuple_GET_ITEM(args, 2);
        bc = SI_From_Integer(PyTuple_GET_ITEM(args, 3));
        prec = SI_From_Integer(PyTuple_GET_ITEM(args, 4));
        rndstr = PyTuple_GET_ITEM(args, 5);
        if (PyErr_Occurred()) {
            TYPE_ERROR("arguments long, PympzObject*, PyObject*, long, long, char needed");
            return NULL;
        }
    }
    else {
        TYPE_ERROR("6 arguments required");
        return NULL;
    }

    if (!Pympz_Check(man)) {
        TYPE_ERROR("argument is not an mpz");
        return NULL;
    }

    /* If rndstr really is a string, extract the first character. */
    if (Py2or3String_Check(rndstr)) {
        rnd = Py2or3String_AsString(rndstr)[0];
    }
    else {
        VALUE_ERROR("invalid rounding mode specified");
        return NULL;
    }

    /* If the mantissa is 0, return the normalized representation. */
    if (!mpz_sgn(man->z)) {
        Py_INCREF((PyObject*)man);
        return mpmath_build_mpf(0, man, 0, 0);
    }

    /* if bc <= prec and the number is odd return it */
    if ((bc <= prec) && mpz_odd_p(man->z)) {
        Py_INCREF((PyObject*)man);
        Py_INCREF((PyObject*)exp);
        return mpmath_build_mpf(sign, man, exp, bc);
    }

    if (!(upper = (PympzObject*)Pympz_new()) ||
        !(lower = (PympzObject*)Pympz_new())) {
        Py_XDECREF((PyObject*)upper);
        Py_XDECREF((PyObject*)lower);
    }

    shift = bc - prec;
    if (shift>0) {
        switch (rnd) {
            case 'f':
                if(sign) {
                    mpz_cdiv_q_2exp(upper->z, man->z, shift);
                }
                else {
                    mpz_fdiv_q_2exp(upper->z, man->z, shift);
                }
                break;
            case 'c':
                if(sign) {
                    mpz_fdiv_q_2exp(upper->z, man->z, shift);
                }
                else {
                    mpz_cdiv_q_2exp(upper->z, man->z, shift);
                }
                break;
            case 'd':
                mpz_fdiv_q_2exp(upper->z, man->z, shift);
                break;
            case 'u':
                mpz_cdiv_q_2exp(upper->z, man->z, shift);
                break;
            case 'n':
            default:
                mpz_tdiv_r_2exp(lower->z, man->z, shift);
                mpz_tdiv_q_2exp(upper->z, man->z, shift);
                if (mpz_sgn(lower->z)) {
                    /* lower is not 0 so it must have at least 1 bit set */
                    if (mpz_sizeinbase(lower->z, 2) == shift) {
                        /* lower is >= 1/2 */
                        if (mpz_scan1(lower->z, 0) == shift-1) {
                            /* lower is exactly 1/2 */
                            if (mpz_odd_p(upper->z))
                                carry = 1;
                        }
                        else {
                            carry = 1;
                        }
                    }
                }
                if (carry)
                    mpz_add_ui(upper->z, upper->z, 1);
        }

        if (!(tmp = PyIntOrLong_FromSI(shift))) {
            Py_DECREF((PyObject*)upper);
            Py_DECREF((PyObject*)lower);
            return NULL;
        }

        if (!(newexp = PyNumber_Add(exp, tmp))) {
            Py_DECREF((PyObject*)upper);
            Py_DECREF((PyObject*)lower);
            Py_DECREF(tmp);
            return NULL;
        }
        Py_DECREF(tmp);
        bc = prec;
    }
    else {
        mpz_set(upper->z, man->z);
        newexp = exp;
        Py_INCREF(newexp);
    }

    /* Strip trailing 0 bits. */
    if ((zbits = mpz_scan1(upper->z, 0)))
        mpz_tdiv_q_2exp(upper->z, upper->z, zbits);

    if (!(tmp = PyIntOrLong_FromSI(zbits))) {
        Py_DECREF((PyObject*)upper);
        Py_DECREF((PyObject*)lower);
        Py_DECREF(newexp);
        return NULL;
    }
    if (!(newexp2 = PyNumber_Add(newexp, tmp))) {
        Py_DECREF((PyObject*)upper);
        Py_DECREF((PyObject*)lower);
        Py_DECREF(tmp);
        Py_DECREF(newexp);
        return NULL;
    }
    Py_DECREF(newexp);
    Py_DECREF(tmp);

    bc -= zbits;
    /* Check if one less than a power of 2 was rounded up. */
    if (!mpz_cmp_ui(upper->z, 1))
        bc = 1;

    Py_DECREF((PyObject*)lower);
    return mpmath_build_mpf(sign, upper, newexp2, bc);
}
示例#5
0
static PyObject *
Pympz_mpmath_create(PyObject *self, PyObject *args)
{
    long sign;
    mpir_si bc, shift, zbits, carry = 0, prec = 0;
    PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0;
    PympzObject *man = 0, *upper = 0, *lower = 0;

    const char *rnd = "f";

    if (PyTuple_GET_SIZE(args) < 2) {
        TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments");
        return NULL;
    }

    switch (PyTuple_GET_SIZE(args)) {
        case 4:
            rnd = Py2or3String_AsString(PyTuple_GET_ITEM(args, 3));
        case 3:
            prec = SI_From_Integer(PyTuple_GET_ITEM(args, 2));
            if (prec == -1 && PyErr_Occurred())
                return NULL;
            prec = ABS(prec);
        case 2:
            exp = PyTuple_GET_ITEM(args, 1);
        case 1:
            man = Pympz_From_Integer(PyTuple_GET_ITEM(args, 0));
            if (!man) {
                TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments");
                return NULL;
            }
    }

    /* If the mantissa is 0, return the normalized representation. */
    if (!mpz_sgn(man->z)) {
        return mpmath_build_mpf(0, man, 0, 0);
    }

    upper = (PympzObject*)Pympz_new();
    lower = (PympzObject*)Pympz_new();
    if (!upper || !lower) {
        Py_DECREF((PyObject*)man);
        Py_XDECREF((PyObject*)upper);
        Py_XDECREF((PyObject*)lower);
        return NULL;
    }

    /* Extract sign, make man positive, and set bit count */
    sign = (mpz_sgn(man->z) == -1);
    mpz_abs(upper->z, man->z);
    bc = mpz_sizeinbase(upper->z, 2);

    if (!prec) prec = bc;

    shift = bc - prec;
    if (shift > 0) {
        switch (rnd[0]) {
            case 'f':
                if(sign) {
                    mpz_cdiv_q_2exp(upper->z, upper->z, shift);
                }
                else {
                    mpz_fdiv_q_2exp(upper->z, upper->z, shift);
                }
                break;
            case 'c':
                if(sign) {
                    mpz_fdiv_q_2exp(upper->z, upper->z, shift);
                }
                else {
                    mpz_cdiv_q_2exp(upper->z, upper->z, shift);
                }
                break;
            case 'd':
                mpz_fdiv_q_2exp(upper->z, upper->z, shift);
                break;
            case 'u':
                mpz_cdiv_q_2exp(upper->z, upper->z, shift);
                break;
            case 'n':
            default:
                mpz_tdiv_r_2exp(lower->z, upper->z, shift);
                mpz_tdiv_q_2exp(upper->z, upper->z, shift);
                if (mpz_sgn(lower->z)) {
                    /* lower is not 0 so it must have at least 1 bit set */
                    if (mpz_sizeinbase(lower->z, 2)==shift) {
                        /* lower is >= 1/2 */
                        if (mpz_scan1(lower->z, 0)==shift-1) {
                            /* lower is exactly 1/2 */
                            if (mpz_odd_p(upper->z))
                                carry = 1;
                        }
                        else {
                            carry = 1;
                        }
                    }
                }
                if (carry)
                    mpz_add_ui(upper->z, upper->z, 1);
        }
        if (!(tmp = PyIntOrLong_FromSI(shift))) {
            Py_DECREF((PyObject*)upper);
            Py_DECREF((PyObject*)lower);
            return NULL;
        }
        if (!(newexp = PyNumber_Add(exp, tmp))) {
            Py_DECREF((PyObject*)man);
            Py_DECREF((PyObject*)upper);
            Py_DECREF((PyObject*)lower);
            Py_DECREF(tmp);
            return NULL;
        }
        Py_DECREF(tmp);
        bc = prec;
    }
    else {
        newexp = exp;
        Py_INCREF(newexp);
    }

    /* Strip trailing 0 bits. */
    if ((zbits = mpz_scan1(upper->z, 0)))
        mpz_tdiv_q_2exp(upper->z, upper->z, zbits);

    if (!(tmp = PyIntOrLong_FromSI(zbits))) {
        Py_DECREF((PyObject*)man);
        Py_DECREF((PyObject*)upper);
        Py_DECREF((PyObject*)lower);
        Py_DECREF(newexp);
        return NULL;
    }
    if (!(newexp2 = PyNumber_Add(newexp, tmp))) {
        Py_DECREF((PyObject*)man);
        Py_DECREF((PyObject*)upper);
        Py_DECREF((PyObject*)lower);
        Py_DECREF(tmp);
        Py_DECREF(newexp);
        return NULL;
    }
    Py_DECREF(newexp);
    Py_DECREF(tmp);

    bc -= zbits;
    /* Check if one less than a power of 2 was rounded up. */
    if (!mpz_cmp_ui(upper->z, 1))
        bc = 1;

    Py_DECREF((PyObject*)lower);
    Py_DECREF((PyObject*)man);
    return mpmath_build_mpf(sign, upper, newexp2, bc);
}
示例#6
0
int main( int argc, char * argv[] ) {

  if ( argc != 3 && argc != 4 ) {
    printf("\n");
    printf("For a^2 + b^2 = c^2 :\n");
    printf("\n");
    printf("Usage: ptriples [-p] c_min c_max\n\n\n");
    printf("Options:\n\n");
    printf("  -p -- primitive triples only\n\n");
    return 1;
  }

  int DoOnlyPrimitives = 0;
  if ( argc == 4 && strcmp( argv[1], "-p" ) == 0 )
    DoOnlyPrimitives = 1;

  mpz_t user_c_min;
  mpz_init_set_str( user_c_min,  argv[argc == 3 ? 1 : 2], 10 );

  mpz_t user_c_max;
  mpz_init_set_str( user_c_max,  argv[argc == 3 ? 2 : 3], 10 );

  if ( mpz_cmp_ui( user_c_min, 1 ) < 0 ) {
    printf("\nc_min must be >= 1.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  if ( mpz_cmp( user_c_min, user_c_max ) > 0 ) {
    printf("\nc_min must be <= c_max.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  mpz_t working_c_min;
  if ( DoOnlyPrimitives )
    mpz_init_set( working_c_min, user_c_min );
  else
    mpz_init_set_ui( working_c_min, 1 );


  // We are going to use Euclid's formula:
  // For arbitrary positive integers m and n, and m > n,
  // a = m^2 - n^2, b = 2mn, c = m^2 + n^2

  // In addition, we will restrict GCD(m,n) = 1 and m-n be
  // an odd number to guarantee that the triple is primitive.

  struct ttable triples;
  triples.count = 0;
  triples.triples = NULL;

  mpz_t a;
  mpz_init( a );
  mpz_t b;
  mpz_init( b );
  mpz_t c;
  mpz_init( c );

  mpz_t n;
  mpz_init( n );
  mpz_t m;
  mpz_init( m );

  // n can vary from 1 to no more than (c_max/2)^(1/2)
  mpz_t n_max;
  mpz_init_set( n_max, user_c_max );
  mpz_cdiv_q_2exp( n_max, n_max, 1 );
  mpz_sqrt( n_max, n_max );

  mpz_t m_min;
  mpz_init( m_min );

  mpz_t m_max;
  mpz_init( m_max );

  mpz_t n_squared;
  mpz_init( n_squared );

  mpz_t m_squared;
  mpz_init( m_squared );

  mpz_t gcd;
  mpz_init( gcd );

  mpz_t tempZ;
  mpz_init( tempZ );

  mpz_t k;
  mpz_init( k );

  mpz_t ka;
  mpz_init( ka );
  mpz_t kb;
  mpz_init( kb );
  mpz_t kc;
  mpz_init( kc );

  // iterate through n
  for ( mpz_set_ui( n, 1 );  mpz_cmp( n, n_max ) <= 0; mpz_add_ui( n, n, 1 ) ) {
    mpz_mul( n_squared, n, n );

    // compute m_min
    mpz_sub( m_min, working_c_min, n_squared );

    if ( mpz_cmp_ui( m_min, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_min, 1 );
    mpz_sqrt( m_min, m_min );
    mpz_sub_ui( m_min, m_min, 1 );  // subtract 1 just to be on the safe side

    // compute m_max
    mpz_sub( m_max, user_c_max, n_squared );
    if ( mpz_cmp_ui( m_max, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_max, 1 );
    mpz_sqrt( m_max, m_max );

    // calc first value of m
    if ( mpz_cmp( n, m_min ) < 0 ) {
      mpz_set( m, m_min );
      mpz_sub( tempZ, m, n );
      if ( mpz_divisible_ui_p( tempZ, 2 ) )
        mpz_add_ui( m, m, 1 );
    }
    else {
      mpz_set( m, n );
      mpz_add_ui( m, m, 1 );
    }

    // iterate through m
    for ( ; mpz_cmp( m, m_max ) <= 0; mpz_add_ui( m, m, 2 ) ) {

      // generate a primitive (a,b,c)
      mpz_gcd( gcd, m, n );
      if ( mpz_cmp_ui( gcd, 1 ) != 0 )
        continue;

      mpz_mul( m_squared, m, m );

      mpz_sub( a, m_squared, n_squared );

      mpz_mul( b, m, n );
      mpz_mul_ui( b, b, 2 );

      mpz_add( c, m_squared, n_squared );

      // check if primitive is outside our working range
      if ( mpz_cmp( c, working_c_min ) < 0 )
        continue;
      if ( mpz_cmp( c, user_c_max ) > 0 )
        continue;

      if ( DoOnlyPrimitives )
        AddPTriple( &triples, a, b, c );
      else {
        // iterate through k in: (k*a)^2 + (k*b)^2 = (k*c)^2
        mpz_fdiv_q( k, user_c_min, c );

        for ( mpz_mul( kc, c, k ); mpz_cmp( kc, user_c_max ) <= 0; mpz_add_ui( k, k, 1 ), mpz_mul( kc, c, k ) ) {

          if ( mpz_cmp( kc, user_c_min ) < 0 )
            continue;

          mpz_mul( ka, a, k );
          mpz_mul( kb, b, k );

          AddPTriple( &triples, ka, kb, kc );
        }
      }
    }
  }

  mpz_clear( kc );
  mpz_clear( kb );
  mpz_clear( ka );
  mpz_clear( k );

  qsort( triples.triples, triples.count, sizeof(struct tentry), ttable_entry_cmpfunc );

  // print
  long i;
  for ( i = 0; i < triples.count; i++ )
    gmp_printf("(%Zd,%Zd,%Zd)\n", triples.triples[i].a, triples.triples[i].b, triples.triples[i].c );

  mpz_clear( tempZ );
  mpz_clear( gcd );
  mpz_clear( m_squared );
  mpz_clear( n_squared );
  mpz_clear( m_max );
  mpz_clear( m_min );
  mpz_clear( n_max );
  mpz_clear( m );
  mpz_clear( n );
  mpz_clear( c );
  mpz_clear( b );
  mpz_clear( a );

  Cleanup_ttable( &triples );

  mpz_clear( working_c_min );
  mpz_clear( user_c_max );
  mpz_clear( user_c_min );

  return 0;
}
示例#7
0
文件: rw.c 项目: agl/rwb0fuz1024
int
main() {
  const int urfd = open("/dev/urandom", O_RDONLY);

  mpz_t p, q, n;

  fprintf(stderr, "Generating group...\n");
  init_random_prime(p, urfd, 512, 3);
  init_random_prime(q, urfd, 512, 7);

  print("  p:", p);
  print("  q:", q);

  mpz_init(n);
  mpz_mul(n, p, q);

  print("  n:", n);

  fprintf(stderr, "Performing extended Euclid...\n");
  mpz_t u, v;
  xgcd(u, v, p, q);
  mpz_mul(u, u, p);
  mpz_mul(v, v, q);

  print ("  u:", u);
  print ("  v:", v);

  fprintf(stderr, "Picking random element...\n");
  mpz_t e;
  random_element(e, urfd, 1024, n);
  print("  e:", e);

  fprintf(stderr, "Tweaking...\n");

  int a = is_quadratic_residue(e, p);
  int b = is_quadratic_residue(e, q);

  fprintf(stderr, "  residue state: [%d, %d]\n", a, b);

  int mul_2 = 0, negate = 0;

  if (a ^ b) {
    mul_2 = 1;
    a ^= 1;
  }

  if (!a) {
    negate = 1;
    a ^= 1;
    b ^= 1;
  }

  fprintf(stderr, "  tweaks: 2:%d -:%d\n", mul_2, negate);
  if (negate) {
    mpz_neg(e, e);
  }
  if (mul_2) {
    mpz_mul_ui(e, e, 2);
  }
  if (negate || mul_2)
    mpz_mod(e, e, n);

  print("  tweaked e:", e);

  uint8_t root;
  read(urfd, &root, 1);
  root &= 3;

  fprintf(stderr, "Calculating root %d...\n", root);

  mpz_t pp1over4, qp1over4;

  mpz_init_set(pp1over4, p);
  mpz_add_ui(pp1over4, pp1over4, 1);
  mpz_cdiv_q_2exp(pp1over4, pp1over4, 2);

  mpz_init_set(qp1over4, q);
  mpz_add_ui(qp1over4, qp1over4, 1);
  mpz_cdiv_q_2exp(qp1over4, qp1over4, 2);

  mpz_t proot, qroot;

  mpz_init_set(proot, e);
  mpz_powm(proot, e, pp1over4, p);

  mpz_init_set(qroot, e);
  mpz_powm(qroot, e, qp1over4, q);

  if (root & 1)
    mpz_neg(proot, proot);
  if (root & 2)
    mpz_neg(qroot, qroot);

  mpz_mul(proot, proot, v);
  mpz_mul(qroot, qroot, u);
  mpz_add(proot, proot, qroot);
  mpz_mod(proot, proot, n);

  print("  sig:", proot);

  fprintf(stderr, "Compressing signature...\n");

  mpz_t zsig;
  mpz_t ncopy;
  mpz_init_set(ncopy, n);
  signature_compress(zsig, proot, ncopy);

  print("  zsig:", zsig);

  mpz_t zsigcopy, t, t2;

  mpz_init(t);
  mpz_init(t2);
  mpz_init(zsigcopy);

  fprintf(stderr, "Performing 1000000 verifications\n");
  const uint64_t start_time = time_now();
  unsigned i;
  for (i = 0; i < 1000000; ++i) {
    mpz_set(zsigcopy, zsig);
    mpz_mul(zsigcopy, zsigcopy, zsigcopy);
    mpz_mul(zsigcopy, zsigcopy, e);
    mpz_mod(zsigcopy, zsigcopy, n);
    if (0 == mpz_sgn(zsigcopy))
      abort();

    mpz_sqrtrem(t, t2, zsigcopy);

    if (mpz_sgn(t2))
      abort();
  }

  const uint64_t end_time = time_now();
  fprintf(stderr, "verify time: %f\n", ((double) (end_time - start_time)) / 1000000);

  return 0;
}