TODO

Implementation

from Crypto.Util.number import getPrime

a = 0
b = 1
p = 665179258825259
F = GF(p)
E = EllipticCurve(F,[a,b])
assert E.j_invariant() == 0
order = E.order()
print(is_prime(order))

# Embedding degree is the smallest integer such that
# (p^k - 1) % E.order() == 0
# It is vital to the MOV attack that k is small.
# For supersingular curves, k ≤	6

k = 2 
assert(p^k - 1) % order == 0

# Create something to break by picking a generator, and a private key
# We will use the MOV attack to recover d from (P,Q)
P = E.gens()[0]
Po = P.order()
d = 123456
Q = d*P

# We now take the supersingular curve E and change the finite field such that we consider E' / GF(p^k)
F2.<x> = GF(p^k)
E2 = E.change_ring(F2)
P2 = E2(P)
Q2 = E2(Q)

# Find a random point with the right behaviour
# Not all points work, so we loop until it does
while True:
    R = E2.random_point()
    Ro = R.order()
    g = gcd(Ro, Po)
    S = (Ro//g)*R
    So = S.order()
    if Po/So in ZZ and Po == So:
        break

# Generate pairings
alpha = P2.weil_pairing(S,Po)
beta = Q2.weil_pairing(S,Po)

# Solve dlog in GF(p^k) instead of E / GF(p)
dd = beta.log(alpha)
print(dd)