forked from jvdsn/crypto-attacks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfrey_ruck_attack.py
More file actions
52 lines (41 loc) · 1.49 KB
/
Copy pathfrey_ruck_attack.py
File metadata and controls
52 lines (41 loc) · 1.49 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import logging
from math import gcd
from math import lcm
from sage.all import GF
from sage.all import crt
def attack(base, multiplication_result):
"""
Solves the discrete logarithm problem using the Frey-Ruck attack.
:param base: the base point
:param multiplication_result: the point multiplication result
:return: l such that l * base == multiplication_result
"""
curve = base.curve()
p = curve.base_ring().order()
n = base.order()
assert gcd(n, p) == 1, "GCD of curve base ring order and generator order should be 1."
logging.debug("Calculating embedding degree...")
# Embedding degree k.
k = 1
while (p ** k - 1) % n != 0:
k += 1
logging.debug(f"Found embedding degree {k}, computing discrete logarithm...")
pairing_curve = curve.base_extend(GF(p ** k))
pairing_base = pairing_curve(base)
pairing_multiplication_result = pairing_curve(multiplication_result)
ls = []
ds = []
while lcm(*ds) != n:
rand = pairing_curve.random_point()
o = rand.order()
d = gcd(o, n)
rand = (o // d) * rand
assert rand.order() == d
u = pairing_base.tate_pairing(rand, n, k)
v = pairing_multiplication_result.tate_pairing(rand, n, k)
logging.debug(f"Calculating ({v}).log({u}) modulo {d}")
l = v.log(u)
logging.debug(f"Found discrete log {l} modulo {d}")
ls.append(int(l))
ds.append(int(d))
return ls[0] if len(ls) == 1 else int(crt(ls, ds))