├── README.md ├── partial_key_exposure_attack.py └── wiener.py /README.md: -------------------------------------------------------------------------------- 1 | # Some RSA attacks with sage 2 | 3 | ## partial_key_exposure_attack.py 4 | My implementation of [http://honors.cs.umd.edu/reports/lowexprsa.pdf](http://honors.cs.umd.edu/reports/lowexprsa.pdf) 5 | 6 | ## wiener.py 7 | Sage implementation of Wiener's Attack mentioned in [Twenty Years of Attacks on the RSA Crypto system](https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf) 8 | 9 | -------------------------------------------------------------------------------- /partial_key_exposure_attack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sage -python 2 | 3 | # by lwc 4 | # 2016/09/22 5 | 6 | from sage.all import * 7 | 8 | def find_p_Coppersmith(n, pLow, lowerBitsNum, beta=0.5): 9 | x = PolynomialRing(Zmod(n), names='x').gen() 10 | nbits = n.bit_length() 11 | 12 | f = 2**lowerBitsNum*x + pLow 13 | f = f.monic() 14 | roots = f.small_roots(X=2**(nbits//2-lowerBitsNum), beta=beta) 15 | if roots: 16 | x0 = roots[0] 17 | p = gcd(2**lowerBitsNum*x0 + pLow, n) 18 | return ZZ(p) 19 | 20 | def find_p(n, e, dLow, beta=0.5): 21 | X = var('X') 22 | lowerBitsNum = dLow.bit_length() 23 | 24 | for k in xrange(1, e+1): 25 | results = solve_mod([e*dLow*X - k*X*(n-X+1) + k*n == X], 2**lowerBitsNum) 26 | for x in results: 27 | pLow = ZZ(x[0]) 28 | p = find_p_Coppersmith(n, pLow, lowerBitsNum) 29 | if p: 30 | return p 31 | 32 | def partial_key_exposure_attack(n, e, dLow, beta=0.5): 33 | p = find_p(n, e, dLow, beta) 34 | assert p is not None and n % p == 0, 'fail' 35 | q = n / p 36 | return p, q 37 | 38 | n = 123541066875660402939610015253549618669091153006444623444081648798612931426804474097249983622908131771026653322601466480170685973651622700515979315988600405563682920330486664845273165214922371767569956347920192959023447480720231820595590003596802409832935911909527048717061219934819426128006895966231433690709 39 | e = 97 40 | 41 | beta = 0.5 42 | dLow = 48553333005218622988737502487331247543207235050962932759743329631099614121360173210513133 43 | p, q = partial_key_exposure_attack(n, e, dLow, beta) 44 | d = inverse_mod(e, (p-1)*(q-1)) 45 | print 'p =', p 46 | print 'q =', q 47 | print 'd =', d 48 | -------------------------------------------------------------------------------- /wiener.py: -------------------------------------------------------------------------------- 1 | # by lwc 2 | # 2016/11/14 3 | 4 | from sage.all import * 5 | 6 | def wiener(n, e): 7 | """Wiener's attack""" 8 | n = Integer(n) 9 | e = Integer(e) 10 | for f in (e / n).continued_fraction().convergents()[1:]: 11 | k, d = f.numerator(), f.denominator() 12 | phi = ((e * d) - 1) / k 13 | b = -(n - phi + 1) 14 | dis_sqrt = sqrt(b * b - 4 * n) 15 | if dis_sqrt.is_integer(): 16 | p = (-b + dis_sqrt) / 2 17 | q = (-b - dis_sqrt) / 2 18 | if p < q: 19 | p, q = q, p 20 | return (p, q, d) 21 | 22 | --------------------------------------------------------------------------------