Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/attacks/ecc/mov_attack.py
2589 views
1
import logging
2
import os
3
import sys
4
from math import gcd
5
6
from sage.all import GF
7
8
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))
9
if sys.path[1] != path:
10
sys.path.insert(1, path)
11
12
from shared.ecc import get_embedding_degree
13
14
15
def attack(P, R, max_k=6, max_tries=10):
16
"""
17
Solves the discrete logarithm problem using the MOV attack.
18
More information: Harasawa R. et al., "Comparing the MOV and FR Reductions in Elliptic Curve Cryptography" (Section 2)
19
:param P: the base point
20
:param R: the point multiplication result
21
:param max_k: the maximum value of embedding degree to try (default: 6)
22
:param max_tries: the maximum amount of times to try to find l (default: 10)
23
:return: l such that l * P == R, or None if l was not found
24
"""
25
E = P.curve()
26
q = E.base_ring().order()
27
n = P.order()
28
assert gcd(n, q) == 1, "GCD of base point order and curve base ring order should be 1."
29
30
logging.info("Calculating embedding degree...")
31
k = get_embedding_degree(q, n, max_k)
32
if k is None:
33
return None
34
35
logging.info(f"Found embedding degree {k}")
36
Ek = E.base_extend(GF(q ** k))
37
Pk = Ek(P)
38
Rk = Ek(R)
39
for i in range(max_tries):
40
Q_ = Ek.random_point()
41
m = Q_.order()
42
d = gcd(m, n)
43
Q = (m // d) * Q_
44
if Q.order() != n:
45
continue
46
47
if (alpha := Pk.weil_pairing(Q, n)) == 1:
48
continue
49
50
beta = Rk.weil_pairing(Q, n)
51
logging.info(f"Computing {beta}.log({alpha})...")
52
l = beta.log(alpha)
53
return int(l)
54
55
return None
56
57