def get_lowest_cf(p, d, x): #find convergent cfs cfp = continued_fraction_periodic(p, d) fracs = list(continued_fraction_convergents(cfp)) #get list of denominators denoms = [int(f.q) for f in fracs] try: val = max([num for num in denoms if num < x]) except ValueError: raise ('List is empty!') return val
def wieners_attack(e: int, n: int): """ returns d """ #pylint: disable=import-outside-toplevel #lazy imports to avoid slowing down initial load from sympy.ntheory.continued_fraction import continued_fraction_convergents, continued_fraction_iterator from sympy.core.numbers import Rational c = 2 convergents = continued_fraction_convergents(continued_fraction_iterator(Rational(e, n))) for convergent in convergents: d = convergent.denominator() p = pow(c, d, n) if pow(p, e, n) == c: return d raise ValueError(f"Couldn't find d for {e=} and {n=}")
def wiener_attack_rsa(public_key): N = public_key[0] e = public_key[1] # cf = continued_fraction_periodic(e, N) convergents = list(continued_fraction_convergents(cf)) polynomial_power = 0 for i in convergents: polynomial_power += 1 n, d = fraction(i) if n != 0: exp = ((e * d) - 1) / n n2, d2 = fraction(exp) #if d2 == 1: factors = (np.roots([1, -((N - n2) + 1), N])) return factors
def exploit(cipher, parameters): from sympy.core.numbers import Rational from sympy.ntheory.continued_fraction import continued_fraction_convergents, continued_fraction_iterator from Crypto.Util.number import bytes_to_long, long_to_bytes e = parameters["e"] n = parameters["n"] maxConvergents = 10000 testMessage = 4711 testCipher = pow(testMessage, e, n) convergents = continued_fraction_convergents(continued_fraction_iterator(Rational(e, n))) i = 0 d = None while i < maxConvergents: try: c = next(convergents) d = c.q if pow(testCipher, d, n) == testMessage: break except StopIteration: assert False, "No more convergents. Key should have been found by now." i += 1 plain = long_to_bytes(pow(bytes_to_long(cipher), d, int(parameters["n"]))) return plain.decode("utf-8")
#!/usr/bin/python3 from Crypto.PublicKey import RSA from sympy import Symbol, Rational from sympy.solvers import solve from sympy.ntheory.continued_fraction import continued_fraction_iterator, continued_fraction_convergents with open('key.pem', 'rb') as f: data = f.read() key = RSA.importKey(data) cf = continued_fraction_iterator(Rational(key.e, key.n)) conv = continued_fraction_convergents(cf) for x in conv: if (x == 0): continue k = x.p d = x.q phi = (key.e * d - 1) // k y = Symbol('y', integer=True) roots = solve(y**2 - ((key.n - phi) + 1) * y + key.n, y) if (roots and key.n == roots[0] * roots[1]): print("FACTORED") break d = Rational(key.e).invert((roots[0] - 1) * (roots[1] - 1))