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
Beispiel #2
0
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=}")
Beispiel #3
0
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")
Beispiel #5
0
#!/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))