Skip to content

Mini-RSA

Crypto - Easy

Description: Decrypting RSA just got a bit more interesting! Don’t forget, you can always simplify 'e'!

Given: p, q, e, c

Directly trying to decrypt using these values results in an error:

from Crypto.Util.number import inverse
from Crypto.Util.number import long_to_bytes

p = 13013195056445077675245767987987229724588379930923318266833492046660374216223334270611792324721132438307229159984813414250922197169316235737830919431103659
q = 12930920340230371085700418586571062330546634389230084495106445639925420450591673769061692508272948388121114376587634872733055494744188467315949429674451947
e = 100
c = 110886661313947816173908115981658339620571560526918289660960169252288610286791854093943168159755480182507940709690550773331393090271095840939446837160952597445303632714973330299193541279697398541542792961783509392552656152310579707871010170438249002720983123078577661000629914516027258039187727198233299377218

n = p * q
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

ValueError: base is not invertible for the given modulus

This is probably because e isn't prime and isn't coprime with phi

Implement the algo in this blog:

from Crypto.Util.number import inverse, GCD
from Crypto.Util.number import long_to_bytes

p = 13013195056445077675245767987987229724588379930923318266833492046660374216223334270611792324721132438307229159984813414250922197169316235737830919431103659
q = 12930920340230371085700418586571062330546634389230084495106445639925420450591673769061692508272948388121114376587634872733055494744188467315949429674451947
e = 100
c = 110886661313947816173908115981658339620571560526918289660960169252288610286791854093943168159755480182507940709690550773331393090271095840939446837160952597445303632714973330299193541279697398541542792961783509392552656152310579707871010170438249002720983123078577661000629914516027258039187727198233299377218

n = p * q
phi = (p - 1) * (q - 1)
max = 100

k = 1
while GCD(e, phi//k) != 1:
    k = k * GCD(e, phi//k)

d = inverse(e, phi//k)
g = pow(c, d, n)
for a in range(1, max):
    r = pow(a, phi//k, n)
    m = (r * g) % n
    print(long_to_bytes(m))

This prints possible plaintexts, including the flag