from sage.all import GF, matrix, vector

alphabet = "АУОИЭЫЯЮЕЁБВГДЖЗЙКЛМНПРСТФХЦЧШЩЪЬ"
char_to_int = dict(zip(alphabet, range(33)))
int_to_char = dict(zip(range(33), alphabet))
assert len(alphabet) == 33

PI = (
    252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250, 218, 35, 197, 4, 77, 
    233, 119, 240, 219, 147, 46, 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, 
    249, 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66, 139, 1, 142, 79, 
    5, 132, 2, 174, 227, 106, 143, 160, 6, 11, 237, 152, 127, 212, 211, 31, 
    235, 52, 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253, 58, 206, 204, 
    181, 112, 14, 86, 8, 12, 118, 18, 191, 114, 19, 71, 156, 183, 93, 135, 
    21, 161, 150, 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158, 178, 177, 
    50, 117, 25, 61, 255, 53, 138, 126, 109, 84, 198, 128, 195, 189, 13, 87, 
    223, 245, 36, 169, 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, 3, 
    224, 15, 236, 222, 122, 148, 176, 188, 220, 232, 40, 80, 78, 51, 10, 74, 
    167, 151, 96, 115, 30, 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, 
    173, 69, 70, 146, 39, 94, 85, 47, 140, 163, 165, 125, 105, 213, 149, 59, 
    7, 88, 179, 64, 134, 172, 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 
    225, 27, 131, 73, 76, 63, 248, 254, 141, 83, 170, 144, 202, 216, 133, 97, 
    32, 113, 103, 164, 45, 43, 9, 91, 203, 155, 37, 208, 190, 229, 108, 82, 
    89, 166, 116, 210, 230, 244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182)
PI_inv = [PI.index(i) for i in range(256)]

assert all(PI[PI_inv[i]] == i for i in range(256))

def P(f):
    return F8.from_integer(PI[f.to_integer()])

def P_inv(f):
    return F8.from_integer(PI_inv[f.to_integer()])

F = GF(2, 'x')
x = F.gen()
F8 = GF(2**8, name='x', modulus='random')

pa = [21, 22, 3, 11, 8, 13, 8, 20, 3, 8] # ПРИВЕДЕНИЕ
assert len(pa) == 10
pa = [0] * 6 + pa

ca = (216, 121, 18, 144, 93, 121, 17, 11, 114, 81, 251, 135, 200, 53, 54, 79)
cb = (216, 121, 230, 68, 93, 121, 229, 223, 114, 81, 251, 83, 200, 53, 194, 79)

H = matrix(F8, [[0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0]])

for i in range(4):
    va = vector(F8, [F8.from_integer(pa[i+4*j]) for j in range(4)])
    Ca = vector(F8, [F8.from_integer(ca[i+4*j]) for j in range(4)])
    Cb = vector(F8, [F8.from_integer(cb[i+4*j]) for j in range(4)])
    Cc = H*(Ca + Cb)
    for j in range(4):
        pt, k = [], []
        for K in range(2**8):
            key = F8.from_integer(K)
            guess = P_inv(P(va[j] + key) + Cc[j]) + key
            guess = guess.to_integer()
            if 0 <= guess and guess <= 32:
                pt.append(guess)
                k.append(K)
        print(i + 4 * j, set(pt))
