# Cry - Morphing Time
Elgamal encryption & decryption
``` pythondef encrypt_setup(p, g, A):    def encrypt(m):        k = randint(2, p - 1)        c1 = pow(g, k, p)        c2 = pow(A, k, p)        c2 = (m * c2) % p
        return c1, c2
    return encrypt
def decrypt_setup(a, p):    def decrypt(c1, c2):        m = pow(c1, a, p)        m = pow(m, -1, p)        m = (c2 * m) % p
        return m
    return decrypt```
Oracle
```pythonm = decrypt((c1 * c1_) % p, (c2 * c2_) % p)```
looking at how the encryption works
c1 = g^k mod pc2 = g^ak * m mod p
during the decryption process
c1 --> g^-ak
so when c1 * c2 mod p will return m because c1 is modular inverse of c2/m (c2 before multiplied by m)
so the oracle formula become
(g^k * c1_)^-a * g^ak * m * c2_ mod p = m
g^-ak * c1^-a * g^ak * m * c2_ mod p = m
now our goal is to find c1_ and c2_ value so that it will cancel each other (modular inverse)
we know p, g, A where A is g^a mod p, based on this value we can solve the equation with A
we have to make c1_^-a --> g^-a and c2_ --> A (g^a mod p) those value will cancel each other so the final equation is
g^-ak * g^-a * g^ak * g^a * m mod p = m
c1_^-a = g^-a so c1_ = g = 2, c2_ = A = g^a mod p
we get the msg
```>>> long_to_bytes(4207564671745017061459002831657829961985417520046041547841180336049591837607722234018405874709347956760957)b'uiuctf{h0m0m0rpi5sms_ar3_v3ry_fun!!11!!11!!}'```