Path: blob/master/attacks/rsa/extended_wiener_attack.py
2589 views
import os1import sys23from sage.all import RR4from sage.all import ZZ5from sage.all import continued_fraction67path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))8if sys.path[1] != path:9sys.path.insert(1, path)1011from attacks.factorization import known_phi121314def attack(n, e, max_s=20000, max_r=100, max_t=100):15"""16Recovers the prime factors if the private exponent is too small.17More information: Dujella A., "Continued fractions and RSA with small secret exponent"18:param n: the modulus19:param e: the public exponent20:param max_s: the amount of s values to try (default: 20000)21:param max_r: the amount of r values to try for each s value (default: 100)22:param max_t: the amount of t values to try for each s value (default: 100)23:return: a tuple containing the prime factors and the private exponent, or None if the private exponent was not found24"""25i_n = ZZ(n)26i_e = ZZ(e)27threshold = i_e / i_n + (RR(2.122) * i_e) / (i_n * i_n.sqrt())28convergents = continued_fraction(i_e / i_n).convergents()29for i in range(1, len(convergents) - 2, 2):30if convergents[i + 2] < threshold < convergents[i]:31m = i32break33else:34return None3536for s in range(max_s):37for r in range(max_r):38k = r * convergents[m + 1].numerator() + s * convergents[m + 1].numerator()39d = r * convergents[m + 1].denominator() + s * convergents[m + 1].denominator()40if pow(pow(2, e, n), d, n) != 2:41continue4243phi = (e * d - 1) // k44factors = known_phi.factorize(n, phi)45if factors:46return *factors, int(d)4748for t in range(max_t):49k = s * convergents[m + 2].numerator() - t * convergents[m + 1].numerator()50d = s * convergents[m + 2].denominator() - t * convergents[m + 1].denominator()51if pow(pow(2, e, n), d, n) != 2:52continue5354phi = (e * d - 1) // k55factors = known_phi.factorize(n, phi)56if factors:57return *factors, int(d)585960