UofT CTF 2024

Piano Man [324 pts]

Windy, a piano prodigy, believes that RSA encryption may not provide sufficient security to safeguard his invaluable piano mastery secrets. So, he uses his musical talents to add another layer of security to the RSA encryption scheme. Now, no one will be able to figure out his secrets!

Note: The flag is UofTCTF{plaintext}.

Author: XiaoXiangjiao
music_cipher.py
musical_e.png
output.txt


We’re given three files. Here’s music_cipher.py:

# no secrets for you!
flag = ...

# Prime numbers
p = 151974537061323957822386073908385085419559026351164685426097479266890291010147521691623222013307654711435195917538910433499461592808140930995554881397135856676650008657702221890681556382541341154333619026995004346614954741516470916984007797447848200982844325683748644670322174197570545222141895743221967042369
q = 174984645401233071825665708002522121612485226530706132712010887487642973021704769474826989160974464933559818767568944237124745165979610355867977190192654030573049063822083356316183080709550520634370714336131664619311165756257899116089875225537979520325826655873483634761961805768588413832262117172840398661229
n = p * q

# a public exponent hidden away by Windy's musical talents
e = ...


# Converting the message to an integer
m = int.from_bytes(message.encode(), 'big')

# Encrypting the message: c = m^e mod n
inc_m = pow(message_int, e, n)

print(encrypted_message_int)

So it seems like this is just standard RSA, plus we’re given access to p and q. So, really, we just need to figure out what e is.

By either guessing that the musical notes encode the digits 0-9, starting from middle C, or finding this via google search, you should realize that e is just 7029307. Following that, it’s simple RSA decryption:

from Crypto.Util.number import long_to_bytes, inverse

# Given
ct = 13798492512038760070176175279601263544116956273815547670915057561532348462120753731852024424193899030774938204962799194756105401464136384387458651343975594539877218889319074841918281784494580079814736461158750759327630935335333130007375268812456855987866715978531148043248418247223808114476698088473278808360178546541128684643502788861786419871174570376835894025839847919827231356213726961581598139013383568524808876923469958771740011288404737208217659897319372970291073214528581692244433371304465252501970552162445326313782129351056851978201181794212716520630569898498364053054452320641433167009005762663177324539460
p = 151974537061323957822386073908385085419559026351164685426097479266890291010147521691623222013307654711435195917538910433499461592808140930995554881397135856676650008657702221890681556382541341154333619026995004346614954741516470916984007797447848200982844325683748644670322174197570545222141895743221967042369
q = 174984645401233071825665708002522121612485226530706132712010887487642973021704769474826989160974464933559818767568944237124745165979610355867977190192654030573049063822083356316183080709550520634370714336131664619311165756257899116089875225537979520325826655873483634761961805768588413832262117172840398661229
n = p * q

e = 7029307
phi = (p - 1) * (q - 1)
d = inverse(e, phi)

print(long_to_bytes(pow(ct, d, n)))
uoftctf{AT1d2jMCVs03xxalViU9zTyiiV1INNJY}