Skip to content

Instantly share code, notes, and snippets.

@igorvanloo
Created April 14, 2022 16:38
Show Gist options
  • Select an option

  • Save igorvanloo/e44662108e702daec1876820ea889fbb to your computer and use it in GitHub Desktop.

Select an option

Save igorvanloo/e44662108e702daec1876820ea889fbb to your computer and use it in GitHub Desktop.
Tonelli-Shanks Algorithm
def legendre_symbol(a, p):
t = pow(a, (p-1)//2, p)
if t == p - 1:
return -1
return t
def tonelli_shanks(a, p):
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return 0
elif p % 4 == 3:
return pow(a, (p + 1)//4, p)
s = p - 1
e = 0
while s % 2 == 0:
s /= 2
e += 1
s = int(s)
n = 2
while legendre_symbol(n, p) != -1:
n += 1
x = pow(a, (s + 1)//2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in range(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2**(r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment