pollard's p-1算法实现(使用GMP库)

pollard’s p-1算法实现(使用GMP库)

隔了好久,今天终于更新了自己的博客。前面偷懒有点过分了,我会陆续把之前积累的一点东西放到博客上来

算法描述

The basic algorithm can be written as follows:
Inputs: n: a composite number
Output: a nontrivial factor of n or failure
1. select a smoothness bound B
2. define

M=primes qBqlogqn

3. compute g = gcd(b
M − 1, n) (note: exponentiation can be done modulo n)

4. if 1 < g < n then return g

5. if g = 1 then select a larger B and go to step 2 or return failure

6. if g = n then select a smaller B and go to step 2 or return failure

If g = 1 in step 6, this indicates there are no prime factors p for which p-1 is B-powersmooth. If g = n in step 7, this usually indicates that all factors were B-powersmooth, but in rare cases it could indicate that a had a small order modulo n.

The running time of this algorithm is O(B × log B × log2 n); larger values of B make it run slower, but are more likely to produce a factor.

适用范围

pollard’s p-1方法有点特殊,它只能应用在求整数n的一个素因子p,且p-1能被“小”因子整除的情况下,除此之外该方法无法正常应用。但是这个方法运用起来相当简单,所以在防止因式分解攻击时,必须考虑这一方法。

实现方式

实际编程时,可以给出一个较大的光滑性界限B,令pi(i = 1, 2, …, t)为不大于B的素数。
For q = {pi | i = 1, 2, …, t且pi<=B}

  • 计算 l=logqn
  • bql 代替 b
  • 计算 g = gcd(b-1, n)
  • if g > 1 return g

End For

代码实现

//求出floor(log(n)/log(q))
int log_f(const mpz_t q, const mpz_t n)
{
    int l = 0;
    mpz_t t;
    mpz_init(t);
    mpz_set_ui(t, 1);

    while (mpz_cmp(t, n) < 0) {
        l++;
        mpz_mul(t, t, q);
    }
    mpz_clear(t);

    return (l-1);
}

//pollard p-1算法
//返回值res 待分解数n 初始值b 光滑性界限B
void pollard_p_1(mpz_t res, const mpz_t n, const mpz_t B, int b)
{
    mpz_t p;
    mpz_init(p);
    mpz_set_ui(p, 2);

    mpz_t g, bb, r;
    mpz_init(g); mpz_init(bb);mpz_init(r);
    mpz_set_si(bb, b);

    mpz_gcd(g, bb, n);
    for (int i = 0; mpz_cmp(p, B) <= 0 && mpz_cmp_si(g, 1) == 0; i++) {
        int l = log_f(p, n);

        for (int j = 0; j < l; j++) {
            mpz_powm(bb, bb, p, n);
        }
        mpz_sub_ui(r, bb, 1);
        mpz_gcd(g, r, n);
        mpz_nextprime(p, p);
    }
    mpz_set(res, g);
    mpz_clear(g); mpz_clear(r); mpz_clear(bb); mpz_clear(p);
}

测试

《pollard's p-1算法实现(使用GMP库)》

体会

密码学计算方法这门课终于结课了。我从这门课程中学到了很多东西——素性测试,整数数分解,离散对数。这门课重新激起了我对数学的兴趣。我也是因为这门课才接触到GMP大数库的。总而言之,我从这门课中收获了很多。就用这篇博文作为纪念,我也会陆续将课程中学到的其他算法放到博客上来。

点赞