Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/attacks/rsa/wiener_attack_common_prime.py
2589 views
1
import logging
2
import os
3
import sys
4
from math import log
5
from math import sqrt
6
7
from sage.all import RR
8
from sage.all import ZZ
9
10
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))
11
if sys.path[1] != path:
12
sys.path.insert(1, path)
13
14
from shared.small_roots import jochemsz_may_integer
15
16
17
def attack(N, e, delta=0.25, m=1, t=None, check_bounds=True):
18
"""
19
Recovers the prime factors of a modulus and the private exponent if the private exponent is too small (Common Prime RSA version).
20
More information: Jochemsz E., May A., "A Strategy for Finding Roots of Multivariate Polynomials with New Applications in Attacking RSA Variants" (Section 5)
21
:param N: the modulus
22
:param e: the public exponent
23
:param delta: a predicted bound on the private exponent (d < N^delta) (default: 0.25)
24
:param m: the m value to use for the small roots method (default: 1)
25
:param t: the t value to use for the small roots method (default: automatically computed using m)
26
:param check_bounds: perform bounds check (default: True)
27
:return: a tuple containing the prime factors and the private exponent, or None if the private exponent was not found
28
"""
29
gamma = 1 - log(e, N)
30
assert not check_bounds or delta <= 1 / 4 * (4 + 4 * gamma - sqrt(13 + 20 * gamma + 4 * gamma ** 2)), f"Bounds check failed ({delta} <= {1 / 4 * (4 + 4 * gamma - sqrt(13 + 20 * gamma + 4 * gamma ** 2))})."
31
32
x, y, z = ZZ["x", "y", "z"].gens()
33
f = e ** 2 * x ** 2 + e * x * (y + z - 2) - (y + z - 1) - (N - 1) * y * z
34
X = int(RR(N) ** delta)
35
Y = int(RR(N) ** (delta - 1 / 2) * e) # Equivalent to N^(delta + 1 / 2 - gamma)
36
Z = int(RR(N) ** (delta - 1 / 2) * e) # Equivalent to N^(delta + 1 / 2 - gamma)
37
W = int(RR(N) ** (2 * delta) * e ** 2) # Equivalent to N^(2 * delta + 2 - 2 * gamma)
38
t = int((1 / 2 + gamma - 4 * delta) / (2 * delta) * m) if t is None else t
39
logging.info(f"Trying {m = }, {t = }...")
40
strategy = jochemsz_may_integer.ExtendedStrategy([t, 0, 0])
41
for x0, y0, z0 in jochemsz_may_integer.integer_multivariate(f, m, W, [X, Y, Z], strategy):
42
d = x0
43
ka = y0
44
kb = z0
45
if pow(pow(2, e, N), d, N) == 2:
46
p = (e * d - 1) // kb + 1
47
q = (e * d - 1) // ka + 1
48
return p, q, d
49
50
return None
51
52