【问题标题】:GMP faulty naive primality algorithm c++GMP错误的朴素素数算法c ++
【发布时间】:2013-11-22 15:56:29
【问题描述】:

我为 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。谁能指出我的素性检验算法中的缺陷?这是我的isPrime() 函数的常规int 版本,如果你想比较一下:

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

【问题讨论】:

  • 你能给出无效输出的示例编号吗?
  • 发现问题。但是给你:p = 1977882773, q = 1932673697
  • 你知道gmplib中的mpz_nextprime函数吗?选择所需大小的随机数,然后调用 mpz_nextprime 以获取下一个更大的素数。如果你想使用 Gmplib 也有随机数生成器。
  • 这是我没有与教授确认的事情。不是数学专业的。所以我只需要检查所有素数吗?对于后一种说法,我使用 GMP 生成随机数。
  • 我仔细检查了mpz_nextprime(),对于这种特殊情况,我必须使用朴素素数测试。您所指的函数使用概率素数。

标签: c++ algorithm rsa primes gmp


【解决方案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;

【讨论】:

    猜你喜欢
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2013-07-18
    • 2021-04-09
    • 2015-03-06
    • 2016-08-18
    • 2014-11-12
    相关资源
    最近更新 更多