素數的Miller Rabbin測試

2021-06-03 07:39:50 字數 2390 閱讀 4040

【引理】如果p是乙個素數的話,那麼對任意乙個小於p的正整數a,a, 2a, 3a, ..., (p-1)a除以p的餘數正好是乙個1到p-1的排列。(例如,5是素數,3, 6, 9, 12除以5的餘數分別為3, 1, 4, 2,正好就是1到4這四個數。)

【證明】( 反證法)假如結論不成立的話,那麼就是說有兩個小於p的正整數m和n使得na和ma除以p的餘數相同。不妨假設n>m,則p可以整除a(n-m)。但p是素數,那麼a和n-m中至少有乙個含有因子p。這顯然是不可能的,因為a和n-m都比p小。

【fermat小定理(fermat's little theorem)】如果p是素數,a是小於p的正整數,那麼a(p-1) mod p ≡ 1。

【證明】用同余式表述,可以證明:(p-1)! ≡ a * 2a * 3a * ... * (p-1)a (mod p),也即:(p-1)! ≡ (p-1)! * a^(p-1) (mod p)。

兩邊同時除以(p-1)!,就得到了我們的最終結論:1 ≡ a^(p-1) (mod p)

談到fermat小定理,數學歷史上有很多誤解。很長一段時間裡,人們都認為fermat小定理的逆命題是正確的,並且有人親自驗證了a=2, p<300的所有情況。2023年有人發現了fermat小定理逆命題的第乙個反例:雖然2的340次方除以341餘1,但341=11*31。後來,人們又發現了561, 645, 1105等數都表明a=2時fermat小定理的逆命題不成立。雖然這樣的數不多,但不能忽視它們的存在。於是,人們把所有能整除2(n-1)-1的合數n叫做偽素數(pseudoprime數)。

不滿足2^(n-1) mod n = 1的n一定不是素數;如果滿足的話則多半是素數。這樣,乙個比試除法效率更高的素性判斷方法出現了:製作一張偽素數表,記錄某個範圍內的所有偽素數,那麼所有滿足2^(n-1) mod n = 1且不在偽素數表中的n就是素數。之所以這種方法更快,是因為我們可以使用二分法快速計算2(n-1)  mod n 的值,這在計算機的幫助下變得非常容易;在計算機中也可以用二分查詢有序數列、hash錶開雜湊、構建trie樹等方法使得查詢偽素數表效率更高。

由於偽素數的存在使得我們需要改進素數檢測演算法。最簡單的想法就是,我們剛才只考慮了a=2的情況。對於式子a^(n-1) mod n,取不同的a可能導致不同的結果。乙個合數可能在a=2時通過了測試,但a=3時的計算結果卻排除了素數的可能。於是,人們擴充套件了偽素數的定義,稱滿足a^(n-1) mod n = 1的合數n叫做以a為底的偽素數(pseudoprime to base a)。前10億個自然數中同時以2和3為底的偽素數只有1272個,這個數目不到剛才的1/4。這告訴我們如果同時驗證a=2和a=3兩種情況,演算法出錯的概率降到了0.000025。容易想到,選擇用來測試的a越多,演算法越準確。通常我們的做法是,隨機選擇若干個小於待測數的正整數作為底數a進行若干次測試,只要有一次沒有通過測試就立即把這個數扔回合數的世界。這就是fermat素性測試。

然而並不能僅通過選取所有小於n的基數a來消除素數測試中的出錯機會,因為總存在這樣的合數,它可以通過所有的測試。carmichael第乙個發現這樣極端的偽素數,因此這類數被稱作carmichael數。carmichael數的存在說明,我們還需要繼續加強素性判斷的演算法。

miller和rabin兩個人的工作讓fermat素性測試邁出了革命性的一步,建立了miller-rabin素性測試演算法。新的測試基於下面的定理:如果p是素數,x是小於p的正整數,且x2 mod p = 1,那麼要麼x=1,要麼x=p-1。這是顯然的,因為x2 mod p = 1相當於p能整除x2-1,也即p能整除(x+1)(x-1)。由於p是素數,那麼只可能是x-1能被p整除(此時x=1)或x+1能被p整除(此時x=p-1)。

這就是miller-rabin素性測試的方法:不斷地提取指數n-1中的因子2,把n-1表示成d*2r(其中d是乙個奇數)。那麼我們需要計算的東西就變成了a的d*2r次方除以n的餘數。於是,a^(d * 2r-1)要麼等於1,要麼等於n-1。如果a^(d *2r-1)等於1,定理繼續適用於a^(d * 2r-2),這樣不斷開方開下去,直到對於某個i滿足a^(d * 2i) mod n = n-1或者最後指數中的2用完了得到的admod n=1或n-1。

這樣,fermat小定理加強為如下形式:盡可能提取因子2,把n-1表示成d*2^r,如果n是乙個素數,那麼或者a^d mod n=1,或者存在某個i使得a^(d*2i) mod n=n-1 ( 0<=id mod n=n-1的情況統一到後面去了).

miller-rabin素性測試同樣是不確定演算法,我們把可以通過以a為底的miller-rabin測試的合數稱作以a為底的強偽素數(strong pseudoprime)。第乙個以2為底的強偽素數為2047。第乙個以2和3為底的強偽素數則大到1 373 653。

miller-rabin演算法的簡單實現(c語言)如下:

long exp_mod(long a,long b,long n)

return r;

}bool miller_rabbin(long n)while(i++

Miller Rabbin素數測試

miller rabbin 素數測試可以判斷比較大的數是不是素數。但是判斷的結果可能是偽素數。費馬小定理 若p為素數是,滿足 a equiv 1 mod p 二次探測定理 若p為奇素數且 x 2 equiv 1 mod p 則x equiv 1 mod p 或者 x equiv p 1 mod p ...

關於Miller Rabbin的一點想法

在好久之後終於搞完了miller rabbin素性測試,談談自己的理解 要判斷的數設為 a,主要思想就是運用費馬小定理來搞,隨機幾個數x x a 1 判斷x a 1 1 mod a 是否成立,如果有不成立,a肯定不是素數 這是有一定錯誤機率的,隨機n個數的錯誤機率為4 n 這麼看來,肯定是多來幾組隨...

素數的判斷和素數表

素數問題自己之前也接觸過,這裡做乙個系統的總結 一 素數的判斷 首先要明白什麼是素數 素數就是只能被1和自己整除的整數,不符合該條件的稱為合數 所以當我們判斷乙個數是否是素數的時候,最直接粗暴的演算法就是對2 n 1進行列舉,如果存在約數k,滿足n k 0 此時,這個數就不是素數,為合數 但是該方法...