ooo
Cute:
message = b""
for _ in range(128):
message += b"o" if random.getrandbits(1) == 1 else b"O"
M = getPrime(len(message) * 5)
S = bytes_to_long(message) % M
print("M =", M)
print('S =', S)
print('MESSAGE =', message.upper().decode("utf-8"))
The goal is to recover the message with original case. Which is a subset sum problem which I solved using a lattice, though there’s likely other ways to do it that are less sledgehammery.
# S from server
S -= any_to_int(b'O'*128)
C = matrix([[-S % M] + [-1]*128])
S = matrix([[32 * 2^(i*8) % M] for i in range(128)])
MOD = matrix([[M] + [0]*128])
M = C.stack(S.augment(2 * matrix.identity(ZZ, 128))).stack(MOD).LLL()
# find row vector with `v[0] == 0 and set(v[1:]) == {-1,1}`
Something like that, kind of translating that into Sage from memory because I solved it in REPL using my own matrix-ergonomics stuff.