Beispiel #1
0
static int VNRW_GMP_D1( const VNAsymCryptCtx_t * ctx, mpz_t zm )
{
	int mod = 0;

	VNRW_GMP_Ctx_t * gmpCtx = VN_CONTAINER_OF( ctx, VNRW_GMP_Ctx_t, mCtx );
	assert( VN_TYPE_VNRWSign_GMP == ctx->mType || VN_TYPE_VNRWEnc_GMP == ctx->mType );

	mod = mpz_fdiv_ui( zm, 4 );

	if( 0 == mod )
	{
		mpz_cdiv_q_ui( zm, zm, 4 );
		mpz_sub_ui( zm, zm, 1 );
	} else if( 1 == mod ) {
		mpz_sub( zm, gmpCtx->mN, zm );
		mpz_cdiv_q_ui( zm, zm, 4 );
		mpz_sub_ui( zm, zm, 1 );
	} else if( 2 == mod ) {
		mpz_cdiv_q_ui( zm, zm, 2 );
		mpz_sub_ui( zm, zm, 1 );
	} else if( 3 == mod ) {
		mpz_sub( zm, gmpCtx->mN, zm );
		mpz_cdiv_q_ui( zm, zm, 2 );
		mpz_sub_ui( zm, zm, 1 );
	}

	mpz_cdiv_q_ui( zm, zm, 2 );

	return 0;
}
Beispiel #2
0
static int VNRW_CalcD( VNAsymCryptCtx_t * ctx )
{
	mpz_t zp, zq;

	VNRW_GMP_Ctx_t * gmpCtx = VN_CONTAINER_OF( ctx, VNRW_GMP_Ctx_t, mCtx );
	assert( VN_TYPE_VNRWSign_GMP == ctx->mType || VN_TYPE_VNRWEnc_GMP == ctx->mType );

	mpz_init( zp );
	mpz_init( zq );

	mpz_set( zp, gmpCtx->mP );
	mpz_set( zq, gmpCtx->mQ );

	mpz_sub_ui( zp, zp, 1 );
	mpz_sub_ui( zq, zq, 1 );

	mpz_mul( gmpCtx->mD, zp, zq );
	mpz_cdiv_q_ui( gmpCtx->mD, gmpCtx->mD, 4 );
	mpz_add_ui( gmpCtx->mD, gmpCtx->mD, 1 );
	mpz_cdiv_q_ui( gmpCtx->mD, gmpCtx->mD, 2 );

	mpz_clear( zp );
	mpz_clear( zq );

	return 0;
}
Beispiel #3
0
void nchoosek_gmp(mpz_t result, mpz_t n, mpz_t k) {
	// special cases
	if(mpz_cmp_ui(k, 0) < 0) {
		mpz_set_ui(result, 0);
		return;
	}
	if(mpz_cmp(k, n) > 0) {
		mpz_set_ui(result, 0);
		return;
	}
	mpz_t c;
	mpz_init_set_ui(c, 0);
	// symmetry
	mpz_sub(c, n, k);
	if(mpz_cmp(k, c) > 0) {
		mpz_set(k, c);
	}
	mpz_cdiv_q_ui(c, n, 2);
	if(mpz_cmp(k, c) > 0) {
		mpz_sub(k, n, k);
	}

	mpz_set_ui(result, 1);
	mpz_set_ui(c, 1);
	for(; mpz_cmp(c, k) <= 0; mpz_add_ui(c, c, 1)) {
		mpz_mul(result, result, n);
		mpz_sub_ui(n, n, 1);
		mpz_tdiv_q(result, result, c);
	}
	mpz_clear(c);
}
Beispiel #4
0
int jacobi(mpz_t aa, mpz_t nn) // Generalization of Legendre's symbol.
{
	mpz_t a, n, n2;
	mpz_init_set(a, aa);
	mpz_init_set(n, nn);
	mpz_init(n2);

	if (mpz_divisible_p(a, n))
		return 0; // (0/n) = 0

	int ans = 1;
	if (mpz_cmp_ui(a, 0) < 0) {
		mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n)
		if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3
			ans = -ans; // (-1/n) = -1 if n = 3 (mod 4)
	}

	if (mpz_cmp_ui(a, 1) == 0) {
		mpz_clear(a);
		mpz_clear(n);
		mpz_clear(n2);

		return ans; // (1/n) = 1
	}

	while (mpz_cmp_ui(a, 0) != 0) {
		if (mpz_cmp_ui(a, 0) < 0) {
			mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n)
			if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3
				ans = -ans; // (-1/n) = -1 if n = 3 ( mod 4 )
		}

		while (mpz_divisible_ui_p(a, 2)) {
			mpz_divexact_ui(a, a, 2); // a = a/2
			if (mpz_congruent_ui_p(n, 3, 8) || mpz_congruent_ui_p(n, 5, 8)) // n%8==3 || n%8==5
				ans = -ans;
		}

		mpz_swap(a, n); // (a,n) = (n,a)
		if (mpz_congruent_ui_p(a, 3, 4) && mpz_congruent_ui_p(n, 3, 4)) // a%4==3 && n%4==3
			ans = -ans;

		mpz_mod(a, a, n); // because (a/p) = (a%p / p ) and a%pi = (a%n)%pi if n % pi = 0
		mpz_cdiv_q_ui(n2, n, 2);
		if (mpz_cmp(a, n2) > 0) // a > n/2
			mpz_sub(a, a, n); // a = a-n
	}

	int cmp = mpz_cmp_ui(n, 1);
	mpz_clear(a);
	mpz_clear(n);
	mpz_clear(n2);

	if (cmp == 0)
		return ans;
	return 0;
}
Beispiel #5
0
void
fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h)
{
    fmpz c1 = *g;
    fmpz c2 = *h;

    if (fmpz_is_zero(h))
    {
        printf("Exception: division by zero in fmpz_fdiv_q\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (!COEFF_IS_MPZ(c2))  /* h is also small */
        {
            fmpz q = c1 / c2;       /* compute C quotient */
            fmpz r = c1 - c2 * q;   /* compute remainder */

            if (r && (c2 ^ r) < 0L)
                --q;

            fmpz_set_si(f, q);
        }
        else                    /* h is large and g is small */
        {
            if ((c1 > 0L && fmpz_sgn(h) < 0) || (c1 < 0L && fmpz_sgn(h) > 0))  /* signs are the same */
                fmpz_set_si(f, -1L);   /* quotient is negative, round down to minus one */
            else 
                fmpz_zero(f);
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr = _fmpz_promote(f);

        if (!COEFF_IS_MPZ(c2))  /* h is small */
        {
            if (c2 > 0)         /* h > 0 */
            {
                mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_fdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2));
        }
        _fmpz_demote_val(f);    /* division by h may result in small value */
    }
}
Beispiel #6
0
void C_BigInt::divideInPlace (const uint32_t inDivisor, uint32_t & outRemainder) {
  mpz_t quotient ;
  mpz_init (quotient) ;
  if (mpz_sgn (mGMPint) >= 0) {
    outRemainder = (uint32_t) mpz_fdiv_q_ui (quotient, mGMPint, inDivisor) ;
  }else{
    outRemainder = (uint32_t) mpz_cdiv_q_ui (quotient, mGMPint, inDivisor) ;
  }
  mpz_swap (quotient, mGMPint) ;
  mpz_clear (quotient) ;
}
Beispiel #7
0
static PyObject *
GMPy_MPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    MPZ_Object *rz;

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

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

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

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("mpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(rz->z, MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(rz->z, MPZ(self), -temp);
                mpz_neg(rz->z, rz->z);
            }
        }
        else {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, other);
            mpz_fdiv_q(rz->z, MPZ(self), tempz);
            mpz_cloc(tempz);
        }
        return (PyObject*)rz;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #8
0
static PyObject *
Pyxmpz_inplace_floordiv(PyObject *a, PyObject *b)
{
    mpz_t tempz;
    mpir_si temp_si;
    int overflow;

    if (PyIntOrLong_Check(b)) {
        temp_si = PyLong_AsSIAndOverflow(b, &overflow);
        if (overflow) {
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, b);
            mpz_fdiv_q(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz);
            mpz_cloc(tempz);
        }
        else if(temp_si == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        else if(temp_si > 0) {
            mpz_fdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si);
        }
        else {
            mpz_cdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), -temp_si);
            mpz_neg(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a));
        }
        Py_INCREF(a);
        return a;
    }

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

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #9
0
int isPrime(const char *s)
{
    mpz_t maxValue;
    mpz_t iterator;
    mpz_t maxIterator;
    mpz_t remainder;
    
    mpz_init_set_str(maxValue, s, 10);
    mpz_init(remainder);
    mpz_init(iterator);
    mpz_init(maxIterator);
    mpz_cdiv_q_ui(maxIterator, maxValue, 2);
    for (mpz_set_ui(iterator, 2); mpz_cmp(iterator, maxIterator) <= 0; mpz_add_ui(iterator, iterator, 1))
    {
        mpz_cdiv_r(remainder, maxValue, iterator);
        if (mpz_cmp_ui(remainder, 0) == 0)
            return 0;
    }
    return 1;
}
void sieving_for(uint64_t index, uint64_t prime_number, uint64_t prime_number_position, smooth_number_t** smooth_array, uint64_t size_base){

  uint64_t i, bit;
  smooth_number_t* smooth;

  for( i = index; i < size_base; i = i + prime_number ){
    smooth = smooth_array[i];
    mpz_cdiv_q_ui(smooth->result, smooth->result, prime_number);

    smooth->exponents[prime_number_position]++;

    if( mpz_tstbit(smooth->exponents_mod_2, prime_number_position) ){
      mpz_clrbit(smooth->exponents_mod_2, prime_number_position);
    }
    else{
      mpz_setbit(smooth->exponents_mod_2, prime_number_position);
    }

  }

}
Beispiel #11
0
static PyObject *
GMPy_XMPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    if (PyIntOrLong_Check(other)) {
        int error;
        native_si temp = GMPy_Integer_AsNative_siAndError(other, &error);

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("xmpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(MPZ(self), MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(MPZ(self), MPZ(self), -temp);
                mpz_neg(MPZ(self), MPZ(self));
            }
        }
        else {
            mpz_set_PyIntOrLong(global.tempz, other);
            mpz_fdiv_q(MPZ(self), MPZ(self), global.tempz);
        }
        Py_INCREF(self);
        return self;
    }

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

    Py_RETURN_NOTIMPLEMENTED;
}
Beispiel #12
0
void
fmpz_cdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h)
{
    fmpz c1 = *g;
    ulong c2 = h;

    if (h == 0)
    {
        printf("Exception: division by zero in fmpz_cdiv_q_ui\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (c1 > 0)
        {
            ulong q = c1 / c2;
            ulong r = c1 - c2 * q;

            if (r)
                ++q;

            fmpz_set_ui(f, q);
        }
        else
        {
            fmpz_set_si(f, - (((ulong) -c1) / c2));
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr = _fmpz_promote(f);

        mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2);
        _fmpz_demote_val(f);    /* division by h may result in small value */
    }
}
Beispiel #13
0
int main(){
    
    int i; 
    int j;
    int sum = 0;

    
    for(i=1; i<=N; i++){
        for(j=1; j<=N; j++){

                mpz_t power;
                
                mpz_init (power);
                mpz_ui_pow_ui(power, i,j);
                //gmp_printf("%Zd ", power);
                int m = 1;
                while(mpz_cmp_ui(power, 10) > 0){
                    mpz_cdiv_q_ui(power, power, 10);
                    m++;
                    if(m>j)
                        break;
                }
                //printf("m is %d\n", m);
                if(m == j){
                    printf("%d  %d\n",i,j);
                    sum++;
                }
                mpz_clear(power);
        }
    
    }

    printf("Total is %d\n", sum);

    return 0;
}
Beispiel #14
0
int
main (int argc, char **argv)
{
  mpz_t dividend;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size;
  unsigned long divisor;
  int i;
  int reps = 10000;
  gmp_randstate_t rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  unsigned long r_rq, r_q, r_r, r;

  tests_start ();
  gmp_randinit_default(rands);

  mpz_init (bs);

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

  mpz_init (dividend);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */

      do
	{
	  mpz_rrandomb (bs, rands, 64);
	  divisor = mpz_get_ui (bs);
	}
      while (divisor == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs);
      mpz_rrandomb (dividend, rands, dividend_size);

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

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

      r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor);
      r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor);
      r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor);
      r = mpz_cdiv_ui (dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
	dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ",
		    dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ",
		    dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != (mpz_cmp_ui (dividend, 0) < 0))
	dump_abort ("quotient sign wrong", dividend, divisor);

      /* Check if the remainder has the opposite sign as the (positive) divisor
	 (quotient rounded towards minus infinity).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if (mpz_cmp_ui (remainder, 0) > 0)
	  dump_abort ("remainder sign wrong", dividend, divisor);

      mpz_mul_ui (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);

      mpz_abs (remainder, remainder);
      if (mpz_cmp_ui (remainder, divisor) >= 0)
	dump_abort ("remainder greater than divisor", dividend, divisor);

      if (mpz_cmp_ui (remainder, r_rq) != 0)
	dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_q) != 0)
	dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_r) != 0)
	dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r) != 0)
	dump_abort ("remainder returned from mpz_cdiv_ui is wrong",
		    dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);
  gmp_randclear(rands);
  tests_end ();
  exit (0);
}
Beispiel #15
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;
}
void fast_fermat_alg( mpz_t n )
{ 
    mpz_t rem, k, y, fl_y, lhs, rhs;
    int d;

    mpz_init( rem );
    mpz_init( k );
    mpz_init( y );
    mpz_init( fl_y );
    mpz_init( lhs );
    mpz_init( rhs );    
    
    /* even number check*/
    mpz_mod_ui( rem, n, 2 );
    if (mpz_cmp_ui( rem, 0) == 0)
        gmp_printf( "%Zd is even\n", n );

    /* initialise bits */
    mpz_sqrt( k, n );
    mpz_add_ui( k, k, 1 );

    mpz_pow_ui( y, k, 2 );
    mpz_sub( y, y, n );

    d = 1;

    while ( 1 )
    {
        mpz_sqrt( fl_y, y );
        mpz_pow_ui(lhs, fl_y, 2 );
        mpz_pow_ui(lhs, lhs, 2 );
        mpz_pow_ui(rhs,    y, 2 );

        if ( mpz_cmp( lhs, rhs ) == 0 )
        {
            printf( "Have found factors:\n" );
            break;            
        }
        
        mpz_mul_si( lhs, k, 2 );
        mpz_add_ui( lhs, lhs, d );
        mpz_add( y, y, lhs );
        d = d + 2;

        mpz_cdiv_q_ui( rhs, n, 2 );
        if (mpz_cmp(fl_y, rhs) > 1)
        {
            printf( "No factor found\n" );
            return;
        }
    }

    mpz_add( k, n, y );
    mpz_sqrt( lhs, k );

    mpz_sqrt( rhs, y );
        
    gmp_printf( " the non-trivial factors of %Zd are\n", n );
    
    mpz_sub( k, lhs, rhs );
    gmp_printf( "%Zd and\n", k );
    
    mpz_add( k, lhs, rhs );
    gmp_printf( "%Zd\n", k );
}
/*
Hauptfunktion
*/
int main (void) {

  // Zahl von der Konsole einlesen und in number speichern
  char *n = (char*) malloc((MAXDIGITS+1)*sizeof(char));
  size_t maxDigits = MAXDIGITS;
  printf("Bitte gib eine zu pruefende Zahl ein: ");
  getline(&n, &maxDigits, stdin);
  int ret = mpz_init_set_str(number, n, 10);

  // Speicher wieder freigeben und Fehlerpruefung
  if (n != NULL) free(n);
  if (ret < 0) {
    printf("Fehler bei der Zuweisung der eingegebenen Zahl! Abbruch.\n");
    mpz_clear(number);
    return ret;
  }

  mpz_out_str(stdout, 10, number);
  printf(" ist... ");
  // 0 und 1 sind keine Primzahlen
  // 2 und 3 sind es hingegen
  if (mpz_cmp_si(number,0) == 0 || mpz_cmp_si(number,1) == 0) {
    printf("keine Primzahl.\n");
    mpz_clear(number);
    return EXIT_SUCCESS;
  } else if (mpz_cmp_si(number,2) == 0 || mpz_cmp_si(number,3) == 0) {
    printf("eine Primzahl.\n");
    mpz_clear(number);
    return EXIT_SUCCESS;
  }

  // Gerade Zahlen koennen sofort als nicht-prim erkannt werden
  mpz_t rest;
  mpz_init(rest);
  if (mpz_mod_ui(rest, number, 2) == 0) {
    printf("keine Primzahl.\n");
    mpz_clear(number);
    mpz_clear(rest);
    return EXIT_SUCCESS;
  } else mpz_clear(rest);

  // Grenzen fuer die Kandidaten moeglicher Teiler festlegen
  mpz_t bis;
  mpz_init(bis);
  // maximaler Teiler ist sqrt(number)
  mpz_root(bis, number, 2);
  mpz_add_ui(bis, bis, 1);

  // ist die Zahl kleiner als INT_MAX, brauchen wir nur einen Thread
  // -> Test ohnehin wenig aufwendig
  // -> auch fuer sehr triviale Festlegung der Suchgrenzen notwendig/hilfreich (s.u.)
  if (mpz_cmp_ui(number, INT_MAX) < 0) ANZTHREADS = 1;

  // ein paar Vorbereitungen
  pthread_t *threads = (pthread_t*) malloc(ANZTHREADS*sizeof(pthread_t));
  anf = (mpz_t*) malloc(ANZTHREADS*sizeof(mpz_t));
  ende = (mpz_t*) malloc(ANZTHREADS*sizeof(mpz_t));
  int i = 0;
  int *nr = (int*) malloc(ANZTHREADS*sizeof(int));;

  // Threads erzeugen
  // Achtung: so klappt es nur, wenn ANZTHREADS < sqrt(number)+3
  // Hinweis: Wenn number<INT_MAX, dann gilt eh ANZTHREADS==1 (s.o.)
  for (i = 0; i < ANZTHREADS; i++) {

    // Suchgrenzen fuer die Threads festlegen
    mpz_init(anf[i]);
    mpz_init(ende[i]);
    if (i == 0) {
      mpz_add_ui(anf[i], anf[i], 3);
    } else {
      mpz_cdiv_q_ui(anf[i], bis, ANZTHREADS);
      mpz_mul_ui(anf[i], anf[i], i);
    }
    mpz_cdiv_q_ui(ende[i], bis, ANZTHREADS);
    mpz_mul_ui(ende[i], ende[i], i+1);

    // Jeder Thread fuehrt "pruefeTeiler" aus.
    // Seine Ordnungsnummer wird ihm als Parameter uebergeben
    // -> dient zum Auslesen der Suchgrenzen des jeweiligen Threads
    nr[i]=i;
    pthread_create(&(threads[i]), NULL, pruefeTeiler, &nr[i]);
  }

  // Warten bis alle Threads zurueckgekehrt sind
  for (i = 0; i < ANZTHREADS; i++) {
    pthread_join(threads[i], NULL);
  }

  // Ergebnis ausgeben
  if (found) {
    printf("keine Primzahl.\n");
  } else {
    printf("eine Primzahl.\n");
  }

  // aufraeumen
  mpz_clear(bis);
  mpz_clear(number);
  for (i = 0; i < ANZTHREADS; i++) {
    mpz_clear(anf[i]);
    mpz_clear(ende[i]);
  }
  if (threads != NULL) free(threads);
  if (anf != NULL) free(anf);
  if (ende != NULL) free(ende);
  if (nr != NULL) free(nr);

  // Ende
  return EXIT_SUCCESS;
}
Beispiel #18
0
int main (int argc, char* argv[])
{
	if(argc !=4)
	{
		printf("usage : ./craquage p r m\n");
		return EXIT_FAILURE;
	}
	
	//Initialisation des variables
	int nb_esclaves = atoi(argv[1]);
	int* tids = (int*) calloc(nb_esclaves, sizeof(int));
	int longueur_mdp = atoi(argv[2]);
	char* mdp = (char*) calloc(strlen(argv[3])+1, sizeof(char));
	strcpy(mdp, argv[3]);

	//declaration de type de tres long entiers (avec bibliotheque GMP)
	mpz_t debut_sequence, pas_reel, pas, fin_exec;
	mpz_init(debut_sequence);
	mpz_init(pas_reel);
	mpz_init(pas);
	mpz_init(fin_exec);

	//recuperation du chemin de l executable
	char* chemin = getcwd(NULL, 1000);
	strcat(chemin, "/craquage_esclave");

	//creation des arguments pour l esclave
	char *argv_esclave[3];
	argv_esclave[2]=NULL;
	argv_esclave[0] = (char*) calloc(strlen(argv[2])+1, sizeof(char));
	strcpy(argv_esclave[0],argv[2]);
	 
	argv_esclave[1] = (char*) calloc(strlen(argv[3])+1, sizeof(char));
	strcpy(argv_esclave[1],argv[3]);
	//printf("strlen %lu, %lu\n", (long unsigned)strlen(argv[2]),(long unsigned) strlen(argv[3]));
	//printf("nb_esclaves %d\n", nb_esclaves);
	
	int i;
	int trouve = 0;
	int fini = 0;
	int size;
	int nb_envoi = 0;
	int nb_pas = nb_esclaves*longueur_mdp;
	int nb_changement = 0;
	char* envoi_char;
		
	int bufid, info, bytes, type, source;
	char * solution;
	pvm_catchout(stderr);
	struct timeval tv1, tv2;
	gettimeofday(&tv1, NULL);
	pvm_spawn(chemin, argv_esclave, PvmTaskDefault,"", nb_esclaves, tids);

	//calcul du pas, fin_exec (= fin execution)
	mpz_set_ui(debut_sequence, 0);
	mpz_ui_pow_ui(fin_exec, 15, longueur_mdp+1);	
	mpz_sub_ui(fin_exec, fin_exec, 15);
	mpz_cdiv_q_ui(fin_exec, fin_exec, 14);
	
	mpz_set(pas, fin_exec);
	mpz_cdiv_q_ui(pas, pas, nb_pas);
	
	if(mpz_cmp_ui(pas, 0)==0)
	  {
	    mpz_set_ui(pas,1); 
	  }

	//gmp_printf("fin_exec: %Zd\npas:%Zd\ndebut_sequence:%Zd\n",fin_exec, pas, debut_sequence);
	
	//boucle principale
	while(!trouve && fini!=nb_esclaves)
	  {
	    //Attente de reception de donnees d un esclave
	    bufid = pvm_recv( -1, -1 );
	    info = pvm_bufinfo( bufid, &bytes, &type, &source );
	    
	    if (info < 0)
	      {
		printf("Erreur de reception : %d\n", info);
		exit(1);
	      }
	    
	    //selon le tag du message, demande de donnees ou solution trouvee
	    switch(type)
	      {
	      case(0)://mot de passe trouve
		solution = calloc(bytes, sizeof(char));
		pvm_upkstr(solution);
		printf("\nLa solution est : %s\n\n", solution);
		trouve = 1;
		break;	
		
	      case(1)://esclave veut plus de donnees
		//prendre en compte la fin des donnees dans le calcul du pas
		if(nb_changement <= 2  && nb_envoi>=(3*nb_pas/4))
		  {
		    mpz_cdiv_q_ui(pas, pas, 2);
		    nb_envoi = 0;
		    nb_pas/=2;
		    nb_changement++;
		  }
		//gmp_printf("fin_exec: %Zd pas:%Zd debut_sequence:%Zd\n",fin_exec, pas, debut_sequence);
		if(mpz_cmp(debut_sequence, fin_exec)< 0){
		  mpz_sub(pas_reel, fin_exec, debut_sequence);
		  if(mpz_cmp(pas, pas_reel)<0)
		    {
		      mpz_set(pas_reel, pas);
		    }
		 		  
		  //envoi des donnes a l esclave
		  pvm_initsend(PvmDataDefault);
		  size = gmp_asprintf(&envoi_char, "%Zd", debut_sequence);
		  pvm_pkint(&size, 1, 1);
		  pvm_pkbyte(envoi_char,size+1, 1);
		  free(envoi_char);
		 
		  size = gmp_asprintf(&envoi_char, "%Zd", pas_reel);
		  pvm_pkint(&size, 1, 1);
		  pvm_pkbyte(envoi_char,size+1 , 1);
		  free(envoi_char);
		  pvm_send(source,0);
		  
		  if(mpz_cmp(pas_reel,pas)!=0)
		    {
		      mpz_set(debut_sequence,fin_exec);
		    }
		  else
		    {
		      mpz_add(debut_sequence, debut_sequence,pas);
		    }
		  nb_envoi++;
		}
		else{
		  fini++ ;
		  printf("Pas de solution pour %d esclave(s)\n", fini);
		}		
		
		break;
		
	      default:
		break;
	      }
	  }
	// suppression des esclave
	for(i=0; i<nb_esclaves;i++)
	  {
	    info = pvm_kill(tids[i]);
	    //printf("Suppression de l esclave %d: retour de pvm_kill: %d\n",i ,info);
	  }
	
	pvm_exit();
	gettimeofday(&tv2, NULL);
	printf("%d %ld\n",longueur_mdp,(tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000); 
	
	mpz_clear(debut_sequence);
	mpz_clear(pas_reel);
	mpz_clear(pas);
	mpz_clear(fin_exec);
	free(tids);
	free(mdp);
	free(argv_esclave[0]);
	free(argv_esclave[1]);
	
	return EXIT_SUCCESS;
}