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(bM − 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);
}

測試

test.exe

體會

密碼學計算方法這門課終於結課了。我從這門課程中學到了很多東西——素性測試,整數數分解,離散對數。這門課重新激起了我對數學的興趣。我也是因爲這門課才接觸到GMP大數庫的。總而言之,我從這門課中收穫了很多。就用這篇博文作爲紀念,我也會陸續將課程中學到的其他算法放到博客上來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章