from Crypto.Util.number import getPrime, bytes_to_long
try:
b = int(input())
m = int.from_bytes(open("flag.txt", "rb").read(), "big")
if b * 2 < m.bit_length(): input("I'm not really sure about this");exit()
for _ in range(b):
n = getPrime(b) * getPrime(b)
c = pow(m, 65537, n)
print(f"Data {_ + 1}: {c = }, {n = }")
except: pass
For each iteration, it encrypts the message m
(derived from the contents of "flag.txt") using a newly generated RSA key and prints the encrypted result and the corresponding modulus.
⇒ Hastad broadcast attack
from sage.all import *
from pwn import *
from Crypto.Util.number import *
from gmpy2 import iroot
from math import prod
CS = []
NS = []
e = 65537
for i in range(300):
print(i)
io = remote("host3.dreamhack.games", 17137)
io.sendline(b'256')
Cs = []
Ns = []
for _ in range(256):
io.recvuntil(f'Data {_ + 1}: '.encode())
c, n = io.recvline().strip().decode().split(', ')
Cs += [int(c[4:])]
Ns += [int(n[4:])]
NS += [ZZ(prod(Ns))]
CS += [ZZ(crt(Cs, Ns))]
io.close()
me = crt(CS, NS)
m, ok = iroot(me, e)
print(long_to_bytes(m))
with open("./modulus2.txt", "w") as f:
f.write(str(prod(NS)))
with open("./ciphertext2.txt", "w") as f:
f.write(str(me))
CS
stores combined ciphertexts using CRT
NS
stores combined moduli using CRT
After collecting the ciphertexts and moduli for each set of 256 datasets:
crt(Cs, Ns)
is applied to combine the ciphertexts and moduli using the Chinese Remainder Theorem.