1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| from secrets import randbits from secret import FLAG, P_known
def gen(): while True: m = randbits(63) | (1 << 62) | 1 if m > 2**62: break a = randbits(62) | 3 c = randbits(62) | 1 s0 = randbits(62) | 5 return m, a, c, s0
def LCG(m, a, c, s0, nblocks): x = s0 out = [] for _ in range(nblocks): x = (a * x + c) % m out.append(x) return out
def encrypt(m, a, c, s0, plaintext: bytes) -> bytes: padlen = (-len(plaintext)) % 8 pt = plaintext + b'\x00' * padlen blocks = [int.from_bytes(pt[i:i+8], 'big') for i in range(0, len(pt), 8)] ks = LCG(m, a, c, s0, len(blocks)) cblocks = [b ^ k for b, k in zip(blocks, ks)] return b''.join(cb.to_bytes(8, 'big') for cb in cblocks)
def main(): m, a, c, s0 = gen() cipher = encrypt(m, a, c, s0, P_known + FLAG)
C_known = cipher[:len(P_known)] C_flag = cipher[len(P_known):len(P_known) + len(FLAG)]
print("P_known =",P_known) print("C_known =", C_known.hex()) print("C_flag =", C_flag.hex())
if __name__ == "__main__": main()
'''
P_know = b'Insecure_linear_congruential_random_number!!!!!!' C_known = 44e18dfa1acd14aa790fc3bac4ca54c137bcd47bdfc2209a53b83715ecad3e29249845720588cac007bfb94f8476d91a C_flag = 1995374a5b64c6696578c1d5bdc6fa3d1e974b813436eab4348db801fb7a6703658eaa4fefa2c6fd6792beb969df8ca70ad87a4f4aea6ca0040d65a3c1e3a5bf2655cafc1e5603a171edc9aa077c0ca264677c351907f35756c14dd7ece428cb424a3804b544ccb53e99935f9bc2d8483dd7587379c99b3542c222008a
'''
|