大素数的费马素数检验

时间:2018-03-27 11:47:13

标签: c linux primes gmp

我目前正在尝试为学校项目实施RSA加密算法。在调查之后我认为生成我自己的素数也会很有趣。我正在使用gmp lib存储数字。

一些消息来源说,这通常是通过使用筛分方法然后对数字进行概率测试来完成的,在我的情况下,我从费马测试开始:

a ^(potPrime-1)≡1(mod potPrime)

我遇到的问题是计算“a ^(potPrime-1)”,我在gmp lib中找不到一个可以计算mpz_t功率的函数另一个mpz_t所以我写了自己的,这真的是一段时间保持循环,直到我将数字乘以所需的次数。 这适用于较小的数字,但是当potPrime可以达到2 ^ 2048时,这个解决方案是不够的。

有谁知道我怎么能解决这个问题?以下是费马测试的代码:

int fermatTest(mpz_t potPrime, mpz_t a) //The fermat test is a mathimatical test that will determine if a number is potentialy prime.
{                                       //a is a random number between ]1;p-1[
    int result;
    mpz_t potPrimeMin1,aSqPotPrimeMin1,val1; //decalre mpz type value, val1=1
    mpz_init(potPrimeMin1); //initialises the mpz type value of the number containing potPrime minus 1
    mpz_init(aSqPotPrimeMin1);//value of a^(p-1)
    mpz_init(val1); //a mpz type var where val1 is allways 1
    mpz_set_ui(val1,1);

    mpz_sub_ui(potPrimeMin1,potPrime,1); //subtracts 1 from potPrime and stores it in potPrimeMin1

    mympz_pow(aSqPotPrimeMin1,a,potPrimeMin1);//aSqPotPrimeMin1=a^potPrimeMin1

    result = mpz_congruent_p(aSqPotPrimeMin1,val1,potPrime); //test checks if a^(potPrime-1) ≡ 1 (mod potPrime) - returns non zero if congruent

    //returns non zero if operation is true, 0 if not

    mpz_clear(potPrimeMin1);//frees the variables used
    mpz_clear(aSqPotPrimeMin1);
    mpz_clear(val1);

    return result;
}

这是pow功能的代码:

int mympz_pow(mpz_t result, mpz_t base, mpz_t power)
{
    mpz_t i;
    mpz_init(i);
    mpz_set_ui(i,1);
    mpz_set(result,base);
    //mpzPrint("1",result);
    while(mpz_cmp(i,power) < 0)
    {
        mpz_mul(result,result,base);
        //mpzPrint("2",result);
        mpz_add_ui(i,i,1);
        mpzPrint("pow",power);
        mpzPrint("i",i);
    }
    //mpzPrint("3",result);
    mpz_clear(i);
    return 1;
}

1 个答案:

答案 0 :(得分:1)

Gmp的函数mpz_powm可以进行模幂运算。如果您想自己动手,请使用square-and-multiply算法:

function powerMod(b, e, m)
    x := 1
    while e > 0
        if e%2 == 1
            x, e := (x*b)%m, e-1
        else b, e := (b*b)%m, e//2
    return x

这需要时间对数的指数而不是线性,正如您的算法所做的那样。或者您可能更喜欢使用mpz_probab_prime_p并让gmp为您完成所有工作。