Dado que se hizo un duplicado de esta pregunta bajo la etiqueta de Python, aquí hay una implementación de Python paso a paso, gigante, que, como señala @MarkBeyers, es un enfoque razonable (siempre que el módulo no sea demasiado grande):
def baby_steps_giant_steps(a,b,p,N = None):
if not N: N = 1 + int(math.sqrt(p))
#initialize baby_steps table
baby_steps = {}
baby_step = 1
for r in range(N+1):
baby_steps[baby_step] = r
baby_step = baby_step * a % p
#now take the giant steps
giant_stride = pow(a,(p-2)*N,p)
giant_step = b
for q in range(N+1):
if giant_step in baby_steps:
return q*N + baby_steps[giant_step]
else:
giant_step = giant_step * giant_stride % p
return "No Match"
En la implementación anterior, un explícito N
se puede pasar a la pesca de un pequeño exponente incluso si p
es criptográficamente grande. Encontrará el exponente siempre que el exponente sea menor que N**2
. Cuando se omite N
, siempre se encontrará el exponente, pero no necesariamente durante su vida o con la memoria de su máquina si p
es demasiado grande.
Por ejemplo, si
p = 70606432933607
a = 100001
b = 54696545758787
luego 'pow (a, b, p)' se evalúa como 67385023448517
y
>>> baby_steps_giant_steps(a,67385023448517,p)
54696545758787
Esto llevó unos 5 segundos en mi máquina. Para el exponente y el módulo de esos tamaños, estimo (en base a los experimentos de sincronización) que la fuerza bruta habría llevado varios meses.
Su afirmación de que todos los algoritmos conocidos se ejecutan en tiempo O (C^N) para C> 1 no es correcto. No existe un algoritmo conocido que se ejecute en tiempo polinomial, pero todavía hay algoritmos conocidos que son subexponenciales. – Accipitridae
Cálculo del índice. – abc