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
3. compute g = gcd(bM
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
- 計算
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);
}
測試
體會
密碼學計算方法這門課終於結課了。我從這門課程中學到了很多東西——素性測試,整數數分解,離散對數。這門課重新激起了我對數學的興趣。我也是因為這門課才接觸到GMP大數庫的。總而言之,我從這門課中收穫了很多。就用這篇博文作為紀念,我也會陸續將課程中學到的其他演算法放到部落格上來。