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; }
/* 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; }
/** * 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); }
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; }
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); }
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; }
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; }
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; }
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 ); }
/** * 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_); }
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; }
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); }
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); }
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; }
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; }
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; }
static int e_mpz_even_p (mpz_srcptr x) { return mpz_even_p (x); }
/* 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; }
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; } }
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; }
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 }
/* 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; }
/* 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; }