GMP故障天真素数算法c ++

时间:2013-11-22 15:56:29

标签: c++ algorithm rsa primes gmp

我为RSA程序实现了以下GMP功能。基本上,程序会生成随机mpz*t个数字,直到其中一个为此函数返回true

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;
}

这是将isPrime()作为子程序调用的函数:

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);
}

该程序编译并运行没有问题。但是,生成的数字不是素数,但isPrime()仍然为它们返回true。谁能指出我的素性测试算法中的缺陷?以下是我int函数的常规isPrime()版本,如果您想要进行比较:

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;
}

1 个答案:

答案 0 :(得分:1)

错误发生在我的for循环中。

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;

这个for循环的正确版本在这里:

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;