Path: blob/master/attacks/rsa/wiener_attack_common_prime.py
2589 views
import logging1import os2import sys3from math import log4from math import sqrt56from sage.all import RR7from sage.all import ZZ89path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))10if sys.path[1] != path:11sys.path.insert(1, path)1213from shared.small_roots import jochemsz_may_integer141516def attack(N, e, delta=0.25, m=1, t=None, check_bounds=True):17"""18Recovers the prime factors of a modulus and the private exponent if the private exponent is too small (Common Prime RSA version).19More information: Jochemsz E., May A., "A Strategy for Finding Roots of Multivariate Polynomials with New Applications in Attacking RSA Variants" (Section 5)20:param N: the modulus21:param e: the public exponent22:param delta: a predicted bound on the private exponent (d < N^delta) (default: 0.25)23:param m: the m value to use for the small roots method (default: 1)24:param t: the t value to use for the small roots method (default: automatically computed using m)25:param check_bounds: perform bounds check (default: True)26:return: a tuple containing the prime factors and the private exponent, or None if the private exponent was not found27"""28gamma = 1 - log(e, N)29assert 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))})."3031x, y, z = ZZ["x", "y", "z"].gens()32f = e ** 2 * x ** 2 + e * x * (y + z - 2) - (y + z - 1) - (N - 1) * y * z33X = int(RR(N) ** delta)34Y = int(RR(N) ** (delta - 1 / 2) * e) # Equivalent to N^(delta + 1 / 2 - gamma)35Z = int(RR(N) ** (delta - 1 / 2) * e) # Equivalent to N^(delta + 1 / 2 - gamma)36W = int(RR(N) ** (2 * delta) * e ** 2) # Equivalent to N^(2 * delta + 2 - 2 * gamma)37t = int((1 / 2 + gamma - 4 * delta) / (2 * delta) * m) if t is None else t38logging.info(f"Trying {m = }, {t = }...")39strategy = jochemsz_may_integer.ExtendedStrategy([t, 0, 0])40for x0, y0, z0 in jochemsz_may_integer.integer_multivariate(f, m, W, [X, Y, Z], strategy):41d = x042ka = y043kb = z044if pow(pow(2, e, N), d, N) == 2:45p = (e * d - 1) // kb + 146q = (e * d - 1) // ka + 147return p, q, d4849return None505152