フェルマーの小定理の証明
定理 1
素数 とそれと互いに素な整数 について、
説明
フェルマーの小定理は、シンプルでありながら非常に多くの場所で利用される定理の一つである。オイラーによって一般化された定理もあるが、フェルマーの小定理だけで十分な場合も多い。特に有限体でのべき乗を多く扱う暗号理論などでは、不可欠な定理である。
証明
戦略: 証明はシンプルだが、それほど簡単ではない。もし が成立するなら、両辺からを消去してフェルマーの小定理を証明することができるだろう。つまり、二つの集合 と がで同じであることを示せばよい。
集合 は、有限集合であるとして、正確に個の要素を持つ。がと互いに素であるため、これらの要素をで割った余りはからまでの整数のいずれかになるだろう。そして、その余りに重複がなければ、 が成立するだろう。から異なる任意の二つの要素とを取り出して考えてみる。これらをで割った余りが同じと仮定すると、が成立する。がと互いに素であるため、両辺からを消去すると、も成立する。しかし、上記の集合でとはより大きくより小さい整数だったため、とも同じである。これは仮定に反するので、異なる任意の二つの要素をで割った余りは常に異なると言える。余りに重複がないためで、 が成立する。一方では素数であるため、と互いに素である。 両辺からを消去すると、合同式を得る。
■
以下の系も覚えておくと良い。
系
- [1] 逆元: で、乗算に対するの逆元は必ずこのように与えられる。
- [2] フェルマーのテスト: が成立しない場合、は合成数である。
ある数が素数かどうかを判定することは難しいが、合成数であることは比較的判定しやすい。注意すべきは、フェルマーのテストの逆は成立しないということである。特に逆が成立しないことを示す反例としては、カーマイケル数がある。カーマイケル数の例としては合成数だが、は常に成立する。
コード
以下は、Rでフェルマーテストを実装したもので、計算には連続べき乗法が使用された。
FPM<-function(base,power,mod) #It is equal to (base^power)%%mod
{
i<-0
if (power<0) {
while((base*i)%%mod != 1) {i=i+1}
base<-i
power<-(-power)}
if (power==0) {return(1)}
if (power==1) {return(base%%mod)}
n<-0
while(power>=2^n) {n=n+1}
A<-rep(1,n)
A[1]=base
for(i in 1:(n-1)) {A[i+1]=(A[i]^2)%%mod}
for(i in n:1) {
if(power>=2^(i-1)) {power=power-2^(i-1)}
else {A[i]=1} }
for(i in 2:n) {A[1]=(A[1]*A[i])%%mod}
return(A[1])
}
fermat.test<-function(n)
{
for(i in 2:(n-1)) {if( i!=FPM(i,n,n) ) {return(paste(i,"is a Fermat witness!"))}}
paste(n,"passes the Fermat test!")
}
fermat.test(121)
fermat.test(341) #Almost composite yields fermat witness 2, but 341=11*31 doesn't.
fermat.test(561) #Carmicheal number 561 = 3*11*17
fermat.test(1031) #1031 is a prime
fermat.test(1105) #Carmicheal number 1105 = 5*13*17
fermat.test(1729) #Carmicheal number 1729 = 7*13*19
fermat.test(41041) #Carmicheal number 41041 = 7*11*13*41
以下はコードを実行した結果である。
フェルマーテストはやのような合成数を確実に捕捉でき、のような素数を正しく通過させた。しかし、、、、のようなカーマイケル数は捕捉できなかった。カーマイケル数を捕捉するには、ミラー-ラビンテストのような方法を使う必要がある。
Silverman. (2012). A Friendly Introduction to Number Theory (4th Edition): p66. ↩︎