from Crypto.Util.number import long_to_bytes, bytes_to_long
from PIL import Image
from hackingscripts import util

def extract_bin(pixels):
    bin_stream = ""
    for p in pixels:
        r = util.lpad(bin(p[0])[2:], n, "0")
        g = util.lpad(bin(p[1])[2:], n, "0")
        b = util.lpad(bin(p[2])[2:], n, "0")
        bin_stream += r + g + b
    return bin_stream

if __name__ == "__main__":
    key_img = Image.open("key.png")
    pix = key_img.load()
    width, height = key_img.size

    pixels_p = []
    pixels_q = []
    end_p = (54, 20)
    end_q = (54, 41)

    for y in range(height):
        for x in range(width):
            if y <= end_p[1]:
                pixels_p.append(pix[x,y])
            else:
                pixels_q.append(pix[x,y])

    p = int(extract_bin(pixels_p), 2)
    q = int(extract_bin(pixels_q), 2)

    e = 0x10001
    n = p * q
    phi_n = (p - 1) * (q - 1)
    d = power_mod(e, -1, phi_n)

    with open("flag.enc", "rb") as f:
        data = f.read()
        ct = bytes_to_long(data)
        pt = power_mod(ct, d, n)
        pt_b = long_to_bytes(pt) 
        with open("decrypted.png", "wb") as g:
            g.write(pt_b)
        
