Legalscape のしろくまです。
今日は確率的素数判定法について話したいと思います。
フェルマーの小定理
が素数のとき
と互いに素な
について
が成り立ちます
確率的素数判定法: フェルマーテスト
フェルマーの小定理の対偶を取ると、次のようなことが言えます。
と互いに素な
について、
ならば、n は合成数である。
このことを利用した素数判定法をフェルマーテストといいます。
このような を
が合成数である「証拠」と言うことにします。
実際に Python でフェルマーテストを実行してみると
# 91 = 13*7 print([pow(i, 91-1, 91) for i in range(2, 7)]) # [64, 1, 1, 64, 64] # 68537611 = 4337*15803 print([pow(i, 68537611-1, 68537611) for i in range(2, 7)]) # [20955178, 68149251, 39398849, 8891250, 3002060]
という風にうまく合成数である証拠を見つけられているように見えます。
しかし、上述の のように合成数であって、
を満たすような a も存在し、そのような
を「うそつき」ということにします。
このときランダムに を選んだとき嘘つきとなるような
を選択する確率は
がカーマイケル数でないならば高くとも 1/2 であることが知られています。
カーマイケル数とは合成数であって なる任意の
について
を満たすような
のことです。
証明は
を
の単元群(n と互いに素な剰余類の乗法群)とし、
を
と定めます。
このとき が合成数でかつカーマイケル数ではないならば
は
の真部分群となります。これは
有限群についての事実:
指数 は
が
の真部分群であるならば
となる。
によって となり、カーマイケル数以外に関してはランダムに選ばれた
がフェルマーテストのうそつきとなる確率は
以下と分かります。
以上より、フェルマーテストを繰り返せば確率的に素数を判定できることがわかりました。
ちなみにカーマイケル数は無限に存在することが知られている一方で素数ほどは多くないので、カーマイケル数に巡り合わない場合はフェルマーテストで"運良く"十分な精度が得られる場合もあるかもしれません。
Miller-Rabin 素数判定法
一方で、そのような運要素を除去して確率を保証できるアルゴリズムとして Miller-Rabin 素数判定法が知られています。
Miller-Rabin 素数判定法も同様に素数が満たすべき性質をもとにした判定法です。
この方法にはカーマイケル数のような例外はなく 1 度の Miller-Rabin テストでランダムに選んだ がうそつきである確率は
以下となることが知られています。
Miller-Rabin テストでは、奇数 に対して
(
は奇数)と分解し、
となる整数
を選びます。この
をテストの「底」と呼びます。
かつ、
を満たすすべての整数
について
が成り立つならば、 は
が合成数である「証拠」です。条件を満たさない場合でも
が素数とは限らず、そのような
を Miller-Rabin テストの「うそつき」と呼びます。
独立に選んだ 個の底について Miller-Rabin テストを行ったとき、合成数
がすべてのテストを通過してしまう確率は高々
です。
ここで、確率的な素数判定という性質に着目すると、実績としてある特定の回数 k で抑え込めるのではないかということが期待されます。
64bit の場合7回で判定可能
そしてそれは 64bit の場合7回で判定可能1なことが知られており、
a ∈ {2, 325, 9375, 28178, 450775, 9780504, 1795265022}
の範囲で Miller-Rabin テストを実行すれば良いです。
Legalscape では様々な領域でエンジニアが活躍しており、現在もエンジニアとして働かれるメンバーを募集しております。