pollard_rho
commit
09451a3b37
|
@ -0,0 +1,66 @@
|
|||
import time
|
||||
# ро-метод Полларда для дискретного логарифмирования
|
||||
# Задача - найти такое x, что выполняется a^x ≡ b (mod p)
|
||||
|
||||
def gcd(a, b):
|
||||
r0, r1 = a, b
|
||||
x0, y0, x1, y1 = 1, 0, 0, 1
|
||||
while r1 != 0:
|
||||
q = r0 // r1
|
||||
x0, x1 = x1, x0 - q * x1
|
||||
y0, y1 = y1, y0 - q * y1
|
||||
r1, r0 = r0 % r1, r1
|
||||
if r1 > r0 >> 1:
|
||||
r1 = r0 - r1
|
||||
x1 = x0 - x1
|
||||
y1 = y0 - y1
|
||||
return x0, y0, r0
|
||||
|
||||
def v(a, b):
|
||||
"""Возвращает абсолютно наименьший вычет числа a по модулю числа b"""
|
||||
r1 = a % b
|
||||
r2 = r1 - b
|
||||
return r1 if abs(r1) < abs(r2) else r2
|
||||
|
||||
def order(a, p):
|
||||
"""Возвращает порядок числа a по модулю числа p"""
|
||||
i, x = 1, 0
|
||||
while x != 1:
|
||||
x, i = pow(a, i, p), i + 1
|
||||
return i - 1
|
||||
|
||||
def f(c, a, b, p, log):
|
||||
if c < 0:
|
||||
log[0] += 1
|
||||
return v(a * c, p)
|
||||
else:
|
||||
log[1] += 1
|
||||
return v(b * c, p)
|
||||
|
||||
def solve(a, b, m):
|
||||
d = gcd(a, m)[2]
|
||||
a1, b1, m1 = a // d, b // d, m // d
|
||||
x0 = b1 * gcd(a1, m1)[0]
|
||||
return x0 % m
|
||||
|
||||
def pollard_rho(a, b, p, ord=0):
|
||||
u, v = 1, 1
|
||||
d = c = pow(a, u, p) * pow(b, v, p) % p
|
||||
log_c, log_d = [1, 1], [1, 1]
|
||||
|
||||
while True:
|
||||
#start_time = time.perf_counter()
|
||||
c = f(c, a, b, p, log_c)
|
||||
d = f(f(d, a, b, p, log_d), a, b, p, log_d)
|
||||
#end_time = time.perf_counter()
|
||||
#print(f"Время выполнения итерации: {end_time - start_time:.10f}")
|
||||
# print(c, d, log_c, log_d)
|
||||
if c == d: break
|
||||
|
||||
if ord == 0: ord = order(a, p)
|
||||
#print(f"{log_c[0]}+{log_c[1]}x≡{log_d[0]}+{log_d[1]}x(mod{ord})")
|
||||
#print(f"{log_c[1]-log_d[1]}x≡{log_d[0]-log_c[0]}(mod{ord})")
|
||||
return solve(log_c[1]-log_d[1], log_d[0]-log_c[0], ord)
|
||||
|
||||
print(pollard_rho(2, 7, 137))
|
||||
# print(pollard_rho(2,11,50091285122438801159, ord=25045642561219400579))
|
Loading…
Reference in New Issue