我为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;
}
答案 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;