bool prime_check(int i)
{
	if(i==1)
		return false;
	if(i==2)
		return true;
	if(miller_rabin(i,2) && miller_rabin(i,3) && miller_rabin(i,5) && miller_rabin(i,7) && miller_rabin(i,11) && miller_rabin(i,13) && miller_rabin(i,17))
		return true;
	return false;
}
Пример #2
0
bool isPrime(const bigInt& a)
{
    if (!checkSmall(a))
        return false;
    if (!miller_rabin(a, 2))
        return false;
    return lucas_selfridge(a);
}
int main()
{
	ull n,i,check;
	scanf("%llu",&n);
	check = miller_rabin(n);
	printf("%s\n",check?"PRIME":"COMPOSITE");
	return 0;
}
bool prime_test(LL n) {
	if (n < 2) return false;
	if (n < 4) return true;
	const int BASIC[12] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
	for (int i = 0; i < 12 && BASIC[i] < n; ++ i) {
		if (!miller_rabin(n, BASIC[i])) return false;
	}
	return true;
}
int main()
{
	mpz_t n;
	mpz_init(n);
	printf("Enter a number - ");
	mpz_inp_str(n , NULL , 10);

    miller_rabin(n);
}
Пример #6
0
unsigned long long prime(void){
  unsigned long long p;
  unsigned long long i = 1;
  unsigned long long s = 1000;
  while(i){
    p = rand() % 65536;
    i = !(miller_rabin(p, s));
  }
  return p;
}
int main()
{
	ull n,i,check,test_cases;
	scanf("%llu",&test_cases);
	while(test_cases--)
	{
		scanf("%llu",&n);
		printf("%s\n",miller_rabin(n)?"YES":"NO");
	}
	return 0;
}
Пример #8
0
void findFactor(bint n,int k) {
  if(n==1)return;
  if(miller_rabin(n, TIME)) {
    factor[++fac_top] = n;
    return;
  }
  bint p = n;
  while(p >= n)
    p = pollard_rho(p,k--);
  findFactor(p,k);
  findFactor(n/p,k);
}
Пример #9
0
int main()
{
	int t;
	int n;
	type i;
	int j;
	type tmp;
	int arr[16];	
	type var = 1;
	scanf("%d", &t);
	for(j =1; j <= t; j++) {
		var = 1;
		scanf("%d", &n);
		for(i = 0; i < n; i++) {
			scanf("%d", &arr[i]);
			var = var * arr[i];
		}
		var++;
		tmp = miller_rabin(var, 5);
		
		if ( tmp == 0 ) {
			for(i = 2; ; i++) {
				if((var - (var/i) * i) == 0) {
					var = var/i;
					i--;
				}
				tmp = miller_rabin(var, 5);
				if( tmp == 1) {
					printf("Case #%d: %lld\n",j, var);
					break;
				}
			}
		} else {
			printf("Case #%d: %lld\n",j, var);
		}
	}
	return 0;
}
Пример #10
0
int main()
{
    int *v;
    v= (int *)malloc(sizeof(int)*1000001);
    int j1, j2, j3, j4, j5, j6, s, n=0;
    int s1, s2, s3, s4, s5;
    for (j6=0; j6<10; j6++) {
        for (j5=0; j5<10; j5++) {
            s5 = j6 + j5;
            for (j4=0; j4<10; j4++) {
                s4 = s5 + j4;
                for (j3=0; j3<10; j3++) {
                    s3 = s4 + j3;
                    for (j2=0; j2<10; j2++) {
                        s2 = s3 + j2;
                        for (j1=0; j1<10; j1++) {
                            v[s2 + j1 + n++] = 1;
                        }
                    }
                }
            }
        }
    }
    v[1] = 1;
    int t;
    scanf("%d", &t);
    while(t--) {
        int m,n;
        scanf("%d%d", &m, &n);

        int count =0;
        int num;
        for(num = m; num <= n; num++) {
            if(v[num] == 0) {
                printf("%d\n", num);
                if(num % 2 == 0) {
                    continue;
                } else if(miller_rabin(num)) {
                    count ++;
                    printf("\t%d\n", num);
                }
            }
        }
        printf("%d\n",count);
    }
    return 0;
}
Пример #11
0
int main(int argc, char *argv[])
{
    int n, cnt;
    long long a;

    while (scanf("%d", &n) != EOF) {
        cnt=0;
        while (n--) {
            scanf("%lld",&a);
            if (miller_rabin(a)) {
                cnt++;
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}
Пример #12
0
int problem263()
{
  integer testnum = string_to_integer("5");
  integer testnum_helper = string_to_integer("5");
  integer two = string_to_integer("2");
  integer total_src = string_to_integer("0");
  integer total_tar = string_to_integer("0");
  integer target_dif = string_to_integer("6");
  integer dif = string_to_integer("0");

  int found = 0;
  integer lastprime = string_to_integer("5");
  //int sexy_count = 0;
  printf("text here\n");
  while (found < 4) {
    //printf("gets 1\n");
    if (miller_rabin(testnum) == PRIME) {
      subtract_integer(testnum, lastprime, dif);
      if (compare_integers(dif, target_dif) == 0) {
        printf("difference between %s and %s is six\n", 
                integer_to_string(testnum), integer_to_string(lastprime));
        found++;
      }else {
        found = 1;
      }
      copy_integer(testnum, lastprime);
      add_integer(total_src, testnum, total_tar);
      copy_integer(total_tar, total_src);
      printf("Total is %s\n", integer_to_string(total_tar));
    }
    add_integer(testnum_helper, two, testnum);
    copy_integer(testnum, testnum_helper);
    printf("Tested %s\n", integer_to_string(testnum));
  }
  return 0;
}
Пример #13
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;
}
Пример #14
0
/**
 * 取下一个可能的素数
 * 参见java语言BigInteger.nextProbablePrime()实现
 */
NUT_API BigInteger next_prime(const BigInteger& n)
{
    if (n <= 1)
        return BigInteger(2);

    const size_t SMALL_PRIME_THRESHOLD = 95;
    const size_t DEFAULT_PRIME_CERTAINTY = 2;
    const BigInteger SMALL_PRIME_PRODUCT(((uint64_t) 3) * 5 * 7 * 11 * 13 * 17 * 19 *
            23 * 29 * 31 * 37 * 41);

    BigInteger result(n);
    ++result;

    // Fastpath for small numbers
    if (result.bit_length() < SMALL_PRIME_THRESHOLD)
    {
        // Ensure an odd number
        if (result.bit_at(0) == 0)
            ++result;

        while(true)
        {
            // Do cheap "pre-test" if applicable
            if (result.bit_length() > 6)
            {
                const int64_t r = (int64_t) (result % SMALL_PRIME_PRODUCT).to_integer();
                if ((0 == r % 3)  || (0 == r % 5)  || (0 == r % 7)  || (0 == r % 11) ||
                    (0 == r % 13) || (0 == r % 17) || (0 == r % 19) || (0 == r % 23) ||
                    (0 == r % 29) || (0 == r % 31) || (0 == r % 37) || (0 == r % 41))
                {
                        result += 2;
                        continue; // Candidate is composite; try another
                }
            }

            // All candidates of bit_length 2 and 3 are prime by this point
            if (result.bit_length() < 4)
                return result;

            // The expensive test
            if (miller_rabin(result, DEFAULT_PRIME_CERTAINTY))
                return result;

            result += 2;
        }
    }

    // Start at previous even number
    if (result.bit_at(0) == 1)
        --result;

    // Looking for the next large prime
    size_t search_len = (result.bit_length() / 20) * 64;

    while (true)
    {
        BitSieve search_sieve(result, (int) search_len);
        const BigInteger candidate = search_sieve.retrieve(result, DEFAULT_PRIME_CERTAINTY);
        if (!candidate.is_zero())
            return candidate;
        result += 2 * search_len;
    }
}