연속제곱법 증명
📂정수론연속제곱법 증명
알고리즘
자연수 a,k,m 에 대해 b≡ak(modm) 를 다음과 같이 계산할 수 있다.
Step 1. k 의 이진법 전개
ui=0 혹은 ui=1 에 대해 다음과 같이 나타낸다.
k=i=0∑rui2i=u0+2u1+⋯+2rur
Step 2.
aa2a4a8≡(a1)2≡(a2)2≡(a4)2≡A02≡A12≡A22≡A0(modm)≡A1(modm)≡A2(modm)≡A3(modm)⋮
위와 같이 a2r≡(a2r−1)2≡Ar−12≡Ar(modm) 를 계산한다.
Step 3.
A0u0⋅A1u1⋅⋯Arur 을 계산하면 다음을 얻는다.
ak≡A0u0⋅A1u1⋅⋯Arur(modm)
설명
컴퓨터의 발전으로 거듭제곱의 계산도 빠르게 할 수 있는 시대가 왔지만 인간은 만족을 모른다. 연속제곱법은 모듈러 연산에 무지막지하게 큰 숫자를 직접 구하지 않고도 그 답을 내주는 방법이다. 한번 제곱할때마다 (modm) 으로 나눠주기 때문에 수가 m 이하로 떨어져서 계산량이 줄어드는 것이다.
예제
예를 들어 7327(mod853) 을 구한다고 해보자. 7327 에 상용로그를 취하면 327log7≈327⋅0.8450=276.315 이므로 자릿수만 무려 277 인 큰 수다. 정직하게 다 곱해서 나눗셈을 하기엔 너무 크니까 위의 알고리즘을 사용해보자. 일단 위의 알고리즘대로 327 를 이진법 전개하면 다음과 같다.
327=256+64+4+2+1=28+26+22+21+20
Step 2대로 계산해보면
772747871673276471287256≡(71)2≡(72)2≡(74)2≡(78)2≡(716)2≡(732)2≡(764)2≡(7128)2≡7≡72≡492≡6952≡2272≡3492≡6752≡1232≡6282≡7(mod853)≡49(mod853)≡2401≡695(mod853)≡227(mod853)≡349(mod853)≡675(mod853)≡123(mod853)≡628(mod853)≡298(mod853)
따라서
7327=7256⋅764⋅74⋅72⋅71=298⋅123⋅695⋅49⋅7≡286(mod853)
이다. 이 방법도 힘들다고 느낄 수는 있겠지만, 그냥 327 번을 일일이 곱하는 것에 비하면 아주 해봄직한 계산량이다.
증명
ak==≡au0+2u1+⋯+2rurau0a2u1⋯a2rurA0u0A1u1⋯Arur(modm)
■
코드
아래는 연속제곱법으로 7327(mod853) 구하는 예제 코드로, R 언어로 작성되었다. 참고로 power
옵션은 음의 정수에도 대응되며, mod
가 소수라면 power=-1
을 입력함으로써 주어진 base
의 곱셈에 대한 역원을 구할 수 있다.
FPM<-function(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])
}
FPM(7,327,853)
FPM(7,-1,11)