0.2 模運算
0.2.4 高次剩餘
33 return ans.first;
34 }catch(signed e){
35 return -1;
36 }
37 }
Listing 21: Calculating square root mod m
注意到其中的 cht 需要用到Listing 18的函式︒
Corollary 23. 若已知 n 的因式分解,可以在期望 O(logn)的時間找出一個 m 模n 的平方根︒
Proof. 假設n =Q
qi =Q
piki︒若 pi = 2,則處理該部分的問題需要
O(ki) = O(logqi)︒若 pi 是奇質數,則需要 Cipolla 的O(logqi) 跟快速冪的 O(logqi)︒CRT 的部分亦是 O(logpi)的︒故總時間是 P
piO(logqi) = O(logn) 的︒
Property 44. 若 p6 |n,則 n 是模 pk 的 pl 次剩餘(l < k)若且唯若n 是模 pl+1 的 pl 次剩餘若且唯若 npl ≡n (mod pl+1)
Proof. (1⇔2): 那個Z/ pk
→Z/ pl+1
的投影根本就只是把指數取 φ(pl+1)的 餘數而已,不會改變指數是不是pl 的倍數︒
(2⇔3) 模pl+1 的 pl 次剩餘只有 φ(pl+1)/pl =p−1 種,其實就是 1pl, . . .(p−1)pl︒所以你只要檢查 n 是不是npl 即可︒
接著我們開始介紹如何實際計算︒首先根據中國剩餘定理,可以把模數拆成質數 冪次的乘積並分開做︒另外,我們也可以把r 拆成質數的乘積並依序開根號︒而 根據以上的討論我們已剩下 r 的質因數整除p 或等於 p的情形了︒若等於 p,我 們可以從p2 的情形慢慢往上推,亦即
Property 45. 在模 p= 2, k >2 或 p >2, k >1 的情況下,若xp ≡n (mod pk),則 y=x−(xp−n)/p 滿足 yp ≡n (mod pk+1)︒
Proof.
yp = (x−(xp−n)/p)p
≡xp+xp−1(xp−n) + p(p−1)
2 ((xp −n)/p)2xp−2
=n+ (xp−1−1)(xp−n) + p(p−1)
2 ((xp−n)/p)2xp−2 ≡n (mod pk+1) 注意到第二項根據費馬小定理被p·pk 整除,第二項被p2k−1 整除(若p= 2 則 26 |p(p2−1),會再少一)︒因此只剩第一項︒
而如果r|p−1,我們有以下 Cipolla 的推廣:
Theorem 9 (Cipolla–Lehmer). 若n 是一個模 p的 r 次剩餘,且 r|p−1 是一個 質數,ar−n 不是一個r 次剩餘,現在考慮在 Z/hpi√r
ar−n
中,並令 b= a−√
a2−nr(p−1)pr−1
︒則 b∈Z/hpi 滿足br =n︒
Proof. 首先注意Z/hpi√r
ar−n
'Z/hpi[X]/hXr−ar+ni 是一個體,且 ω=√r
ar−np−1 = (ar−n)(p−1)/r 的階是 r(這裡用到 r 是質數)︒因此ωp =ω,
且
(√r
ar−n)pi =√r
ar−n (√r
ar−n)p−11+p+···+pi−1
=ωi√r ar−n 故
br =
a−√ a2−n
1+p+p2+···+pr−1
=
r−1
Y
i=0
(a−ωi√r
ar−n) = ar−(√r
ar−n)r =n
Lemma 20 ([8] Theorem 2). 固定 r|p−1,則對於任何 n,使 ar−n 是 r 次剩 餘的a 至多只有 p/r+O(√
p) 個︒
Proof. 細節待補,想法是找一個多項式R(x)使得當x∈Fp 滿足 xr−n 是 r次剩 餘時(亦即(xr−n)(p−1)/r =xp−x= 0 時),R 在x 都是一個 M 階零點︒(在該 處泰勒展開的最低 M 項為零)︒因此滿足該條件的 x至多只有 degR/M 個︒藉 由選取好的R 我們便可以得到上述上界︒
綜合以上討論,隨機戳到非 r 次剩餘的機率是1−r−1−O(1/√
p) 的︒因此對於 每一個r 都只要試 O(1) 次
Corollary 24. 對固定 r,我們都有一個期望複雜度 O(logp) 的開r 次方根演算 法︒
Remark 10. 注意上述O(logp) 的常數與 r 有關︒如果不考慮隨機部分,那大 約是O(r3logp)的︒
不只Cipolla 演算法可以被推廣,Tonelli-Shanks 也可以被推廣,稱為
Adelman-Manders-Miller 演算法[1]︒
1 #include<unordered_map>
2 using Random::randInt;
3
4 int invmod(int a, int mod);
5
6 bool is_rth_residue(int n, int p, int r){
7 return fpow(n, (p-1)/r, p) == 1;
8 } 9
10 int adelman_manders_miller(int n, int p, int r){
11 int a = 0, b = p-1, c;
12 vector<int> r_power; r_power.push_back(1);
13 while(b%r == 0) b/=r, a++, r_power.push_back(r*r_power.back()%p);
14 do c = randInt(2, p-1);
15 while(is_rth_residue(c, p, r));
16
17 int d = a, l = (r-invmod(b, r))%r, e = fpow(c, b, p), 18 f = fpow(n, l*b%(p-1), p), g = fpow(n, (l*b+1)/r, p), 19 omega = fpow(c, (p-1)/r, p);
20
21 std::unordered_map<int, int> omega_power;
22 for(int i = 0, o = 1; i < r; i++, o = o*omega%p) omega_power[o] = i;
23
24 while(true){
25 if(f == 1) return g;
26 int i = 0, prev;
27 for(int t = f; i < d && t != 1; i++, prev=t, t=fpow(t, r, p));
28 if(i == d) throw -1;
29
30 int j = omega_power[invmod(prev, p)],
31 h = fpow(e, j*r_power[d-i-1], p);
32 d = i, e = fpow(e, r_power[d-i], p), f=f*h%p*h%p, g=g*h%p;
33 }
34 }
Listing 22: Adelman-Manders-Miller algorithm
Lemma 21. 上述演算法的輸出 g 滿足 gr ≡n (mod p)︒
Proof. 注意到ω 6= 1 滿足 ord(ω) =r︒我們有以下不變量:
erd−1 ≡ω, frd−1 ≡1, gr ≡f n︒
注意到每次選取的 i 是使fri ≡1 的最小正整數︒
此時ord(fri−1) =r,因此存在j 使得 ωjfri−1 = 1︒
Corollary 25. 給定 n 為模 p的 r 次剩餘,Adelman-Manders-Miller 演算法可 以在最差O(plogp),期望O
r+ loglog2rp
的時間複雜度內找出一個 x 使得 xr ≡n (mod p)︒
Proof. 一開始需要O(logr(p) +r)的時間,而迴圈總共跑 O(logr(p)) 次,每次需 要跑O(logr(p)logr+logp) 的時間,因此總共是 O
r+ loglog2rp
的︒
Remark 11. 如果 r= Ω(√p)的話,直接做離散對數再把指數除以 r 會比上述 兩種演算法都來得快︒