ソロベイ–シュトラッセン素数判定法

提供: testwiki
2021年6月15日 (火) 16:31時点におけるimported>シダー近藤による版 (Category:数論アルゴリズムを除去; Category:素数判定を追加 (HotCat使用))
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

ソロベイ–シュトラッセン素数判定法テンプレート:Lang-en-short)は、テンプレート:仮リンクフォルカー・シュトラッセンによって開発された、与えられた数が合成数擬素数か判定する確率的テストである。現在ではテンプレート:仮リンクミラー-ラビン素数判定法にとって代わられているが、RSA暗号の実用性を示したアルゴリズムとして歴史的には重要である。

概要

レオンハルト・オイラーは任意の素数pと整数aに対して、

a(p1)/2(ap)(modp)

((ap)テンプレート:仮リンク)であることを証明した[1]テンプレート:仮リンクはルジャンドル指標を一般の奇数nに対する(an)に一般化したものである。ヤコビ指標は平方剰余の相互法則のヤコビによる一般化を用いればO((log n)2)時間で計算できる。

奇数nが与えられたとき、合同式

a(n1)/2(an)(modn)

nと互いに素な様々な底aに対して成立するかどうかを考えることができる。nが素数なら、この合同式はすべてのaに対して真である。そのため、ランダムにaを取ってこの合同式をチェックすれば、成り立たないaが存在した時にnが素数でないことが言える(ただし素因数分解は分からない)。この場合の底anのEuler witnessと呼ぶ。このanが合成数であることの証拠である。もしnが合成数で上の合同式が成立するならば、そのときの底anのEuler liarと呼ぶ。

任意の奇数の合成数nに対して、全ての底のうち少なくとも半分の底

a(/n)*

がEuler witnessである[2]。これは、証拠の数がずっと少なくなり得るフェルマーテストとは対照的である。そのため、フェルマーテストにおけるカーマイケル数の存在とは対照的に、証拠がたくさん存在しないような(奇数の)合成数nは存在しない。

n = 221が素数かどうかを判定したいとする。(n−1)/2=110である。

ランダムにaを取る(ここではa = 47 < n)。このとき、

  • a(n−1)/2 mod n  =  47110 mod 221  =  −1 mod 221
  • (an) mod n  =  (47221) mod 221  =  −1 mod 221.

これにより、221が素数であるか、47が221のEuler liarであることが分かる。もう一つ別のa(ここではa = 2)で試す。

  • a(n−1)/2 mod n  =  2110 mod 221  =  30 mod 221
  • (an) mod n  =  (2221) mod 221  =  −1 mod 221.

2は221が合成数であることを示すEuler witnessであるため、47は実はEuler liarであった。なおこの方法では221の約数(13と17)については何も分からないことに注意されたい。

アルゴリズムと実行時間

このアルゴリズムは以下の疑似コードで書ける:

入力: n : 素数かどうかチェックする数; k: テストの正確性を決めるパラメータ
出力: nが合成数の場合はcomposite、そうでなければprobably prime
以下を k 回繰り返す:
  [2,n − 1]の範囲からaをランダムに選ぶ
   x(an)
   if x = 0 or a(n1)/2≢x(modn) then return composite
return probably prime

冪剰余の高速なアルゴリズムを使えば、このアルゴリズムの実行時間はO(k·log3 n)である(kは異なるaでテストをする回数)。

テストの正確性

このアルゴリズムは誤った答えを返すことがある。入力nが実際に素数であれば、出力は常に正しく「probably prime」である。しかし、入力nが合成数である場合にも、出力が「probably prime」である場合がある。そのような整数n擬素数と呼ばれる。

nが奇数の合成数である場合、gcd(a,n) = 1であるようなaのうち少なくとも半分はEuler witnessである。これは以下のように証明できる。{a1, a2, ..., am}をEuler liarの集合とし、aをEuler witnessとする。各i = 1,2,...,mに対して次が成り立つ:

(aai)(n1)/2=a(n1)/2ai(n1)/2=a(n1)/2(ain)≢(an)(ain)(modn)
(an)(ain)=(aain)

なので、

(aai)(n1)/2≢(aain)(modn).

が成り立つ。

これにより、各Euler liar aiに対して、a·aiがEuler witnessになる。そのため、Euler witnessの個数はEuler liarの個数以上である。それゆえ、nが合成数ならば、gcd(a,n) = 1となるaのうち少なくとも半分はEuler witnessである。

このため、失敗の確率は最大で2kである(ミラー-ラビン素数判定法の失敗の確率(最大4k)と比較されたい)。

暗号の目的で使用する場合、沢山のaでテストするほど、つまり十分大きなkを選べば、テストはより正確になる。そのためこのアルゴリズムが失敗する可能性はとても低いので、実用的な暗号への応用においてはこの方法で得られた(擬似)乱数が使われる。しかし、素数を得ることが重要であるような応用においては、テンプレート:仮リンクやPocklington[3]のような素数性を「証明」するテストを使用すべきである。

注釈

テンプレート:Reflist

参考文献

外部リンク

  • Solovay-Strassen Implementation of the Solovay–Strassen primality test in Maple

テンプレート:Numtheory-stub