Path: blob/master/attacks/rsa/cherkaoui_semmouni.py
2589 views
import logging1import os2import sys3from math import isqrt4from math import log5from math import sqrt67from sage.all import RR8from sage.all import ZZ910path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))11if sys.path[1] != path:12sys.path.insert(1, path)1314from shared.small_roots import herrmann_may151617def attack(N, e, beta, delta, m=1, t=None, check_bounds=True):18"""19Recovers the prime factors of a modulus and the private exponent if |p - q| is sufficiently small.20More information: Cherkaoui-Semmouni M. et al., "Cryptanalysis of RSA Variants with Primes Sharing Most Significant Bits"21:param N: the modulus22:param e: the exponent23:param beta: the parameter beta such that |p - q| <= N^beta24:param delta: the parameter delta such that d <= N^delta25:param m: the m value to use for the small roots method (default: 1)26:param t: the t value to use for the small roots method (default: automatically computed using m)27:param check_bounds: perform bounds check (default: True)28:return: a tuple containing the prime factors and the private exponent, or None if the factors could not be found29"""30alpha = log(e, N)31assert not check_bounds or delta < 2 - sqrt(2 * alpha * beta), f"Bounds check failed ({delta} < {2 - sqrt(2 * alpha * beta)})."3233x, y = ZZ["x", "y"].gens()34A = -(N - 1) ** 235f = x * y + A * x + 136X = int(2 * e * RR(N) ** (delta - 2)) # Equivalent to 2N^(alpha + delta - 2)37Y = int(RR(N) ** (2 * beta))38t = int((2 - delta - 2 * beta) / (2 * beta) * m) if t is None else t39logging.info(f"Trying {m = }, {t = }...")40for x0, y0 in herrmann_may.modular_bivariate(f, e, m, t, X, Y):41s = isqrt(y0)42d = s ** 2 + 4 * N43p = int(-s + isqrt(d)) // 244q = int(s + isqrt(d)) // 245d = int(f(x0, y0) // e)46return p, q, d4748return None495051