CTF Crypto task를 풀다 보면, 간혹
Tonelli-Shanks Algorithm은
주어진 홀수인 소수
인지 확인한다. 만약 아니라면 제곱근이 존재하지 않는다. 인 홀수 와 음이 아닌 정수 를 구한다. 로 를 초기화한 후 이 아닐 때까지 를 증가시키는 과정을 반복한다. 종료 시점의 값을 라고 정의한다.- 다음과 같이 변수에 값을 대입한다.
- 다음 과정을 반복한다.
이면 을 출력하고 종료한다. 이면 을 출력하고 종료한다. 과 를 만족하는 최소의 자연수 를 찾는다.
Tonelli-Shanks 알고리즘의 정당성 증명
알고리즘의 정당성 증명은 다음과 같이 기술할 수 있다.
우선 다음의 두 명제를 확인하자.
Claim 1.
에서 0이 아닌 quadratic residue는 정확히 개 존재한다.
따라서
Claim 2.
- '
이 에서 quadratic residue이다'와 는 동치이다.
이는 페르마 소정리에 의해
변수들의 초기값을 다시 기술하면 다음과 같다.
상기된 초기값에 관해 다음과 같은 사실을 알 수 있다.
는 quadratic non-residue이므로 이 성립한다. 은 quadratic residue이므로 이 성립한다. 이다.
한 번의 반복에서
은 과 를 만족하는 최소의 자연수
이러한 정의에 따라 변화한 값에 대해서도 초기값에서와 동일한 성질들이 몇가지 성립함을 확인할 수 있다.
이때
Tonelli-Shanks 알고리즘의 시간복잡도 증명
위에서 기술한 알고리즘의 동작 과정 중 1., 2., 4.는 거듭제곱 연산과 대입 연산만으로 구성되므로 분할정복을 이용한 거듭제곱을 사용하면
3.의 경우 가장 작은 quadratic non-residue
5.에서
따라서 3.의 소요 시간을 평균적인 상수 시간으로 가정한다면
Tonelli-Shanks 알고리즘의 구현
CTF 암호학에서 자주 사용되는 언어는 SageMath, Python이다. SageMath에서는 sage.rings.finite_rings.integer_mod의 square_root_mod_prime을 통해 간단하게 Tonelli-Shanks 알고리즘을 사용할 수 있으며, square_root_mod_prime_power와 같은 확장 또한 사용 가능하다. 따라서 개인적으로 SageMath를 이용하길 권장하나, 그렇지 못하는 경우를 위해 Python에서 Tonelli-Shanks를 구현하는 코드를 간단하게 소개한다.
def tonelli_shanks(n,p):
def isQR(x,p):# check whether x is quadratic residue
return pow(x,(p-1)//2,p)==1
# (1.)
if not isQR(n,p):
return -1
# (2.)
Q,S=p-1,0
while Q%2==0:
S+=1
Q//=2
# (3.)
z=None
for x in range(2,p):
if not isQR(x,p):
z=x
break
# (4.)
M,c,t,R=S,pow(z,Q,p),pow(n,Q,p),pow(n,(Q+1)//2,p)
# (5.)
while True:
if t==0:
return 0
elif t==1:
return R
k=t*t%p
ii=None
for i in range(1,M):
if k==1:
ii=i
break
k*=k
k%=p
b=pow(c,2**(M-i-1),p)%p
M=ii%p
c=b*b%p
t=t*c%p
R=R*b%p
# test
if __name__=='__main__':
n,p=map(int,input().split())
print("STARTED")
print(tonelli_shanks(n,p))
'ctf' 카테고리의 다른 글
2022 Fall GoN Open Qual CTF Write-up (1) | 2022.08.28 |
---|---|
Introduction and Proof of Baby-step Giant-step Algorithm (BSGS) (3) | 2022.08.13 |
HackTheon 2022 Writeup (0) | 2022.08.11 |
CTF 암호학을 위한 기초적 확률 지식 / Basic Knowledge about Probability for CTF (0) | 2022.06.11 |
페르마 인수분해(Fermat Factorization) (0) | 2022.05.22 |