Rating:

Players were given a url and port to connect with. When connecting with nc, the service returned the c source for a program. This program asked the user for an input number, did multiple rounds of math on it, and compared it to a constant. If the calculated result matched the constant, it would print a win condition. The particulars are randomized each round.

Each round of math consistend of one of the following:
- Mod a constant (done initially)
- Addition mod that constant
- Subtraction mod that constant
- Multiplication mod that constant

Of those, the first three are easy to reverse. The issue is with the multiplication case. Thankfully, I noticed the constant is always prime, allowing for us to use fermat's little theorem to find the inverse.

```
from pwn import *

def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)

def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m

r = remote("bitpuzzler.wpictf.xyz", 31337)
for round in range(82):
print r.recvuntil("-----")
temp = r.recvuntil("-----")
print temp
print round, "read 1 done"
ops = []
end_comp = -1
first_mod = -1
sec_mod = -1

for i in temp.splitlines():
#if len
if "x %" in i:
first_mod = int(i.split()[5][:-1])
elif "v +" in i:
sec_mod = int(i.split()[3][:-1])
elif "pmod(x" in i:
statements = i.split(";")
for j in statements:
temp = j.split()
if len(temp) == 0:
continue
#print temp
op = temp[-2]
num = temp[-1][:-1]
#print op, num
if len(temp) == 3:
ops += [(None, None)]
else:
ops += [(op, int(num))]
elif "==" in i:
num = i.split()[2][:-1]
end_comp = int(num)
print "Starting Math"
#Not that relevant a check
assert first_mod == sec_mod
temp = end_comp
for i in reversed(ops):
op = i[0]
num = i[1]
if op == "+":
temp = (temp - num) % first_mod
elif op == "-":
temp = (temp + num) % first_mod
elif op == "*":
#plz work fermat little theorum that I totally didn't just google
inv = pow(num, first_mod - 2, first_mod)
temp = (temp * inv) % first_mod
print "got ",temp
r.send(str(temp) + "\n")
print r.recvuntil("CORRECT!")
r.interactive()
```