-
Notifications
You must be signed in to change notification settings - Fork 121
/
smart_attack.py
33 lines (28 loc) · 986 Bytes
/
smart_attack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from sage.all import EllipticCurve
from sage.all import Qp
from sage.all import ZZ
# Lifts a point to the p-adic numbers.
def _lift(E, P, gf):
x, y = map(ZZ, P.xy())
for point_ in E.lift_x(x, all=True):
_, y_ = map(gf, point_.xy())
if y == y_:
return point_
def attack(G, P):
"""
Solves the discrete logarithm problem using Smart's attack.
More information: Smart N. P., "The discrete logarithm problem on elliptic curves of trace one"
:param G: the base point
:param P: the point multiplication result
:return: l such that l * G == P
"""
E = G.curve()
gf = E.base_ring()
p = gf.order()
assert E.trace_of_frobenius() == 1, f"Curve should have trace of Frobenius = 1."
E = EllipticCurve(Qp(p), [int(a) + p * ZZ.random_element(1, p) for a in E.a_invariants()])
G = p * _lift(E, G, gf)
P = p * _lift(E, P, gf)
Gx, Gy = G.xy()
Px, Py = P.xy()
return int(gf((Px / Py) / (Gx / Gy)))