I don't know Y this is the only challenge I can come up with right now...
def fac(n):
return 1 if n < 1 else fac(n-1)*n
def key(i):
return fac(i+20) % 40759
ct = [20379, 22231, 40047, 22485, 8838, 20160, 34181, 28547, 27773, 27981, 22457, 4071, 4900, 1438, 11512, 33162, 15228, 29963, 834, 31108, 25327, 15360, 37694, 32607, 6735, 15813, 33138, 5482, 14601, 27053, 9987, 26176, 14530, 34510, 27096, 21242, 1849, 25880, 36392, 30711, 2542, 26769, 35566, 32658, 16871, 30924, 1425]
flag = [key(i)^v for i,v in enumerate(ct)]
print(bytes(flag))
The binary uses the Y combinator to generate the factorial mod 40759, and xors it with the ciphertext to compare against the flag.
The decompilation (in ghidra, at least) is very nasty, so instead of reversing the key gen algorithm, setting a breakpoint in gdb to dump the key values should also work.