This video from NUS Greyhats should help you with this challenge. Basically, in the additive group of
Denote
Hence, the secret key
We have:
With this, we can derive the secret key of Alice, then create the shared secret to retrieve the flag.
Python Implementation:
xxxxxxxxxx
from pwn import *
import json
from sage.arith.misc import inverse_mod
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
def is_pkcs7_padded(message):
padding = message[-message[-1]:]
return all(padding[i] == len(padding) for i in range(0, len(padding)))
def decrypt_flag(shared_secret: int, iv: str, ciphertext: str):
# Derive AES key from shared secret
sha1 = hashlib.sha1()
sha1.update(str(shared_secret).encode('ascii'))
key = sha1.digest()[:16]
# Decrypt flag
ciphertext = bytes.fromhex(ciphertext)
iv = bytes.fromhex(iv)
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
if is_pkcs7_padded(plaintext):
return unpad(plaintext, 16).decode('ascii')
else:
return plaintext.decode('ascii')
io = remote('socket.cryptohack.org', 13380)
alice = json.loads(io.recvline().strip().decode().split("e: ")[1])
p = int(alice['p'], 16)
g = int(alice['g'], 16)
A = int(alice['A'], 16)
bob = json.loads(io.recvline().strip().decode().split("b: ")[1])
B = int(bob['B'], 16)
ct = json.loads(io.recvline().strip().decode().split("e: ")[1])
iv = ct['iv']
enc_flag = ct['encrypted']
a = int(inverse_mod(g, p) * A) % p
shared_secret = int((a * B) % p)
print(decrypt_flag(shared_secret, iv, enc_flag))