Pregunta

I implemented the following GMP function for an RSA program. Basically, the program generates random mpz*t numbers until one of them returns true for this function.

bool isPrime(const mpz_t bignum)
{
    mpz_t modnum; mpz_init(modnum);
    if(mpz_cmp_ui(bignum,4)<0 && mpz_cmp_si(bignum,0)>=0) {
        fprintf(stderr,"Trivially prime.\n");
        return false;
    }
    else if(mpz_mod_ui(modnum,bignum,2)==0)
        return false;
    mpz_clear(modnum);

    mpz_t i,rootnum; 
    mpz_inits(i,modnum,rootnum,NULL);
    mpz_sqrt(rootnum,bignum);
    mpz_set_str(i,"3",10);

    for(;mpz_cmp(rootnum,i)>0; mpz_add_ui(i,i,2)) {
        mpz_mod(modnum,bignum,i);
        if(mpz_cmp(modnum,i)==0)
            return false;
    }
    mpz_clears(modnum,i,rootnum,NULL);
    return true;
}

Here is the function that calls isPrime() as a subroutine:

void generate_pq(mpz_t& p, mpz_t& q) 
{
    gmp_randstate_t rstate;
    gmp_randinit_default(rstate);
    gmp_randseed_ui(rstate,time(NULL));

    printf("\nGenerating keys...\n");
    do {
        mpz_urandomb(p,rstate,32);
    } while(!isPrime(p));
    printf("\n***** p *****\n");
    gmp_printf("    %Zd\n",p);
    do {
        mpz_urandomb(q,rstate,32);
    } while(!isPrime(q));
    gmp_randclear(rstate);

    printf("\n***** q *****\n");
    gmp_printf("    %Zd\n",q);
}

The program compiles and runs no problem. However, the numbers generated are not prime and yet isPrime() still returns true for them. Could anyone point out the flaw in the algorithm of my primality test? Here is the regular int version of my isPrime() function, if you'd like to compare:

bool isPrime(uint64_t n) 
{
    //waste of time
    if(n < 4) {
        fprintf(stderr,"Trivially prime.\n");
        return true;
    }
    //even #, not prime
    else if(n%2==0) {
        return false;
    }
    //check if divisible by all odd #s < sqrt(n)
    for(uint64_t i=3; i<(uint64_t)sqrt(n+1); i+=2) {
        if(n%i==0) {
            return false;
        }
    }
    return true;
}
¿Fue útil?

Solución

The error was in my for-loop.

for(;mpz_cmp(rootnum,i)>0; mpz_add_ui(i,i,2)) {
    mpz_mod(modnum,bignum,i);
    if(mpz_cmp(modnum,i)==0) // <-----not supposed to do if(modnum==i)
        return false;

The correct version of this for-loop is here:

for(;mpz_cmp(rootnum,i)>0; mpz_add_ui(i,i,2)) {
    mpz_mod(modnum,bignum,i);
    if(mpz_cmp_ui(modnum,0)==0) // <-- if bignum % modnum == 0, return false
        return false;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top