Last active
November 27, 2020 01:46
-
-
Save maojui/61c10d93db220e9c77b20d274969e363 to your computer and use it in GitHub Desktop.
Find nth_root on modulo p
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def cube_root(c, q): | |
F = FiniteField(q) | |
R.<x> = PolynomialRing(F,'x') | |
while 1: | |
a = F.random_element() | |
b = F.random_element() | |
fx = x**3 - a*x**2 + b*x - c | |
fc = list(factor(fx)) | |
if len(fc) <= 1: | |
root = pow(x, (q**2+q+1)//3, fx) | |
root %= x | |
return int(root) | |
def cube_roots(c,mod): | |
c = c % mod | |
rems = [] | |
if gcd( (mod-1), 3) == 1: | |
d = inverse_mod(3, mod - 1) | |
rems.append( int(pow(c, d, mod)) ) | |
else: | |
g = GF(mod).multiplicative_generator() | |
u = int(g ** ((mod-1)//3)) | |
r1 = int(cube_root(c, mod)) | |
for i in range(3): | |
rems.append( int(r1 * pow(u, i, mod) % mod) ) | |
for m in rems : | |
if pow(m,3,p) != c : | |
print('%d = m^3 mod %d, m has no integer solutions.' % (c,p) ) | |
exit() | |
return rems | |
if __name__ == '__main__': | |
# Debug | |
# p = random_prime(2^128-1,False,2^127) | |
# x = randint(2^127,2^128) % p | |
# c = pow(x, 3, p) | |
# print(f"{x}^{3} mod {p} = {c}") | |
# rems = cube_roots(c%p, p) | |
# print(f'x = {rems}') | |
# assert x in rems | |
print("x^3 mod p = c") | |
c = int(input("c = ")) | |
p = int(input("p = ")) | |
rems = cube_roots(c%p,p) | |
print(f"x = {rems}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_phi(N): | |
phi = N | |
for f in factor(N): | |
phi = phi * (1 - 1 / f[0]) | |
return phi | |
def get_roots(r,c,mod): | |
rems = [] | |
if gcd( get_phi(mod), r) == 1: | |
d = inverse_mod( r,get_phi(mod) ) | |
rems.append(int(pow(c, d, mod))) | |
else: | |
g = GF(mod).multiplicative_generator() | |
u = int(g ** ((mod-1)/r)) | |
r1 = int(rth_root(r,c, mod)) | |
for i in range(r): | |
rems.append( int(r1 * pow(u, i, mod) % mod) ) | |
return rems | |
def rth_root(c,p,root): | |
rems = get_roots(root, c%p, p) | |
for m in rems : | |
if pow(m,root,p) != c : | |
print('%d = m^%d mod %d, m has no integer solutions.' % (c,root,p) ) | |
exit() | |
return rems | |
if __name__ == "__main__": | |
# # Debug | |
# p = random_prime(2^128-1,False,2^127) | |
# x = randint(2^127,2^128) % p | |
# e = random_prime(15) | |
# c = pow(x,e,p) | |
# print(f"{x}^{e} mod {p} = {c}") | |
# rems = rth_root(c,p,e) | |
# print(f'x = {rems}') | |
# assert x in rems | |
# Example | |
print("x^e mod p = c") | |
c = int(input("c = ")) | |
p = int(input("p = ")) | |
e = int(input("e = ")) | |
rems = rth_root(c,p,e) | |
print(f"x = {rems}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
z = Mod(c, n) | |
print(sqrt(z)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment