밀러 - 라빈 소수 판정법

MTsauRus·2023년 8월 12일
0

알고리즘

목록 보기
1/3
post-thumbnail


소수 판정법 이해에 필요한 기초 지식이다. 해당 판정법은 페르마의 소정리에 기반을 둔다. pp는 홀수인 소수이고, aa는 양의 정수이다.
페르마의 소정리 2)에 의해 ap1=a2s×d1(mod p)a^{p-1}=a^{2^{s}\times d}\equiv1(mod\ p)가 성립한다. 우변의 1을 좌변으로 넘긴 후 전개하면 다음과 같다.

a2s×d1a^{2^{s}\times d}-1를 다음과 같이 변형할 수 있다.

a2s×d1=(a2s1×d+1)(a2s2×d+1)(a2s3×d+1)(ad+1)(ad1)a^{2^{s}\times d}-1= (a^{2^{s-1}\times d}+1)(a^{2^{s-2}\times d}+1)(a^{2^{s-3}\times d}+1)\cdots(a^{d}+1)(a^{d}-1)

a2s×d1a^{2^{s}\times d}-1의 각 인수가 pp에 의해 나누어 떨어진다면, 즉 a2s1×da^{2^{s-1}\times d}, a2s2×da^{2^{s-2}\times d} \cdots 등을 pp로 나누었을 때의 나머지가 -1이라면 pp는 아마 소수일 것이다. 마지막 항(ad1)(a^{d} - 1)의 경우, 나머지가 1이라면 pp는 아마 소수일 것이다.

구현은 생각보다 간단하다.

def miller_rabin(a, p):
    k = p - 1
    while True:
        tmp = power_mod(a, k, p) # a^(p-1) % p
        if tmp == p - 1: # a^(k) % p == -1
            return True
        k //= 2 # a^(s-1), a^(s-2)... 
        if k % 2 == 1: # k가 홀수라면, 즉 2^s * d에서 d만 남았다면
            break
    # (a^d + 1)(a^d - 1)만 남아 있음.
    return (tmp == p - 1 or tmp == 1)

int 범위의 경우, aa에 2, 7, 61을, long long의 경우 37 이하의 모든 소수에 대해 위의 구현이 성립한다면 pp는 소수임이 증명되었다고 한다.

profile
생각날 때 쓰는 ps일기장

0개의 댓글