Exemple #1
0
static PyObject *
GMPy_MPZ_Function_IsEven(PyObject *self, PyObject *other)
{
    int res;
    MPZ_Object *tempx;

    if (MPZ_Check(other)) {
        res = mpz_even_p(MPZ(other));
    }
    else {
        if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) {
            TYPE_ERROR("is_even() requires 'mpz' argument");
            return NULL;
        }
        else {
            res = mpz_even_p(tempx->z);
            Py_DECREF((PyObject*)tempx);
        }
    }

    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
Exemple #2
0
/* See Cohen 1.5.3 */
int modified_cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p)
{
    int result = 0;
    mpz_t a, b, c, d;

    if (mpz_cmp_ui(p, 2) == 0) {
        mpz_add_ui(x, D, 8);
        if (mpz_perfect_square_p(x)) {
            mpz_sqrt(x, x);
            mpz_set_ui(y, 1);
            result = 1;
        }
        return result;
    }
    if (mpz_jacobi(D, p) == -1)     /* No solution */
        return 0;

    mpz_init(a);
    mpz_init(b);
    mpz_init(c);
    mpz_init(d);

    sqrtmod(x, D, p, a, b, c, d);
    if ( (mpz_even_p(D) && mpz_odd_p(x)) || (mpz_odd_p(D) && mpz_even_p(x)) )
        mpz_sub(x, p, x);

    mpz_mul_ui(a, p, 2);
    mpz_set(b, x);
    mpz_sqrt(c, p);
    mpz_mul_ui(c, c, 2);

    /* Euclidean algorithm */
    while (mpz_cmp(b, c) > 0) {
        mpz_set(d, a);
        mpz_set(a, b);
        mpz_mod(b, d, b);
    }

    mpz_mul_ui(c, p, 4);
    mpz_mul(a, b, b);
    mpz_sub(a, c, a);   /* a = 4p - b^2 */
    mpz_abs(d, D);      /* d = |D| */

    if (mpz_divisible_p(a, d)) {
        mpz_divexact(c, a, d);
        if (mpz_perfect_square_p(c)) {
            mpz_set(x, b);
            mpz_sqrt(y, c);
            result = 1;
        }
    }

    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(d);

    return result;
}
Exemple #3
0
/**
 *  Stein's binary greatest common divisor algorithm
 */
void cpt_bin_gcd(mpz_t res, mpz_srcptr a, mpz_srcptr b)
{
	mpz_t x,y,p,r;
	mpz_init(x);
	mpz_init(y);
	mpz_init(r);
	mpz_abs(x,a);
	mpz_abs(y,b);
	if(mpz_cmp_si(x,0) == 0)
	{
		mpz_set(res,y);
		mpz_clear(x);
		mpz_clear(y);
		mpz_clear(r);
		return;
	}
	if(mpz_cmp_si(y,0) == 0)
	{
		mpz_set(res,x);
		mpz_clear(x);
		mpz_clear(y);
		mpz_clear(r);
		return;
	}
	mpz_init_set_si(p,1);
	while(mpz_even_p(x) && mpz_even_p(y))
	{
		mpz_divexact_ui(x,x,2);
		mpz_divexact_ui(y,y,2);
		mpz_mul_ui(p,p,2);
	}
	while(mpz_even_p(x))
		mpz_divexact_ui(x,x,2);
	while(mpz_even_p(y))
		mpz_divexact_ui(y,y,2);
	if(mpz_cmp(x,y) > 0)
		mpz_swap(x,y);
	while(mpz_cmp_si(x,0) > 0)
	{
		mpz_sub(r,y,x);
		while(mpz_cmp_si(r,0) && mpz_even_p(r))
			mpz_divexact_ui(r,r,2);
		if(mpz_cmp(r,x) >= 0)
			mpz_set(y,r);
		else
		{
			mpz_set(y,x);
			mpz_set(x,r);
		}
	}
	mpz_mul(res,p,y);
	mpz_clear(x);
	mpz_clear(y);
	mpz_clear(p);
	mpz_clear(r);
}
Exemple #4
0
int rabin_miller(mpz_t n, unsigned int t, gmp_randstate_t rand_state) {

    mpz_t a;
    unsigned int res = PRIME, i;

    /* skrati cas */
    if (mpz_even_p(n)) return COMPOSITE;
    if (mpz_fdiv_ui(n, 3) == 0) return COMPOSITE;
    if (mpz_fdiv_ui(n, 5) == 0) return COMPOSITE;
    if (mpz_fdiv_ui(n, 7) == 0) return COMPOSITE;

    mpz_init(a);

    for (i = 0; i < t; ++i) {
        /* nahodne kladne a  */
        do {
            mpz_urandomm(a,rand_state, n);
        } while(mpz_sgn(a) == 0); /* nesmie byt 0 */
        if(rabin_miller_test(n,a) == COMPOSITE) {
            res = COMPOSITE;
            break;
        }
    }

    mpz_clear(a);

    return res;
}
Exemple #5
0
static PyObject *
GMPy_MPZ_Function_Legendre(PyObject *self, PyObject *args)
{
    MPZ_Object *tempx = NULL, *tempy = NULL;
    long res;

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

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) ||
        !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) {

        Py_XDECREF((PyObject*)tempx);
        Py_XDECREF((PyObject*)tempy);
        return NULL;
    }

    if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) {
        VALUE_ERROR("y must be odd, prime, and >0");
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return NULL;
    }

    res = (long)(mpz_legendre(tempx->z, tempy->z));
    Py_DECREF((PyObject*)tempx);
    Py_DECREF((PyObject*)tempy);
    return PyIntOrLong_FromLong(res);
}
static inline void
fib_matrix_pow (mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t term)
{
	mpz_t half_term;

	if (mpz_cmp_ui (term, 1) == 0) return;

	mpz_init (half_term);

	if (mpz_even_p (term)) {
		mpz_tdiv_q_2exp (half_term, term, 1);
		fib_matrix_pow (a, b, c, d, half_term);
		fib_matrix_square (a, b, c, d);
	} else {
		mpz_t e, f, g, h;
		mpz_init_set (e, a);
		mpz_init_set (f, b);
		mpz_init_set (g, c);
		mpz_init_set (h, d);

		mpz_sub_ui (half_term, term, 1);
		mpz_tdiv_q_2exp (half_term, half_term, 1);

		fib_matrix_pow (a, b, c, d, half_term);
		fib_matrix_square (a, b, c, d);
		fib_matrix_mul (a, b, c, d, e, f, g, h);

		mpz_clear (e);
		mpz_clear (f);
		mpz_clear (g);
		mpz_clear (h);
	}

	mpz_clear (half_term);
}
Exemple #7
0
int rabin_miller_test(mpz_t n, mpz_t a) {

    mpz_t n_minus, d, a_power;
    int j, s = 0;

    /* d(n_minus) = n - 1 */
    mpz_init(n_minus);
    mpz_sub_ui(n_minus,n,1);
    mpz_init_set(d,n_minus);

    while(mpz_even_p(d)) {
        mpz_fdiv_q_2exp(d, d, 1);
        s++;
    }

    /* a_power = a^d mod n */
    mpz_init(a_power);
    mod_exp(a,d,n,a_power);

    if(mpz_cmp_ui(a_power,1) == 0) {
        mpz_clear(n_minus);
        mpz_clear(d);
        mpz_clear(a_power);

        return PRIME;
    }

    for (j = 0; j < s - 1; ++j) {
        if(mpz_cmp(a_power,n_minus) == 0) {
            mpz_clear(n_minus);
            mpz_clear(d);
            mpz_clear(a_power);

            return PRIME;
        }

        mod_exp_ui(a_power,2,n,a_power);
        /*mpz_powm_ui (a_power, a_power, 2, n);*/
    }

    if(mpz_cmp(a_power,n_minus) == 0) {
        mpz_clear(n_minus);
        mpz_clear(d);
        mpz_clear(a_power);

        return PRIME;
    }

    mpz_clear(n_minus);
    mpz_clear(d);
    mpz_clear(a_power);

    return COMPOSITE;
}
Exemple #8
0
static PyObject *
GMPy_MPZ_Method_IsEven(PyObject *self, PyObject *other)
{
    int res;

    res = mpz_even_p(MPZ(self));

    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
Exemple #9
0
int miller_rabin_pass(mpz_t a, mpz_t n)
{
    int i, s;
    mpz_t a_to_power, d, n_minus_one;

    mpz_init(n_minus_one);
    mpz_sub_ui(n_minus_one, n, 1);

    //on calcule s et d
    s = 0;
    mpz_init_set(d, n_minus_one);
    while (mpz_even_p(d))
    {
        mpz_fdiv_q_2exp(d, d, 1);
        s++;
    }

    mpz_init(a_to_power);
    mpz_powm(a_to_power, a, d, n);
    if (mpz_cmp_ui(a_to_power, 1) == 0)
    {
        mpz_clear(a_to_power);
        mpz_clear(d);
        mpz_clear(n_minus_one);
        return 1;
    }

    for(i=0; i < s-1; i++)
    {
        if (mpz_cmp(a_to_power, n_minus_one) == 0)
        {
            mpz_clear(a_to_power);
            mpz_clear(d);
            mpz_clear(n_minus_one);
            return 1;
        }
        mpz_powm_ui (a_to_power, a_to_power, 2, n);
    }

    if (mpz_cmp(a_to_power, n_minus_one) == 0)
    {
        mpz_clear(a_to_power);
        mpz_clear(d);
        mpz_clear(n_minus_one);
        return 1;
    }
    return 0;
}
Exemple #10
0
int isprime( mpz_t n )
{
    mpz_t i, n2, tmp;
    int d, ret;

    /*  1は素数ではない */
    if( mpz_cmp_ui( n, 1 ) == 0 )
        return( 0 );

    /*  2,3は素数 */
    if( mpz_cmp_ui( n, 2 ) == 0 || mpz_cmp_ui( n, 3 ) == 0 )
        return( 1 );

    /*  2,3で割り切れたら合成数    */
    if( mpz_even_p( n ) || mpz_divisible_ui_p( n, 3 ) )
        return( 0 );

    mpz_init( i );
    mpz_init( n2 );
    mpz_init( tmp );

    /*  sqrt(n)+1を求める */
    mpz_sqrt( n2, n );

    /*  n2以下の2,3の倍数以外での剰余が0かどうか調べる   */
    d = 2;
    mpz_set_ui( i, 5 );
    ret = 1;
    while( mpz_cmp( i, n2 ) <= 0 ) {
        if( mpz_divisible_p( n, i ) ) {
            ret = 0;
            break;
        }
        mpz_add_ui( tmp, i, d );
        mpz_set( i, tmp );
        d = ( d == 2 ? 4 : 2 );
    }

    mpz_clear( i );
    mpz_clear( n2 );
    mpz_clear( tmp );

    return( ret );
}
Exemple #11
0
/**
 * Let D(x) be the divisor count of x.
 * D(t) = D(n/2))*D(n+1) if n is even.
 * D(t) = D(n)*D( (n+1)/2 ) if n odd.
 * where t is the n'th triangular number.
 */
int count_divisors_of_triangular_num(const mpz_t nth) {
	int count;
	mpz_t n1, n2;
	mpz_init(n1);
	mpz_init(n2);

	if(mpz_even_p(nth)){
		mpz_divexact_ui(n1,nth,2);
		mpz_add_ui(n2,nth,1);

	} else {
		mpz_set(n1,nth);
		mpz_add_ui(n2,nth,1);
		mpz_divexact_ui(n2,n2,2);
	}

	count = mpz_count_divisors(n1) * mpz_count_divisors(n2);
	mpz_clear(n1);
	mpz_clear(n2);
	return count;
}
int miller_rabin_pass(mpz_t a, mpz_t n) {
    int i, s, result;
    mpz_t a_to_power, d, n_minus_one;

    mpz_init(n_minus_one);
    mpz_sub_ui(n_minus_one, n, 1);

    s = 0;
    mpz_init_set(d, n_minus_one);
    while (mpz_even_p(d)) {
        mpz_fdiv_q_2exp(d, d, 1);
        s++;
    }

    mpz_init(a_to_power);
    mpz_powm(a_to_power, a, d, n);
    if (mpz_cmp_ui(a_to_power, 1) == 0)  {
        result=PROBABLE_PRIME; goto exit;
    }
    for(i=0; i < s-1; i++) {
        if (mpz_cmp(a_to_power, n_minus_one) == 0) {
            result=PROBABLE_PRIME; goto exit;
        }
        mpz_powm_ui (a_to_power, a_to_power, 2, n);
    }
    if (mpz_cmp(a_to_power, n_minus_one) == 0) {
        result=PROBABLE_PRIME; goto exit;
    }
    result = COMPOSITE;

exit:
    mpz_clear(a_to_power);
    mpz_clear(d);
    mpz_clear(n_minus_one);
    return result;
}
//------------------------------------------------------------------------------
// Name: is_even
//------------------------------------------------------------------------------
bool knumber_integer::is_even() const {
	return mpz_even_p(mpz_);
}
Exemple #14
0
int main()
{
                                        // VARIABLES DECLARATION
        //Clées Générées
    mpz_t clee_privee;      mpz_init(clee_privee);
    mpz_t clee_publique;    mpz_init(clee_publique);
    mpz_t clee_modulo;      mpz_init(clee_modulo);


        // Auto GMP + test  prima
    mpz_t __n;      mpz_init(__n);
    mpz_t __max;    mpz_init(__max);
    mpz_t __two;    mpz_init_set_ui(__two, 2);
    mpz_t __p;      mpz_init(__p);
    mpz_t __q;      mpz_init(__q);

    gmp_randstate_t __rand_state;
    gmp_randinit_default(__rand_state);
    gmp_randseed_ui (__rand_state, time(NULL));

        // Manu GMP
    mpz_t _p, _q;   mpz_init (_p); mpz_init (_q);
	mpz_t _n;       mpz_init (_n);
	mpz_t _phi;     mpz_init(_phi);
	mpz_t _e,_d;    mpz_init(_e); mpz_init(_d);
	mpz_t _temp1;    mpz_init(_temp1);
	mpz_t _temp2;   mpz_init(_temp2);

        //manu Small
	int p,q;
	int n;
	int phi;
	int e,d;

        // In / Out
    char s_temp[1000]="";
    char s_in[1000]  = "ref.txt";
    char s_out[1000] = "out.txt";
    FILE * f_in ;
    FILE * f_out;

        // Some vars
    int longeur_nombres=100;
    int clees_generees=0;
    int i,j;
 	char c = ' ';
	int menu;
	int continuer =1;
	int base_cryptage=10;
	char separator='\n';

    while (continuer ==1 )
    {
        if (clees_generees==1) {printf("\n\n\n\nLes clees ont ete generees");}
        else  {printf("\n\n\nLes clees n'ont  pas encore ete generees");}
            //Menu
        printf("\n\t-> 1: generer des cles RSA manuellement (petits nombres ; sans GMP).");
        printf("\n\t-> 2: generer des cles RSA manuellement (grands nombres ; avec GMP).");
        printf("\n\t-> 3: generer des cles RSA automatiquement (avec GMP ).");
        printf("\n\t-> 8: Entrer manuellement les clees.");
        printf("\n\t-> 9: Charger les clees a partir d'un fichier.");

        if (clees_generees==1)
        {
            printf("\n\n4: Cripter un fichier.");
            printf("\n5: Decripter un fichier.");
            printf("\n10: Enregistrer les clees dans un fichier");
        }
        printf("\n\n6: Test de primalite ( Miller Rabin ).");
        printf("\n\n0: Quitter.");

        printf("\n\nChoix : ");
        scanf("%d",&menu);

		switch (menu)
		{
			case 0: // quiter
				continuer=0;
			break;

			case 1: // setup RSA
				printf("\nEntrez deux nombres premiers p et q, : \n"); // On entre deux nbres premiers p, q
				do { printf("\tp = ");           scanf("%d",&p); } while( premier(p)!= 1 );
				do { printf("\tp = %d, q = ",p); scanf("%d",&q); } while( q==p || premier(q)!= 1 );

				n = p*q;		    // on calcul la première partie de la clé publique
				phi=(p-1)*(q-1);	// on calcule l'indicatrice d'euler de n

				printf("\tphi(%d) = %d\n",n,phi);
				printf("\nEntrez un nombre e, tel que Pgcd(%d,e) = 0 :\n",phi);
				do { printf("\te = "); scanf("%d",&e);printf("\n"); d= inverseModulo(e,phi); } while( d==0 );
				printf("\n\td = %d , car (%d * %d = 1 mod %d )\n",d,d,e,phi);

                while (d<0) {d+=n;}
				printf("\n\tCle Publique : { %d, %d }",e,n);
				printf("\n\tCle Privee   : { %d, %d }\n\n",d,n);

				mpz_set_ui(clee_privee,d);
				mpz_set_ui(clee_publique,e);
				mpz_set_ui(clee_modulo,n);
				clees_generees=1;
			break;

			case 2: // setup RSA
				printf("\nEntrez deux nombres premiers p et q, : \n"); // On entre deux nbres premiers p, q
				do { printf("\tp = ");                gmp_scanf("%Zd",_p);  } while( mpz_premier(_p)!= 1 );
				do { gmp_printf("\tp = %Zd, q = ",_p); gmp_scanf("%Zd",_q); } while( mpz_cmp(_q,_p)==0 || mpz_premier(_q)!= 1 );

				mpz_mul(_n,_p,_q);              // on calcul la première partie de la clé publique

				mpz_sub_ui(_temp1,_p,1);
				mpz_sub_ui(_temp2,_q,1);
				mpz_mul(_phi,_temp1,_temp2);    // on calcule l'indicatrice d'euler de n

				gmp_printf("\tphi(%Zd) = %Zd\n",_n,_phi);
				gmp_printf("\nEntrez un nombre e, tel que Pgcd(%Zd,e) = 0 :\n",_phi);
                do { printf("\te = "); gmp_scanf("%Zd",_e);printf("\n"); mpz_inverseModulo(&_d,_e,_phi); } while( mpz_cmp_ui(_d,0)==0 );

				gmp_printf("%Zd",_e);
				gmp_printf("%Zd",_phi);

				gmp_printf("\n\td = %Zd , car (%Zd * %Zd = 1 mod %Zd )\n",_d,_d,_e,_phi);

				gmp_printf("\n\tCle Publique : { %Zd, %Zd }",_e,_n);
				gmp_printf("\n\tCle Privee   : { %Zd, %Zd }\n\n",_d,_n);

                mpz_set(clee_privee,_d);
				mpz_set(clee_publique,_e);
				mpz_set(clee_modulo,_n);
				clees_generees=1;
			break;

            case 8:
                printf("\n\n\t  * ENTREZ LES CLEES *\n");
                printf("\n\tClee publique = "); gmp_scanf("%Zd",clee_publique);
                printf("\tClee privee = ");   gmp_scanf("%Zd",clee_privee);
                printf("\tClee Modulo = ");   gmp_scanf("%Zd",clee_modulo);
                printf("\n\n");
                clees_generees=1;

			break;

            case 9: // Charger les clees a partir d'un fichier
                {
                    j=0;
                    do
                    {
                        printf("\n\n\t\t * CHARGER *\n( clee publique / privee / modulo)\n ");

                        printf("\n\t1 : Input  : %s",s_in);
                        printf("\n\t2 : separateur input  : ");
                            if (separator == '\n'){printf("retour a la ligne");}
                            if (separator == '\t'){printf("tabulation");}
                            if (separator == ' '){printf("espace");}
                        printf("\n\n\t0 : Charger !!! :");

                        scanf("%d",&menu);
                        if (menu == 1) {printf("\n\tnouveau fichier : "); scanf("%s",s_in);}
                        if (menu == 2)
                        {
                                printf("\n\tnouveau caractere de separation :");
                                printf("\n\t\t1 : retour a la ligne");
                                printf("\n\t\t2 : tabulation ");
                                printf("\n\t\t3 : espace ");
                                printf("\n\n\t\t0 : annuler ");
                                scanf("%d",&menu);
                                if (menu==1) { separator='\n';}
                                if (menu==2) { separator='\t';}
                                if (menu==3) { separator=' ';}
                        }

                    }while (menu!=0);

                    f_in = fopen(s_in,"r");

                    c = '0';
                    while(c != EOF)
                        {
                            i=0;
                            c = '0';
                            while(c != EOF && c!= separator)
                            {
                                c = fgetc(f_in);
                                if (c != EOF && c!= separator)
                                {
                                    s_temp[i]=c;
                                    i++;
                                }
                            }
                            if (c!=EOF)
                            {
                                s_temp[i]='\0';
                                if (j==0) {mpz_set_str(clee_publique,s_temp,10); }
                                if (j==1) {mpz_set_str(clee_privee  ,s_temp,10); }
                                if (j==2) {mpz_set_str(clee_modulo  ,s_temp,10); }
                                j++;
                            }
                        }

                    fclose(f_in);
                    printf("\nappuyez sur une touche pour continuer");
                    clees_generees=1;
                    getchar(); getchar();
                    j=0;
                }

			break;


			case 3: // auto crypte rabin
                mpz_mul_2exp(__max, __two, longeur_nombres );
                printf("\nGeneration de 2 nombres premiers p et q, : \n");
                do
                {
                    mpz_urandomm(__p, __rand_state, __max);

                    // a remplacer par une boucle propre sur les 100 plus petits premiers par exemple
                    if (mpz_even_p(__p)) continue;
                    if (mpz_fdiv_ui(__p, 3) == 0) continue;
                    if (mpz_fdiv_ui(__p, 5) == 0) continue;
                    if (mpz_fdiv_ui(__p, 7) == 0) continue;
                } while (miller_rabin(__p, __rand_state, 100) == 0);
                do
                {
                    mpz_urandomm(__q, __rand_state, __max);

                    // a remplacer par une boucle propre sur les 100 plus petits premiers par exemple
                    if (mpz_even_p(__q)) continue;
                    if (mpz_fdiv_ui(__q, 3) == 0) continue;
                    if (mpz_fdiv_ui(__q, 5) == 0) continue;
                    if (mpz_fdiv_ui(__q, 7) == 0) continue;
                } while (miller_rabin(__q, __rand_state, 100) == 0);
                do
                {
                    mpz_urandomm(_e, __rand_state, __max);

                    // a remplacer par une boucle propre sur les 100 plus petits premiers par exemple
                    if (mpz_even_p(_e)) continue;
                    if (mpz_fdiv_ui(_e, 3) == 0) continue;
                    if (mpz_fdiv_ui(_e, 5) == 0) continue;
                    if (mpz_fdiv_ui(_e, 7) == 0) continue;
                } while (miller_rabin(_e, __rand_state, 100) == 0);
                gmp_printf("\n\tp = %Zd,\n\n\tq = %Zd",__p,__q);

                mpz_mul(_n,__p,__q);            // on calcul la première partie de la clé publique
				mpz_sub_ui(_temp1,__p,1);
				mpz_sub_ui(_temp2,__q,1);
				mpz_mul(_phi,_temp1,_temp2);    // on calcule l'indicatrice d'euler de n

				gmp_printf("\n\n\tphi(%Zd) \n\t= %Zd\n",_n,_phi);
				mpz_inverseModulo(&_d,_e,_phi);

				gmp_printf("\n\tCle Publique : \n\t{ %Zd,\n\t%Zd }",_e,_n);
				gmp_printf("\n\n\tCle Privee   : \n\t{ %Zd,\n\t%Zd }\n\n",_d,_n);

                mpz_set(clee_privee,_d);
				mpz_set(clee_publique,_e);
				mpz_set(clee_modulo,_n);
				clees_generees=1;
            break;

            case 4: // crypte
                if (clees_generees==1)
                {
                    do
                    {
                        printf("\n\n\t * CRYPTAGE *\n");

                        printf("\n\t1 : Input  : %s",s_in);
                        printf("\n\t2 : Output : %s",s_out);
                        printf("\n\t3 : Base   : %d",base_cryptage);
                        printf("\n\t4 : separateur : ");
                            if (separator == '\n'){printf("retour a la ligne");}
                            if (separator == '\t'){printf("tabulation");}
                            if (separator == ' '){printf("espace");}
                        printf("\n\n\t0 : CRYPTER !!! :");

                        scanf("%d",&menu);
                        if (menu == 1) {printf("\n\tnouveau fichier : "); scanf("%s",s_in);}
                        if (menu == 2) {printf("\n\tnouveau fichier : "); scanf("%s",s_out);}
                        if (menu == 3) {printf("\n\tnouvelle base ( entre 2 et 36) : "); scanf("%d",&base_cryptage);
                                        if (base_cryptage<2 || base_cryptage>36) {base_cryptage=10;}}
                        if (menu == 4)
                        {
                                printf("\n\tnouveau caractere de separation :");
                                printf("\n\t\t1 : retour a la ligne");
                                printf("\n\t\t2 : tabulation ");
                                printf("\n\t\t3 : espace ");
                                printf("\n\n\t\t0 : annuler ");
                                scanf("%d",&menu);
                                if (menu==1) { separator='\n';}
                                if (menu==2) { separator='\t';}
                                if (menu==3) { separator=' ';}
                        }
                    }while (menu!=0);

                    f_in = fopen(s_in,"r");
                    f_out = fopen(s_out,"w+");

                    c = ' ';
                    while(c != EOF)
                    {
                        c = fgetc(f_in);
                        if (c!=EOF)
                        {
                            mpz_set_ui(_temp1,(unsigned int)c);
                            mpz_powm(_temp1,_temp1,clee_publique,clee_modulo);
                            mpz_out_str (f_out, base_cryptage, _temp1 );
                            fputc(separator,f_out);
                        }
                    }

                    fclose(f_in);
                    fclose(f_out);
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
                else
                {
                    printf("\nVous devez d'abord generer un set de Clees");
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
			break;

			case 5: // Décrypte
                if (clees_generees==1)
                {
                    do
                    {
                        printf("\n\n\t * DECRYPTAGE *\n");

                        printf("\n\t1 : Input  : %s",s_in);
                        printf("\n\t2 : Output : %s",s_out);
                        printf("\n\t3 : Base   : %d",base_cryptage);
                        printf("\n\t4 : separateur input  : ");
                            if (separator == '\n'){printf("retour a la ligne");}
                            if (separator == '\t'){printf("tabulation");}
                            if (separator == ' '){printf("espace");}
                        printf("\n\n\t0 : DECRYPTER !!! :");

                        scanf("%d",&menu);
                        if (menu == 1) {printf("\n\tnouveau fichier : "); scanf("%s",s_in);}
                        if (menu == 2) {printf("\n\tnouveau fichier : "); scanf("%s",s_out);}
                        if (menu == 3) {printf("\n\tnouvelle base ( entre 2 et 36) : "); scanf("%d",&base_cryptage);
                                        if (base_cryptage<2 || base_cryptage>36) {base_cryptage=10;}}
                        if (menu == 4)
                        {
                                printf("\n\tnouveau caractere de separation :");
                                printf("\n\t\t1 : retour a la ligne");
                                printf("\n\t\t2 : tabulation ");
                                printf("\n\t\t3 : espace ");
                                printf("\n\n\t\t0 : annuler ");
                                scanf("%d",&menu);
                                if (menu==1) { separator='\n';}
                                if (menu==2) { separator='\t';}
                                if (menu==3) { separator=' ';}
                        }

                    }while (menu!=0);

                    f_in = fopen(s_in,"r");
                    f_out = fopen(s_out,"w+");

                    c = '0';
                    while(c != EOF)
                        {
                            i=0;
                            c = '0';
                            while(c != EOF && c!= separator)
                            {
                                c = fgetc(f_in);
                                if (c != EOF && c!= separator)
                                {
                                    s_temp[i]=c;
                                    i++;
                                }
                            }
                            if (c!=EOF)
                            {
                                s_temp[i]='\0';
                                mpz_set_str(_temp1,s_temp,base_cryptage);
                                mpz_powm(_temp1,_temp1,clee_privee,clee_modulo);
                                fputc((char)(mpz_get_ui(_temp1)),f_out);
                            }
                        }

                    fclose(f_in);
                    fclose(f_out);
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
                else
                {
                    printf("\nVous devez d'abord generer un set de Clees");
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
			break;

			case 10: // enregistre les clees
                if (clees_generees==1)
                {
                    do
                    {
                        printf("\n\n\t * SAUVER  *\n");

                        printf("\n\t1 : Output : %s",s_out);
                        printf("\n\t2 : separateur : ");
                            if (separator == '\n'){printf("retour a la ligne");}
                            if (separator == '\t'){printf("tabulation");}
                            if (separator == ' '){printf("espace");}
                        printf("\n\n\t0 : CRYPTER !!! :");

                        scanf("%d",&menu);
                        if (menu == 1) {printf("\n\tnouveau fichier : "); scanf("%s",s_out);}
                        if (menu == 2)
                        {
                                printf("\n\tnouveau caractere de separation :");
                                printf("\n\t\t1 : retour a la ligne");
                                printf("\n\t\t2 : tabulation ");
                                printf("\n\t\t3 : espace ");
                                printf("\n\n\t\t0 : annuler ");
                                scanf("%d",&menu);
                                if (menu==1) { separator='\n';}
                                if (menu==2) { separator='\t';}
                                if (menu==3) { separator=' ';}
                        }
                    }while (menu!=0);

                    f_out = fopen(s_out,"w+");

                    mpz_out_str (f_out, 10, clee_publique );
                    fputc(separator,f_out);

                    mpz_out_str (f_out, 10, clee_privee );
                    putc(separator,f_out);

                    mpz_out_str (f_out, 10, clee_modulo );
                    fputc(separator,f_out);

                    fclose(f_out);
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
                else
                {
                    printf("\nVous devez d'abord generer un set de Clees");
                    printf("\nappuyez sur une touche pour continuer");
                    getchar(); getchar();
                }
			break;

            case 6: // Test de primalité
                printf("Entrez un nombre, et nous vous dirrons s'il est premier ou pas :\n\t n = ");
                gmp_scanf("%Zd",__n);
                if (miller_rabin(__n, __rand_state, 100) == 1)
                        { printf("\n PROBABLEMENT, ce nombre est probablement premier ."); }
                else    { printf("\n NON, ce nombre n'est pas premier !"); }
			break;
			default : printf("  -> Choix non reconnu !"); break;
		}
    }

	return 0;
}
Exemple #15
0
int
mpz_probab_prime_p (mpz_srcptr n, int reps)
{
  mp_limb_t r;
  mpz_t n2;

  /* Handle small and negative n.  */
  if (mpz_cmp_ui (n, 1000000L) <= 0)
    {
      if (mpz_cmpabs_ui (n, 1000000L) <= 0)
	{
	  int is_prime;
	  unsigned long n0;
	  n0 = mpz_get_ui (n);
	  is_prime = n0 & (n0 > 1) ? isprime (n0) : n0 == 2;
	  return is_prime ? 2 : 0;
	}
      /* Negative number.  Negate and fall out.  */
      PTR(n2) = PTR(n);
      SIZ(n2) = -SIZ(n);
      n = n2;
    }

  /* If n is now even, it is not a prime.  */
  if (mpz_even_p (n))
    return 0;

#if defined (PP)
  /* Check if n has small factors.  */
#if defined (PP_INVERTED)
  r = MPN_MOD_OR_PREINV_MOD_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP,
			       (mp_limb_t) PP_INVERTED);
#else
  r = mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP);
#endif
  if (r % 3 == 0
#if GMP_LIMB_BITS >= 4
      || r % 5 == 0
#endif
#if GMP_LIMB_BITS >= 8
      || r % 7 == 0
#endif
#if GMP_LIMB_BITS >= 16
      || r % 11 == 0 || r % 13 == 0
#endif
#if GMP_LIMB_BITS >= 32
      || r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0
#endif
#if GMP_LIMB_BITS >= 64
      || r % 31 == 0 || r % 37 == 0 || r % 41 == 0 || r % 43 == 0
      || r % 47 == 0 || r % 53 == 0
#endif
      )
    {
      return 0;
    }
#endif /* PP */

  /* Do more dividing.  We collect small primes, using umul_ppmm, until we
     overflow a single limb.  We divide our number by the small primes product,
     and look for factors in the remainder.  */
  {
    unsigned long int ln2;
    unsigned long int q;
    mp_limb_t p1, p0, p;
    unsigned int primes[15];
    int nprimes;

    nprimes = 0;
    p = 1;
    ln2 = mpz_sizeinbase (n, 2);	/* FIXME: tune this limit */
    for (q = PP_FIRST_OMITTED; q < ln2; q += 2)
      {
	if (isprime (q))
	  {
	    umul_ppmm (p1, p0, p, q);
	    if (p1 != 0)
	      {
		r = MPN_MOD_OR_MODEXACT_1_ODD (PTR(n), (mp_size_t) SIZ(n), p);
		while (--nprimes >= 0)
		  if (r % primes[nprimes] == 0)
		    {
		      ASSERT_ALWAYS (mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) primes[nprimes]) == 0);
		      return 0;
		    }
		p = q;
		nprimes = 0;
	      }
	    else
	      {
		p = p0;
	      }
	    primes[nprimes++] = q;
	  }
      }
  }

  /* Perform a number of Miller-Rabin tests.  */
  return mpz_millerrabin (n, reps);
}
Exemple #16
0
int chpl_mpz_even_p(const mpz_t op) {
  return mpz_even_p(op);
}
void mpz_sqrtmp_r
	(mpz_ptr root, mpz_srcptr a, mpz_srcptr p)
{
	/* ? a \neq 0 */
	if (mpz_get_ui(a) != 0)
	{
		/* ? p = 3 (mod 4) */
		if (mpz_congruent_ui_p(p, 3L, 4L))
		{
			mpz_t foo;
			mpz_init_set(foo, p);
			mpz_add_ui(foo, foo, 1L);
			mpz_fdiv_q_2exp(foo, foo, 2L);
			mpz_powm(root, a, foo, p);
			mpz_clear(foo);
			return;
		}
		/* ! p = 1 (mod 4) */
		else
		{
			/* ! s = (p-1)/4 */
			mpz_t s;
			mpz_init_set(s, p);
			mpz_sub_ui(s, s, 1L);
			mpz_fdiv_q_2exp(s, s, 2L);
			/* ? p = 5 (mod 8) */
			if (mpz_congruent_ui_p(p, 5L, 8L))
			{
				mpz_t foo, b;
				mpz_init(foo);
				mpz_powm(foo, a, s, p);
				mpz_init_set(b, p);
				mpz_add_ui(b, b, 3L);
				mpz_fdiv_q_2exp(b, b, 3L);
				mpz_powm(root, a, b, p);
				/* ? a^{(p-1)/4} = 1 (mod p) */
				if (mpz_cmp_ui(foo, 1L) == 0)
				{
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
				/* ! a^{(p-1)/4} = -1 (mod p) */
				else
				{
					do
						mpz_wrandomm(b, p);
					while (mpz_jacobi(b, p) != -1);
					mpz_powm(b, b, s, p);
					mpz_mul(root, root, b);
					mpz_mod(root, root, p);
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
			}
			/* ! p = 1 (mod 8) */
			else
			{
				mpz_t foo, bar, b, t;
				mpz_init(foo), mpz_init(bar);
				mpz_powm(foo, a, s, p);
				/* while a^s = 1 (mod p) */
				while (mpz_cmp_ui(foo, 1L) == 0)
				{
					/* ? s odd */
					if (mpz_odd_p(s))
					{
						mpz_add_ui(s, s, 1L);
						mpz_fdiv_q_2exp(s, s, 1L);
						mpz_powm(root, a, s, p);
						mpz_clear(foo), mpz_clear(s);
						return;
					}
					/* ! s even */
					else
					{
						mpz_fdiv_q_2exp(s, s, 1L);
					}
					mpz_powm(foo, a, s, p);
				}
				/* ! a^s = -1 (mod p) */
				mpz_init(b);
				do
					mpz_wrandomm(b, p);
				while (mpz_jacobi(b, p) != -1);
				mpz_init_set(t, p);
				mpz_sub_ui(t, t, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				/* while s even */
				while (mpz_even_p(s))
				{
					mpz_fdiv_q_2exp(s, s, 1L);
					mpz_fdiv_q_2exp(t, t, 1L);
					mpz_powm(foo, a, s, p);
					mpz_powm(bar, b, t, p);
					mpz_mul(foo, foo, bar);
					mpz_mod(foo, foo, p);
					mpz_set_si(bar, -1L);
					/* ? a^s * b^t = -1 (mod p) */
					if (mpz_congruent_p(foo, bar, p))
					{
						mpz_set(bar, p);
						mpz_sub_ui(bar, bar, 1L);
						mpz_fdiv_q_2exp(bar, bar, 1L);
						mpz_add(t, t, bar);
					}
				}
				mpz_add_ui(s, s, 1L);
				mpz_fdiv_q_2exp(s, s, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				mpz_powm(foo, a, s, p);
				mpz_powm(bar, b, t, p);
				mpz_mul(root, foo, bar);
				mpz_mod(root, root, p);
				mpz_clear(foo), mpz_clear(bar);
				mpz_clear(s), mpz_clear(b), mpz_clear(t);
				return;
			}
		}
	}
	/* error, return zero root */
	mpz_set_ui(root, 0L);
}
Exemple #18
0
int ecpp_test(unsigned long n)
{
  mpz_t a, b,
        x0, y0,
        xt, yt,
        tmp;
  int z;
  int is_prime = 0;

  if (n <= USHRT_MAX)
  {
    return sieve_test(n);
  }

  mpz_init(a);
  mpz_init(b);
  mpz_init(x0);
  mpz_init(y0);
  mpz_init(xt);
  mpz_init(yt);
  mpz_init(tmp);

#ifdef DEBUG
  gmp_fprintf(stderr, "\nTesting %d with ECPP...\n", n);
#endif /* DEBUG */

  for (;;) /* keep trying while the curve order factoring fails */
  {
    for (;;) /* keep trying while n divides curve discriminant */
    {
      /* initialise a random point P = (x0, y0)
       * and a random elliptic curve E(a, b): y^2 = x^3 + a*x + b
       * with b expressed in terms of (a, x0, y0) so the point lies on the curve
       */

      mpz_set_ui(a, rand() % n);
      mpz_set_ui(x0, rand() % n);
      mpz_set_ui(y0, rand() % n);
      mpz_init(b);

      mpz_mul(b, y0, y0);
      mpz_mul(tmp, x0, x0);
      mpz_submul(b, tmp, x0);
      mpz_submul(b, a, x0);
      mpz_mod_ui(b, b, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\n\tn = %d\n", n);
      gmp_fprintf(stderr, "\tE: y^2 = x^3 + %Zd * x + %Zd\n", a, b);
      gmp_fprintf(stderr, "\tP = (%Zd,%Zd,1)\n", x0, y0);
#endif /* DEBUG */

      /* the discriminant of the curve and n are required to be coprimes
       * -- if not, then either
       *   A) n divides the discriminant -- a new curve must be generated
       *   B) n is composite and a proper factor is found -- the algorithm can
       *      terminate
       */

      ec_discriminant(tmp, a, b);

#ifdef DEBUG
      mpz_mod_ui(tmp, tmp, n);
      gmp_fprintf(stderr, "\tdelta(E/GF(n)) = %Zd\n", tmp);
#endif /* DEBUG */

      mpz_gcd_ui(tmp, tmp, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\tgcd(delta, n) = %Zd\n", tmp);
#endif /* DEBUG */

      if (0 == mpz_cmp_ui(tmp, 1))
      {
        break;
      }
      else if (0 != mpz_cmp_ui(tmp, n))
      {
#ifdef DEBUG
        gmp_fprintf(stderr, "\tfound a proper factor, %d is composite\n", n);
#endif /* DEBUG */
        is_prime = 0;
        goto cleanup_and_return;
      }
    }

    /* P + P != 0, or a new curve is generated
     */
    z = ec_add(xt, yt, x0, y0, 1, x0, y0, 1, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t2 * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 == z)
    {
      continue;
    }

    /* the curve order algorithm failing indicates n is composite
     */
    if (!(ec_order(tmp, a, b, n)))
    {
#ifdef DEBUG
      gmp_fprintf(stderr,
          "\tcurve order algorithm failed, %d must be composite\n", n);
#endif /* DEBUG */

      is_prime = 0;
      break;
    }

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E/GF(n)| = %Zd\n", tmp);
#endif /* DEBUG */

    /* the curve order should be the multiple of 2 and a "probable prime" n --
     * if the order is not even, a new curve is generated
     */
    if (!mpz_even_p(tmp))
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E/GF(n)| is odd, generating new curve...\n");
#endif /* DEBUG */
      continue;
    }

    /* order * P = 0, or n is composite
     */
    z = ec_times(xt, yt, x0, y0, 1, tmp, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E| * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 != z)
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E| * P is non-zero, %d is composite\n", n);
#endif /* DEBUG */
      is_prime = 0;
      break;
    }

    /* at this point, order/2 being a prime implies n is a prime --
     * a recursive call to ecpp_test is used to test order/2 for primality
     */
    mpz_div_ui(tmp, tmp, 2);
    if (ecpp_test(mpz_get_ui(tmp)))
    {
      is_prime = 1;
      break;
    }
  }

cleanup_and_return:
  mpz_clear(a);
  mpz_clear(b);
  mpz_clear(x0);
  mpz_clear(y0);
  mpz_clear(xt);
  mpz_clear(yt);
  mpz_clear(tmp);

  return is_prime;
}
Exemple #19
0
bool
is_even<mpz_class>(const mpz_class &x)
{
	return mpz_even_p(x.get_mpz_t());
}
int check_specialcase(FILE *sieve_log, fact_obj_t *fobj)
{
	//check for some special cases of input number
	//sieve_log is passed in already open, and should return open
	if (mpz_even_p(fobj->qs_obj.gmp_n))
	{
		printf("input must be odd\n");
		return 1;
	}

	if (mpz_probab_prime_p(fobj->qs_obj.gmp_n, NUM_WITNESSES))
	{
		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n", gmp_base10(fobj->qs_obj.gmp_n), 
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));
		mpz_set_ui(fobj->qs_obj.gmp_n,1);
		return 1;
	}

	if (mpz_perfect_square_p(fobj->qs_obj.gmp_n))
	{
		mpz_sqrt(fobj->qs_obj.gmp_n,fobj->qs_obj.gmp_n);

		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->qs_obj.gmp_n), 
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));
		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->qs_obj.gmp_n),
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));

		mpz_set_ui(fobj->qs_obj.gmp_n,1);
		return 1;
	}

	if (mpz_perfect_power_p(fobj->qs_obj.gmp_n))
	{
		if (VFLAG > 0)
			printf("input is a perfect power\n");
		
		factor_perfect_power(fobj, fobj->qs_obj.gmp_n);

		if (sieve_log != NULL)
		{
			uint32 j;
			logprint(sieve_log,"input is a perfect power\n");

			for (j=0; j<fobj->num_factors; j++)
			{
				uint32 k;
				for (k=0; k<fobj->fobj_factors[j].count; k++)
				{
					logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->fobj_factors[j].factor), 
						mpz_conv2str(&gstr1.s, 10, fobj->fobj_factors[j].factor));
				}
			}
		}
		return 1;
	}

	if (mpz_sizeinbase(fobj->qs_obj.gmp_n,2) < 115)
	{
		//run MPQS, as SIQS doesn't work for smaller inputs
		//MPQS will take over the log file, so close it now.
		int i;

		// we've verified that the input is not odd or prime.  also
		// do some very quick trial division before calling smallmpqs, which
		// does none of these things.
		for (i=1; i<25; i++)
		{
			if (mpz_tdiv_ui(fobj->qs_obj.gmp_n, spSOEprimes[i]) == 0)
				mpz_tdiv_q_ui(fobj->qs_obj.gmp_n, fobj->qs_obj.gmp_n, spSOEprimes[i]);
		}

		smallmpqs(fobj);
		return 1;	//tells SIQS to not try to close the logfile
	}

	if (gmp_base10(fobj->qs_obj.gmp_n) > 140)
	{
		printf("input too big for SIQS\n");
		return 1;
	}

	return 0;
}
Exemple #21
0
void zFermat(uint64 limit, uint32 mult, fact_obj_t *fobj)
{
	// Fermat's factorization method with a sieve-based improvement
	// provided by 'neonsignal'
	mpz_t a, b2, tmp, multN, a2;
	int i;
	int numChars;
	uint64 reportIt, reportInc;
	uint64 count;
	uint64 i64;
	FILE *flog = NULL;
	uint32 M = 2 * 2 * 2 * 2 * 3 * 3 * 5 * 5 * 7 * 7; //176400u
	uint32 M1 = 11 * 17 * 23 * 31; //133331u
	uint32 M2 = 13 * 19 * 29 * 37; //265031u
	uint8 *sqr, *sqr1, *sqr2, *mod, *mod1, *mod2;
	uint16 *skip;
	uint32 m, mmn, s, d;
	uint8 masks[8] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
	uint8 nmasks[8];
	uint32 iM = 0, iM1 = 0, iM2 = 0;

	if (mpz_even_p(fobj->div_obj.gmp_n))
	{
		mpz_init(tmp);
		mpz_set_ui(tmp, 2);
		mpz_tdiv_q_2exp(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, 1);
		add_to_factor_list(fobj, tmp);
		mpz_clear(tmp);
		return;
	}

	if (mpz_perfect_square_p(fobj->div_obj.gmp_n))
	{
		//open the log file
		flog = fopen(fobj->flogname,"a");
		if (flog == NULL)
		{
			printf("fopen error: %s\n", strerror(errno));
			printf("could not open %s for writing\n",fobj->flogname);
			return;
		}

		mpz_sqrt(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n);
		if (is_mpz_prp(fobj->div_obj.gmp_n))
		{			
			logprint(flog, "Fermat method found perfect square factorization:\n");
			logprint(flog,"prp%d = %s\n",
				gmp_base10(fobj->div_obj.gmp_n),
				mpz_conv2str(&gstr1.s, 10, fobj->div_obj.gmp_n));
			logprint(flog,"prp%d = %s\n",
				gmp_base10(fobj->div_obj.gmp_n),
				mpz_conv2str(&gstr1.s, 10, fobj->div_obj.gmp_n));
		}
		else
		{
			logprint(flog, "Fermat method found perfect square factorization:\n");
			logprint(flog,"c%d = %s\n",
				gmp_base10(fobj->div_obj.gmp_n),
				mpz_conv2str(&gstr1.s, 10, fobj->div_obj.gmp_n));
			logprint(flog,"c%d = %s\n",
				gmp_base10(fobj->div_obj.gmp_n),
				mpz_conv2str(&gstr1.s, 10, fobj->div_obj.gmp_n));
		}
		add_to_factor_list(fobj, fobj->div_obj.gmp_n);
		add_to_factor_list(fobj, fobj->div_obj.gmp_n);
		mpz_set_ui(fobj->div_obj.gmp_n, 1);
		fclose(flog);
		return;
	}

	mpz_init(a);
	mpz_init(b2);
	mpz_init(tmp);
	mpz_init(multN);
	mpz_init(a2);

	// apply the user supplied multiplier
	mpz_mul_ui(multN, fobj->div_obj.gmp_n, mult);
	
	// compute ceil(sqrt(multN))
	mpz_sqrt(a, multN);

	// form b^2
	mpz_mul(b2, a, a);
	mpz_sub(b2, b2, multN);

	// test successive 'a' values using a sieve-based approach.
	// the idea is that not all 'a' values allow a^2 or b^2 to be square.  
	// we pre-compute allowable 'a' values modulo various smooth numbers and 
	// build tables to allow us to quickly iterate over 'a' values that are 
	// more likely to produce squares.
	// init sieve structures
	sqr = (uint8 *)calloc((M / 8 + 1) , sizeof(uint8));
	sqr1 = (uint8 *)calloc((M1 / 8 + 1) , sizeof(uint8));
	sqr2 = (uint8 *)calloc((M2 / 8 + 1) , sizeof(uint8));
	mod = (uint8 *)calloc((M / 8 + 1) , sizeof(uint8));
	mod1 = (uint8 *)calloc((M1 / 8 + 1) , sizeof(uint8));
	mod2 = (uint8 *)calloc((M2 / 8 + 1) , sizeof(uint8));
	skip = (uint16 *)malloc(M * sizeof(uint16));

	// test it.  This will be good enough if |u*p-v*q| < 2 * N^(1/4), where
	// mult = u*v
	count = 0;
	if (mpz_perfect_square_p(b2))
		goto found;

	for (i=0; i<8; i++)
		nmasks[i] = ~masks[i];

	// marks locations where squares can occur mod M, M1, M2
	for (i64 = 0; i64 < M; ++i64)
		setbit(sqr, (i64*i64)%M);

	for (i64 = 0; i64 < M1; ++i64)
		setbit(sqr1, (i64*i64)%M1);

	for (i64 = 0; i64 < M2; ++i64)
		setbit(sqr2, (i64*i64)%M2);

	// for the modular sequence of b*b = a*a - n values 
	// (where b2_2 = b2_1 * 2a + 1), mark locations where
	// b^2 can be a square
	m = mpz_mod_ui(tmp, a, M);
	mmn = mpz_mod_ui(tmp, b2, M);
	for (i = 0; i < M; ++i)
	{
		if (getbit(sqr, mmn)) setbit(mod, i);
		mmn = (mmn+m+m+1)%M;
		m = (m+1)%M;
	}

	// we only consider locations where the modular sequence mod M can
	// be square, so compute the distance to the next square location
	// at each possible value of i mod M.
	s = 0;
	d = 0;
	for (i = 0; !getbit(mod,i); ++i)
		++s;
	for (i = M; i > 0;)
	{
		--i;
		++s;
		skip[i] = s;
		if (s > d) d = s;
		if (getbit(mod,i)) s = 0;
	}
	//printf("maxSkip = %u\n", d);

	// for the modular sequence of b*b = a*a - n values 
	// (where b2_2 = b2_1 * 2a + 1), mark locations where the
	// modular sequence can be a square mod M1.  These will
	// generally differ from the sequence mod M.
	m = mpz_mod_ui(tmp, a, M1);
	mmn = mpz_mod_ui(tmp, b2, M1);
	for (i = 0; i < M1; ++i)
	{
		if (getbit(sqr1, mmn)) setbit(mod1, i);
		mmn = (mmn+m+m+1)%M1;
		m = (m+1)%M1;
	}

	// for the modular sequence of b*b = a*a - n values 
	// (where b2_2 = b2_1 * 2a + 1), mark locations where the
	// modular sequence can be a square mod M2.  These will
	// generally differ from the sequence mod M or M1.
	m = mpz_mod_ui(tmp, a, M2);
	mmn = mpz_mod_ui(tmp, b2, M2);
	for (i = 0; i < M2; ++i)
	{
		if (getbit(sqr2, mmn)) setbit(mod2, i);
		mmn = (mmn+m+m+1)%M2;
		m = (m+1)%M2;
	}

	// loop, checking for perfect squares
	mpz_mul_2exp(a2, a, 1);
	count = 0;
	numChars = 0;
	reportIt = limit / 100;
	reportInc = reportIt;
	do
	{
		d = 0;
		i64 = 0;
		do
		{
			// skip to the next possible square residue of b*b mod M
			s = skip[iM];

			// remember how far we skipped
			d += s;

			// update the other residue indices
			if ((iM1 += s) >= M1) iM1 -= M1;
			if ((iM2 += s) >= M2) iM2 -= M2;
			if ((iM += s) >= M) iM -= M;

			// some multpliers can lead to infinite loops.  bail out 
			// if so.
			if (++i64 > M) goto done;

			// continue if either of the other residues indicates
			// non-square.
		} while (!getbit(mod1,iM1) || !getbit(mod2,iM2));

		// form b^2 by incrementing by many factors of 2*a+1
		mpz_add_ui(tmp, a2, d);
		mpz_mul_ui(tmp, tmp, d);
		mpz_add(b2, b2, tmp);

		// accumulate so that we can reset d 
		// (and thus keep it single precision)
		mpz_add_ui(a2, a2, d*2);

		count += d;
		if (count > limit)
			break;

		//progress report
		if ((count > reportIt) && (VFLAG > 1))
		{
			for (i=0; i< numChars; i++)
				printf("\b");
			numChars = printf("%" PRIu64 "%%",(uint64)((double)count / (double)limit * 100));
			fflush(stdout);
			reportIt += reportInc;
		}
	} while (!mpz_perfect_square_p(b2));


found:

	// 'count' is how far we had to scan 'a' to find a square b
	mpz_add_ui(a, a, count);
	//printf("count is %" PRIu64 "\n", count);

	if ((mpz_size(b2) > 0) && mpz_perfect_square_p(b2))
	{
		//printf("found square at count = %d: a = %s, b2 = %s",count,
		//	z2decstr(&a,&gstr1),z2decstr(&b2,&gstr2));
		mpz_sqrt(tmp, b2); 		
		mpz_add(tmp, a, tmp);
		mpz_gcd(tmp, fobj->div_obj.gmp_n, tmp);

		flog = fopen(fobj->flogname,"a");
		if (flog == NULL)
		{
			printf("fopen error: %s\n", strerror(errno));
			printf("could not open %s for writing\n",fobj->flogname);
			goto done;
		}
		logprint(flog, "Fermat method found factors:\n");

		add_to_factor_list(fobj, tmp);
		if (is_mpz_prp(tmp))
		{			
			logprint(flog,"prp%d = %s\n",
				gmp_base10(tmp),
				mpz_conv2str(&gstr1.s, 10, tmp));
		}
		else
		{
			logprint(flog,"c%d = %s\n",
				gmp_base10(tmp),
				mpz_conv2str(&gstr1.s, 10, tmp));
		}

		mpz_tdiv_q(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, tmp);
		mpz_sqrt(tmp, b2);
		mpz_sub(tmp, a, tmp);
		mpz_gcd(tmp, fobj->div_obj.gmp_n, tmp);

		add_to_factor_list(fobj, tmp);
		if (is_mpz_prp(tmp))
		{			
			logprint(flog,"prp%d = %s\n",
				gmp_base10(tmp),
				mpz_conv2str(&gstr1.s, 10, tmp));
		}
		else
		{
			logprint(flog,"c%d = %s\n",
				gmp_base10(tmp),
				mpz_conv2str(&gstr1.s, 10, tmp));
		}

		mpz_tdiv_q(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, tmp);
	}

done:
	mpz_clear(tmp);
	mpz_clear(a);
	mpz_clear(b2);
	mpz_clear(multN);
	mpz_clear(a2);
	free(sqr);
	free(sqr1);
	free(sqr2);
	free(mod);
	free(mod1);
	free(mod2);
	free(skip);
	if (flog != NULL)
		fclose(flog);
	return;

}
Exemple #22
0
static int
e_mpz_even_p (mpz_srcptr x)
{
  return mpz_even_p (x);
}
Exemple #23
0
/* sqrtmod_prime */
static int sqrtmod_prime(void *n, void *prime, void *ret)
{
   int res, legendre, i;
   mpz_t t1, C, Q, S, Z, M, T, R, two;

   LTC_ARGCHK(n     != NULL);
   LTC_ARGCHK(prime != NULL);
   LTC_ARGCHK(ret   != NULL);

   /* first handle the simple cases */
   if (mpz_cmp_ui(((__mpz_struct *)n), 0) == 0) {
      mpz_set_ui(ret, 0);
      return CRYPT_OK;
   }
   if (mpz_cmp_ui(((__mpz_struct *)prime), 2) == 0)     return CRYPT_ERROR; /* prime must be odd */
   legendre = mpz_legendre(n, prime);
   if (legendre == -1)                                  return CRYPT_ERROR; /* quadratic non-residue mod prime */

   mpz_init(t1); mpz_init(C); mpz_init(Q);
   mpz_init(S);  mpz_init(Z); mpz_init(M);
   mpz_init(T);  mpz_init(R); mpz_init(two);

   /* SPECIAL CASE: if prime mod 4 == 3
    * compute directly: res = n^(prime+1)/4 mod prime
    * Handbook of Applied Cryptography algorithm 3.36
    */
   i = mpz_mod_ui(t1, prime, 4); /* t1 is ignored here */
   if (i == 3) {
      mpz_add_ui(t1, prime, 1);
      mpz_fdiv_q_2exp(t1, t1, 2);
      mpz_powm(ret, n, t1, prime);
      res = CRYPT_OK;
      goto cleanup;
   }

   /* NOW: Tonelli-Shanks algorithm */

   /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
   mpz_set(Q, prime);
   mpz_sub_ui(Q, Q, 1);
   /* Q = prime - 1 */
   mpz_set_ui(S, 0);
   /* S = 0 */
   while (mpz_even_p(Q)) {
      mpz_fdiv_q_2exp(Q, Q, 1);
      /* Q = Q / 2 */
      mpz_add_ui(S, S, 1);
      /* S = S + 1 */
   }

   /* find a Z such that the Legendre symbol (Z|prime) == -1 */
   mpz_set_ui(Z, 2);
   /* Z = 2 */
   while(1) {
      legendre = mpz_legendre(Z, prime);
      if (legendre == -1) break;
      mpz_add_ui(Z, Z, 1);
      /* Z = Z + 1 */
   }

   mpz_powm(C, Z, Q, prime);
   /* C = Z ^ Q mod prime */
   mpz_add_ui(t1, Q, 1);
   mpz_fdiv_q_2exp(t1, t1, 1);
   /* t1 = (Q + 1) / 2 */
   mpz_powm(R, n, t1, prime);
   /* R = n ^ ((Q + 1) / 2) mod prime */
   mpz_powm(T, n, Q, prime);
   /* T = n ^ Q mod prime */
   mpz_set(M, S);
   /* M = S */
   mpz_set_ui(two, 2);

   while (1) {
      mpz_set(t1, T);
      i = 0;
      while (1) {
         if (mpz_cmp_ui(((__mpz_struct *)t1), 1) == 0) break;
         mpz_powm(t1, t1, two, prime);
         i++;
      }
      if (i == 0) {
         mpz_set(ret, R);
         res = CRYPT_OK;
         goto cleanup;
      }
      mpz_sub_ui(t1, M, i);
      mpz_sub_ui(t1, t1, 1);
      mpz_powm(t1, two, t1, prime);
      /* t1 = 2 ^ (M - i - 1) */
      mpz_powm(t1, C, t1, prime);
      /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
      mpz_mul(C, t1, t1);
      mpz_mod(C, C, prime);
      /* C = (t1 * t1) mod prime */
      mpz_mul(R, R, t1);
      mpz_mod(R, R, prime);
      /* R = (R * t1) mod prime */
      mpz_mul(T, T, C);
      mpz_mod(T, T, prime);
      /* T = (T * C) mod prime */
      mpz_set_ui(M, i);
      /* M = i */
   }

cleanup:
   mpz_clear(t1); mpz_clear(C); mpz_clear(Q);
   mpz_clear(S);  mpz_clear(Z); mpz_clear(M);
   mpz_clear(T);  mpz_clear(R); mpz_clear(two);
   return res;
}
Exemple #24
0
int applyExtendedEuclid(mpz_t e, mpz_t phi, mpz_t d)
{
	
	mpz_t x, y, z, a, b, c,  div, temp, mul, tx, ty, tz;
	
	if(mpz_even_p(e))	
		return 0;
	
	mpz_init(x);
	mpz_init(y);
	mpz_init(z);
	mpz_init(a);
	mpz_init(b);
	mpz_init(c);
	mpz_init(mul);
	mpz_init(tx);
	mpz_init(ty);
	mpz_init(tz);
	
	mpz_init(div);
	mpz_init(temp);
	
	mpz_init_set_si(a, 1);
	mpz_init_set_si(b, 0);
	mpz_init_set(c, phi);
	mpz_init_set_si(x, 0);
	mpz_init_set_si(y, 1);
	mpz_init_set(z, e);

	do
	{
		mpz_init_set(tx, x);
		mpz_init_set(ty, y);
		mpz_init_set(tz, z);
		#if DEBUG
			printf("\n\n");
			mpz_out_str(NULL, 10, a);
			printf("\n");
			mpz_out_str(NULL, 10, b);
			printf("\n");
			mpz_out_str(NULL, 10, c);
			printf("\n\n");
			mpz_out_str(NULL, 10, x);
			printf("\n");	
			mpz_out_str(NULL, 10, y);
			printf("\n");
			mpz_out_str(NULL, 10, z);
			printf("\n\n");
		#endif
		mpz_tdiv_qr(div, z, c, z);
		mpz_mul(mul, x, div);
		mpz_sub(x, a, mul);
		mpz_mul(mul, y, div);
		mpz_sub(y, b, mul);
		mpz_init_set(a, tx);
		mpz_init_set(b, ty);
		mpz_init_set(c, tz);
		
		
		#if DEBUG
			mpz_out_str(NULL, 10, div);
			printf("\n");
			
			mpz_out_str(NULL, 10, mul);
			printf("\n Sub:");
			
			mpz_out_str(NULL, 10, x);
			printf("\n");
			
			mpz_out_str(NULL, 10, mul);
			printf("\n");
			
			mpz_out_str(NULL, 10, y);
			printf("\n");
			
			mpz_out_str(NULL, 10, a);
			printf("\n");
			mpz_out_str(NULL, 10, b);
			printf("\n");
			mpz_out_str(NULL, 10, c);
			printf("\n\n");
		#endif
	}while(mpz_cmp_si(z, 0L)!=0);	
	
	//LCM not 1
	if(mpz_cmp_si(tz, 1L)!=0)
	{
		return 0;
	}
	else
	{
		mpz_init_set(d, ty);
		return 1;
	}
}
Exemple #25
0
int main(void) {
	long sd = 0;
	int t = 20;
	int s,j_rab;//miller
	int result = 0; //miller
	//metavlites gia metatropi keimenou se int k tubalin
	char mystring[MAXCHARS];//my text to encrypt - decrypt hope so
    long int str_len;
    char c;
    mpz_t max_int, c_int, str_int, encrypted,decrypted;
    mpz_init(max_int); mpz_init(c_int); mpz_init(str_int);mpz_init(encrypted); mpz_init(decrypted);
	mpz_t psi, d, n_minus_one;//miller
mpz_t n_prime,n,three,two,a,one,p,q,phi,p_minus_one,q_minus_one,e,gcd,d_priv,t2;
mpz_t seed;
mpz_t ro;//for encry-decry
gmp_randinit(stat,GMP_RAND_ALG_LC,120);
mpz_init(n_prime);
mpz_init(n);//iniatialize
mpz_init(three);
mpz_init(a);
mpz_init(two);
mpz_init(one);
mpz_init(seed);
mpz_init(psi);//for miller-rabin
mpz_init(p);
mpz_init(q);
mpz_init(phi);
mpz_init(p_minus_one);
mpz_init(q_minus_one);
mpz_init(e);
mpz_init(gcd);
mpz_init(d_priv);
mpz_init(ro);
mpz_init(t2);
mpz_set_str(three, "3", 10);
mpz_set_str(two, "2", 10);
mpz_set_str(one, "1", 10);
srand((unsigned)getpid()); //initialize stat
sd = rand();
mpz_set_ui(seed,sd);
gmp_randseed(stat,seed);
int countpq=0;//0 primes pros to paron, kantous 2 (p kai q)
int i = 0;
//printf("Give a message (till %d chars):\n",MAXCHARS-1);
//fgets(mystring,MAXCHARS,stdin);
//

FILE *fp;            /* declare the file pointer */
 fp = fopen ("file.txt", "r");
 while(fgets(mystring, MAXCHARS, fp) != NULL)
    { sscanf (mystring, "%d"); }
fclose(fp);
//
do{ // mehri na vreis 2 prime

do{//RANDOM NUMBER
	mpz_urandomb(n_prime,stat,512);//create a random number
}while((mpz_even_p(n_prime))&& (n_prime<=three));//checking n to be >=3 && n be odd

mpz_init(n_minus_one); //initialize
mpz_sub_ui(n_minus_one, n_prime, 1);//n_minus_one = n-1
	s = 0;
	mpz_init_set(d, n_minus_one);
	while (mpz_even_p(d)) {// gia oso ine artios
		mpz_fdiv_q_2exp(d, d, 1); //shift right
		s++;//inc s
	}
	for (i = 0; i < t; ++i) {
		do{
		mpz_urandomb(a,stat,20);//create random number
		}while(!((a<=(n_prime-two)) && (a>=two)));//checking a must be (2<=a<=n-2)
		 mpz_powm(psi,a,d,n_prime);
		 if(mpz_cmp(psi,one)!=0 && mpz_cmp(psi,n_minus_one)){
			 j_rab=1;
			 while(j_rab<s &&  mpz_cmp(psi,n_minus_one)){
				 mpz_mul(psi,psi,psi); // y^2
				 mpz_mod(psi,psi,n_prime); //psi= psi^2 mod n
				 	 if(mpz_cmp(psi,one)==0){//if y=1
				 		  result = 1; goto exit_miller;
				 	 }
				 	 j_rab++;
			 }
		 	 if(mpz_cmp(psi,n_minus_one)!=0){//if y=n-1
		 		 result = 1; goto exit_miller;
		 	 }
		 }//end external if
}//end for

	if(result!=1){ countpq++; //an ine prime tote save
	if(countpq==1){mpz_set(p,n_prime);}//save p
	else{
		mpz_set(q,n_prime);}//save q
	}
	exit_miller: result = 0;
	if(mpz_cmp(p,q)==0){countpq=0;}//an p kai q idioi pame pali
}while(countpq<2);

	gmp_printf ("p = %Zd\n", p);
	gmp_printf ("q = %Zd\n", q);
mpz_mul(n,p,q); //calculate p*q
	gmp_printf ("n = p*q = %Zd\n", n);
mpz_sub(p_minus_one,p,one);
mpz_sub(q_minus_one,q,one);
	gmp_printf ("p-1 = %Zd\n", p_minus_one);
	gmp_printf ("q-1 = %Zd\n", q_minus_one);
mpz_mul(phi,p_minus_one,q_minus_one);
	gmp_printf ("phi = %Zd\n", phi);

	do{
	mpz_urandomm(e,stat,phi);//create random number e opou < tou phi
    mpz_add(e,e,two);//add two to be bigger the e from ena
	mpz_gcd(gcd,e,phi);
	}while((!(mpz_cmp(gcd,one)==0)));//checking..gcd=1
		gmp_printf ("e = %Zd\n", e);
		gmp_printf ("gcd = %Zd\n", gcd);
	mpz_invert(d_priv,e,phi);//ypologismos antistrofou e mod phi
		gmp_printf ("private key (d) = %Zd\n", d_priv);
			gmp_printf ("public key (n,e) = (%Zd , %Zd)\n", n,e);
////// convert myText to myIntegerText
		    str_len = strlen(mystring);
		    if(mystring[str_len - 1] == '\n')
		       mystring[str_len - 1] = '\0';
		       str_len = strlen(mystring);
		       printf("%s -> %ld \n", mystring, str_len);
		              for(i = str_len - 1; i >= 0; i--){
		                  c = mystring[i];
		                  mpz_mul_ui(ro,ro,BASE); // r=r*BASE
		                  mpz_add_ui(ro, ro, c);     // r=r+c
		              	  }//now ro is mystring as Integers
		     gmp_printf("My text is: %s and has %ld chars.\nAs Integer is:%Zd",mystring, strlen(mystring), ro);
////// encrypt text
		     mpz_powm(encrypted,ro,e,n);//
		     gmp_printf("\nEncrypted message is: %Zd",encrypted);
		     ////
//// create encrypted file
		     fp= fopen("encrypted_file.txt","w");
		     fprintf(fp, encrypted);
		     fclose(fp);
		     ////
////// decrypt text
		     mpz_powm(decrypted,encrypted,d_priv,n);//
		     gmp_printf("\nDecrypted message is: %Zd",decrypted);
////// convert myIntegerText to myText
		     mpz_set(str_int, ro);//integerText to mytext
		     mpz_set_ui(max_int, 1UL);//larger int set
		     for(i = 0; i < 10; i++){// maxlength =100
		         if(mpz_cmp(str_int, max_int) <= 0){
		        	str_len = i;
		        	break;}
		         mpz_mul_ui(max_int, max_int, BASE);}
		     for(i = 0; i < str_len; i++){
		     mpz_mod_ui(c_int, str_int,BASE);        // ekxoreitai sthn metablhth c_int=str_int mod BASE
		     mpz_sub(str_int, str_int, c_int);
		     mpz_tdiv_q_ui(str_int, str_int,BASE);
		     mystring[i] = mpz_get_ui(c_int);}
		     mystring[str_len] = '\0';
		     //printf("Num of Chars--> %ld\n", str_len);
///////plaintext
		     gmp_printf("\nPlaintext message is: %s",mystring);
mpz_clear(n_prime);
mpz_clear(n);//clear
mpz_clear(three);
mpz_clear(a);
mpz_clear(two);
mpz_clear(seed);
mpz_clear(one);
mpz_clear(d);
mpz_clear(n_minus_one);
mpz_clear(psi);
mpz_clear(p);
mpz_clear(q);
mpz_clear(phi);
mpz_clear(p_minus_one);
mpz_clear(q_minus_one);
mpz_clear(e);
mpz_clear(gcd);
	mpz_clear(d_priv);
	mpz_clear(ro);
    mpz_clear(max_int);
    mpz_clear(c_int);
    mpz_clear(str_int);
	mpz_clear(t2);
	mpz_clear(encrypted);
	mpz_clear(decrypted);
	return 0;
}
Exemple #26
0
int rho_factor(unsigned long *factors, mpz_t n)
/********************************************************************/
{ int    numFactors=0, res, sorted=1, i, retVal;
  static mpz_t stack[32];
  static int initialized=0, stackSize=0;
  long c;

  if (!(initialized)) {
    mpz_init(div1); mpz_init(div2); mpz_init(remain);
    for (i=0; i<32; i++) mpz_init(stack[i]);
    initialized=1;
  }
  if (mpz_cmp_ui(n, 1)==0) {
    factors[0]=1;  return 0;
  }
  mpz_abs(remain, n);
  while (mpz_even_p(remain)) {
    factors[numFactors++]=2;
    mpz_tdiv_q_2exp(remain, remain, 1);
  }

  if (mpz_probab_prime_p(remain, 1)) {
    if (mpz_fits_ulong_p(remain)) {
      factors[numFactors++] = mpz_get_ui(remain);
      return numFactors;
    } else return -1;
  }

  /* 50000 is sufficient for all primes below 100,000,000. */
  c = 1;
  do {
    if (c <= 2)
      res = prho(div1, div2, remain, c, 50000);
    else
      res = prho(div1, div2, remain, c, c*50000);
    c++;
  } while (res && (c <4));

  if (res) {
#define _QUIET
#ifndef _QUIET
    printf("Gave up on factoring "); mpz_out_str(stdout, 10, remain); 
    printf(" (useTrialDivision = %d)\n", useTrialDivision);
#endif
    return -1;
  }

  if (mpz_cmp(div1, div2) > 0) mpz_swap(div1, div2);
  if (mpz_probab_prime_p(div1, 1)) {
    if (mpz_fits_ulong_p(div1)) {
      factors[numFactors++] = mpz_get_ui(div1);
    } else return -1; /* Prime factor that doesn't fit in a long. */
  } else {
    mpz_set(stack[stackSize++], div2);
    retVal = rho_factor(&factors[numFactors], div1);
    mpz_set(div2, stack[--stackSize]);
    if (retVal >=0) numFactors += retVal;
    else return retVal;
  }
  if (mpz_probab_prime_p(div2, 1)) {
    if (mpz_fits_ulong_p(div2)) {
      factors[numFactors++] = mpz_get_ui(div2);
    } else return -1; /* Prime factor that doesn't fit in a long. */
  } else {
    retVal = rho_factor(&factors[numFactors], div2);
    if (retVal >=0) numFactors += retVal;
    else return retVal;
  }
    
  /* Here we should sort the factors. */
  for (i=0; i<(numFactors-1); i++) 
    if (factors[i] > factors[i+1])
      sorted=0;
  if (!(sorted)) {
    /***********************************************************/
    /* This will only happen very very rarely, so it's ok to   */
    /* use quick sort, even though it's only a small number of */
    /* integers, and we could sort it much faster in an ad-hoc */
    /* way.                                                    */
    /***********************************************************/
    qsort(factors, numFactors, sizeof(long), cmpUL);
  }

  return numFactors;
}  
void filter_SPV(uint8 parity, uint8 *sieve, uint32 poly_id, uint32 bnum, 
				static_conf_t *sconf, dynamic_conf_t *dconf)
{
	//we have flagged this sieve offset as likely to produce a relation
	//nothing left to do now but check and see.
	int i;
	uint32 bound, tmp, prime, root1, root2;
	int smooth_num;
	sieve_fb *fb;
	sieve_fb_compressed *fbc;
	tiny_fb_element_siqs *fullfb_ptr, *fullfb = sconf->factor_base->tinylist;
	uint8 logp, bits;
	uint32 tmp1, tmp2, tmp3, tmp4, offset, report_num;

	fullfb_ptr = fullfb;
	if (parity)
	{
		fb = dconf->fb_sieve_n;
		fbc = dconf->comp_sieve_n;
	}
	else
	{
		fb = dconf->fb_sieve_p;
		fbc = dconf->comp_sieve_p;
	}

	//the minimum value for the current poly_a and poly_b occur at offset (-b + sqrt(N))/a
	//make it slightly easier for a number to go through full trial division for
	//nearby blocks, since these offsets are more likely to factor over the FB.
	mpz_sub(dconf->gmptmp1, sconf->sqrt_n, dconf->curr_poly->mpz_poly_b);
	mpz_tdiv_q(dconf->gmptmp1, dconf->gmptmp1, dconf->curr_poly->mpz_poly_a);
	if (mpz_sgn(dconf->gmptmp1) < 0)
		mpz_neg(dconf->gmptmp1, dconf->gmptmp1);

	mpz_tdiv_q_2exp(dconf->gmptmp1, dconf->gmptmp1, sconf->qs_blockbits);
	if (abs(bnum - mpz_get_ui(dconf->gmptmp1)) == 0)
		dconf->tf_small_cutoff = sconf->tf_small_cutoff - 5;
	else if (abs(bnum - mpz_get_ui(dconf->gmptmp1)) == 1)
		dconf->tf_small_cutoff = sconf->tf_small_cutoff - 3;
	else 
		dconf->tf_small_cutoff = sconf->tf_small_cutoff;

#ifdef QS_TIMING
	gettimeofday(&qs_timing_start, NULL);
#endif

	for (report_num = 0; report_num < dconf->num_reports; report_num++)
	{
		uint64 q64;
#ifdef USE_YAFU_TDIV
		z32 *tmp32 = &dconf->Qvals32[report_num];
#endif		

		//this one qualifies to check further, log that fact.
		dconf->num++;

		smooth_num = -1;

		//this one is close enough, compute 
		//Q(x)/a = (ax + b)^2 - N, where x is the sieve index
		//Q(x)/a = (ax + 2b)x + c;	
		offset = (bnum << sconf->qs_blockbits) + dconf->reports[report_num];

		//multiple precision arithmetic.  all the qstmp's are a global hack
		//but I don't want to Init/Free millions of times if I don't have to.

		mpz_mul_2exp(dconf->gmptmp2, dconf->curr_poly->mpz_poly_b, 1); 
		mpz_mul_ui(dconf->gmptmp1, dconf->curr_poly->mpz_poly_a, offset);

		if (parity)
			mpz_sub(dconf->Qvals[report_num], dconf->gmptmp1, dconf->gmptmp2); 
		else
			mpz_add(dconf->Qvals[report_num], dconf->gmptmp1, dconf->gmptmp2); 

		mpz_mul_ui(dconf->Qvals[report_num], dconf->Qvals[report_num], offset); 
		mpz_add(dconf->Qvals[report_num], dconf->Qvals[report_num], dconf->curr_poly->mpz_poly_c); 

		if (mpz_sgn(dconf->Qvals[report_num]) < 0)
		{
			mpz_neg(dconf->Qvals[report_num], dconf->Qvals[report_num]);
			dconf->fb_offsets[report_num][++smooth_num] = 0;
		}

		//we have two signs to worry about.  the sign of the offset tells us how to calculate ax + b, while
		//the sign of Q(x) tells us how to factor Q(x) (with or without a factor of -1)
		//the square root phase will need to know both.  fboffset holds the sign of Q(x).  the sign of the 
		//offset is stored standalone in the relation structure.
	
		//compute the bound for small primes.  if we can't find enough small
		//primes, then abort the trial division early because it is likely to fail to
		//produce even a partial relation.
		bits = sieve[dconf->reports[report_num]];
		bits = (255 - bits) + sconf->tf_closnuf + 1;

#ifdef USE_YAFU_TDIV
		mpz_to_z32(dconf->Qvals[report_num], tmp32);

		//take care of powers of two
		while ((tmp32->val[0] & 0x1) == 0)
		{
			zShiftRight32_x(tmp32, tmp32, 1);
			dconf->fb_offsets[report_num][++smooth_num] = 1;
			bits++;
		}

#else


		//take care of powers of two
		while (mpz_even_p(dconf->Qvals[report_num]))
		{
			//zShiftRight32_x(Q,Q,1);
			mpz_tdiv_q_2exp(dconf->Qvals[report_num], dconf->Qvals[report_num], 1);
			dconf->fb_offsets[report_num][++smooth_num] = 1;
			bits++;
		}
#endif

		i=2;
		//explicitly trial divide by small primes which we have not
		//been sieving.  because we haven't been sieving, their progressions
		//have not been updated and thus we can't use the faster methods
		//seen below.  fortunately, there shouldn't be many of these to test
		//to speed things up, use multiplication by inverse rather than 
		//division, and do things in batches of 4 so we can use
		//the whole cache line at once (16 byte structure)


		//do the small primes in optimized batches of 4
		bound = (sconf->sieve_small_fb_start - 4);
		
		while ((uint32)i < bound)
		{
			tmp1 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp1 * (uint64)fullfb_ptr->small_inv[i];
			tmp1 = q64 >> 32; 
			//at this point tmp1 is offset / prime
			tmp1 = offset - tmp1 * fullfb_ptr->prime[i];
			//now tmp1 is offset % prime
			i++;

			tmp2 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp2 * (uint64)fullfb_ptr->small_inv[i];
			tmp2 = q64 >> 32; 
			tmp2 = offset - tmp2 * fullfb_ptr->prime[i];
			i++;

			tmp3 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp3 * (uint64)fullfb_ptr->small_inv[i];
			tmp3 = q64 >> 32;
			tmp3 = offset - tmp3 * fullfb_ptr->prime[i];
			i++;

			tmp4 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp4 * (uint64)fullfb_ptr->small_inv[i];
			tmp4 = q64 >> 32; 
			tmp4 = offset - tmp4 * fullfb_ptr->prime[i];
			
			i -= 3;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp1 == root1 || tmp1 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}

			i++;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp2 == root1 || tmp2 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}

			i++;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp3 == root1 || tmp3 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}
Exemple #28
0
/* returns 0 on success		*/
int
gen_consts (int numb, int nail, int limb)
{
  mpz_t x, y, z, t;
  unsigned long a, b, first = 1;

  printf ("/* This file is automatically generated by gen-fac_ui.c */\n\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb);
  printf ("Error , error this data is for %d GMP_NUMB_BITS only\n", numb);
  printf ("#endif\n");
  printf ("#if GMP_LIMB_BITS != %d\n", limb);
  printf ("Error , error this data is for %d GMP_LIMB_BITS only\n", limb);
  printf ("#endif\n");

  printf
    ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x2),");
  mpz_init_set_ui (x, 2);
  for (b = 3;; b++)
    {
      mpz_mul_ui (x, x, b);	/* so b!=a       */
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      if (first)
	{
	  first = 0;
	}
      else
	{
	  printf ("),");
	}
      printf ("CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");


  mpz_set_ui (x, 1);
  mpz_mul_2exp (x, x, limb + 1);	/* x=2^(limb+1)        */
  mpz_init (y);
  mpz_set_ui (y, 10000);
  mpz_mul (x, x, y);		/* x=2^(limb+1)*10^4     */
  mpz_set_ui (y, 27182);	/* exp(1)*10^4      */
  mpz_tdiv_q (x, x, y);		/* x=2^(limb+1)/exp(1)        */
  printf ("\n/* is 2^(GMP_LIMB_BITS+1)/exp(1) */\n");
  printf ("#define FAC2OVERE CNST_LIMB(0x");
  mpz_out_str (stdout, 16, x);
  printf (")\n");


  printf
    ("\n/* FACMULn is largest odd x such that x*(x+2)*...*(x+2(n-1))<=2^GMP_NUMB_BITS-1 */\n\n");
  mpz_init (z);
  mpz_init (t);
  for (a = 2; a <= 4; a++)
    {
      mpz_set_ui (x, 1);
      mpz_mul_2exp (x, x, numb);
      mpz_root (x, x, a);
      /* so x is approx sol       */
      if (mpz_even_p (x))
	mpz_sub_ui (x, x, 1);
      mpz_set_ui (y, 1);
      mpz_mul_2exp (y, y, numb);
      mpz_sub_ui (y, y, 1);
      /* decrement x until we are <= real sol     */
      do
	{
	  mpz_sub_ui (x, x, 2);
	  odd_products (t, x, a);
	  if (mpz_cmp (t, y) <= 0)
	    break;
	}
      while (1);
      /* increment x until > real sol     */
      do
	{
	  mpz_add_ui (x, x, 2);
	  odd_products (t, x, a);
	  if (mpz_cmp (t, y) > 0)
	    break;
	}
      while (1);
      /* dec once to get real sol */
      mpz_sub_ui (x, x, 2);
      printf ("#define FACMUL%lu CNST_LIMB(0x", a);
      mpz_out_str (stdout, 16, x);
      printf (")\n");
    }

  return 0;
}
Exemple #29
0
/*
	Returns nonzero when the number in num_str is probably prime.
*/
CPRIMES_DEC int miller_rabin(const char* num_str) {
	int maybe_prime;
	size_t i;

	uint64_t s;

	mpz_t num;
	mpz_t d;
	mpz_t a;
	mpz_t tmp;

	mpz_init_set_str(num, num_str, 10);

	mpz_init_set(d, num);
	mpz_sub_ui(d, d, 1);

	mpz_init(a);

	mpz_init(tmp);

	/* Doesn't play nice for small numbers.... */
	if(mpz_cmp_ui(num, PRIMES_MAX + 1) < 0) {
		for(i = 0; i < PRIMES_LEN; ++i) {
			if(!mpz_cmp_ui(num, primes_cache[i])) {
				maybe_prime = 1;
				goto end;
			}
		}
		maybe_prime = 0;
		goto end;
	} else {
		for(i = 0; i < PRIMES_LEN; ++i) {
			/* Just your friendly neighborhood trivial division */
			if(mpz_divisible_ui_p(num, primes_cache[i])) {
				maybe_prime = 0;
				goto end;
			}
		}
	}

	if(mpz_even_p(num)) {
		if(!mpz_cmp_ui(num, 2)) {
			maybe_prime = 1; /* 2 is prime */
		} else {
			maybe_prime = 0; /* no other evens are */
		}
		goto end;
	}

	/* get D and S ready for _miller_round */
	for(s = 0; mpz_even_p(d); ++s) {
		mpz_divexact_ui(d, d, 2);
	}

	/* select witnesses from the list of primes */
	for(i = 0; i < PRIMES_LEN; ++i) {
		mpz_set_ui(a, primes_cache[i]);
		mpz_set(tmp, d);
		if(!miller_rabin_round(&num, &a, &tmp, s)) {
			maybe_prime = 0;
			goto end;
		}
	}
	maybe_prime = 1;
end:
	mpz_clear(num);
	mpz_clear(d);
	mpz_clear(a);
	mpz_clear(tmp);
	return maybe_prime;
}