def __init__(self, key, block_size=16):
    if ((block_size != 16) and (block_size != 24) and (block_size != 32)):
        raise ValueError(('Invalid block size: ' + str(block_size)))
    if ((len(key) != 16) and (len(key) != 24) and (len(key) != 32)):
        raise ValueError(('Invalid key size: ' + str(len(key))))
    self.block_size = block_size
    ROUNDS = num_rounds[len(key)][block_size]
    BC = (block_size // 4)
    Ke = [([0] * BC) for i in range((ROUNDS + 1))]
    Kd = [([0] * BC) for i in range((ROUNDS + 1))]
    ROUND_KEY_COUNT = ((ROUNDS + 1) * BC)
    KC = (len(key) // 4)
    tk = []
    for i in range(0, KC):
        tk.append(((((ord(key[(i * 4)]) << 24) | (ord(key[((i * 4) + 1)]) << 16)) | (ord(key[((i * 4) + 2)]) << 8)) | ord(key[((i * 4) + 3)])))
    t = 0
    j = 0
    while ((j < KC) and (t < ROUND_KEY_COUNT)):
        Ke[(t // BC)][(t % BC)] = tk[j]
        Kd[(ROUNDS - (t // BC))][(t % BC)] = tk[j]
        j += 1
        t += 1
    tt = 0
    rconpointer = 0
    while (t < ROUND_KEY_COUNT):
        tt = tk[(KC - 1)]
        tk[0] ^= ((((((S[((tt >> 16) & 255)] & 255) << 24) ^ ((S[((tt >> 8) & 255)] & 255) << 16)) ^ ((S[(tt & 255)] & 255) << 8)) ^ (S[((tt >> 24) & 255)] & 255)) ^ ((rcon[rconpointer] & 255) << 24))
        rconpointer += 1
        if (KC != 8):
            for i in range(1, KC):
                tk[i] ^= tk[(i - 1)]
        else:
            for i in range(1, (KC // 2)):
                tk[i] ^= tk[(i - 1)]
            tt = tk[((KC // 2) - 1)]
            tk[(KC // 2)] ^= ((((S[(tt & 255)] & 255) ^ ((S[((tt >> 8) & 255)] & 255) << 8)) ^ ((S[((tt >> 16) & 255)] & 255) << 16)) ^ ((S[((tt >> 24) & 255)] & 255) << 24))
            for i in range(((KC // 2) + 1), KC):
                tk[i] ^= tk[(i - 1)]
        j = 0
        while ((j < KC) and (t < ROUND_KEY_COUNT)):
            Ke[(t // BC)][(t % BC)] = tk[j]
            Kd[(ROUNDS - (t // BC))][(t % BC)] = tk[j]
            j += 1
            t += 1
    for r in range(1, ROUNDS):
        for j in range(BC):
            tt = Kd[r][j]
            Kd[r][j] = (((U1[((tt >> 24) & 255)] ^ U2[((tt >> 16) & 255)]) ^ U3[((tt >> 8) & 255)]) ^ U4[(tt & 255)])
    self.Ke = Ke
    self.Kd = Kd
def __init__(self, key, block_size=16):
    if ((block_size != 16) and (block_size != 24) and (block_size != 32)):
        raise ValueError(('Invalid block size: ' + str(block_size)))
    if ((len(key) != 16) and (len(key) != 24) and (len(key) != 32)):
        raise ValueError(('Invalid key size: ' + str(len(key))))
    self.block_size = block_size
    ROUNDS = num_rounds[len(key)][block_size]
    BC = (block_size // 4)
    Ke = [([0] * BC) for i in range((ROUNDS + 1))]
    Kd = [([0] * BC) for i in range((ROUNDS + 1))]
    ROUND_KEY_COUNT = ((ROUNDS + 1) * BC)
    KC = (len(key) // 4)
    tk = []
    for i in range(0, KC):
        tk.append(((((ord(key[(i * 4)]) << 24) | (ord(key[((i * 4) + 1)]) << 16)) | (ord(key[((i * 4) + 2)]) << 8)) | ord(key[((i * 4) + 3)])))
    t = 0
    j = 0
    while ((j < KC) and (t < ROUND_KEY_COUNT)):
        Ke[(t // BC)][(t % BC)] = tk[j]
        Kd[(ROUNDS - (t // BC))][(t % BC)] = tk[j]
        j += 1
        t += 1
    tt = 0
    rconpointer = 0
    while (t < ROUND_KEY_COUNT):
        tt = tk[(KC - 1)]
        tk[0] ^= ((((((S[((tt >> 16) & 255)] & 255) << 24) ^ ((S[((tt >> 8) & 255)] & 255) << 16)) ^ ((S[(tt & 255)] & 255) << 8)) ^ (S[((tt >> 24) & 255)] & 255)) ^ ((rcon[rconpointer] & 255) << 24))
        rconpointer += 1
        if (KC != 8):
            for i in range(1, KC):
                tk[i] ^= tk[(i - 1)]
        else:
            for i in range(1, (KC // 2)):
                tk[i] ^= tk[(i - 1)]
            tt = tk[((KC // 2) - 1)]
            tk[(KC // 2)] ^= ((((S[(tt & 255)] & 255) ^ ((S[((tt >> 8) & 255)] & 255) << 8)) ^ ((S[((tt >> 16) & 255)] & 255) << 16)) ^ ((S[((tt >> 24) & 255)] & 255) << 24))
            for i in range(((KC // 2) + 1), KC):
                tk[i] ^= tk[(i - 1)]
        j = 0
        while ((j < KC) and (t < ROUND_KEY_COUNT)):
            Ke[(t // BC)][(t % BC)] = tk[j]
            Kd[(ROUNDS - (t // BC))][(t % BC)] = tk[j]
            j += 1
            t += 1
    for r in range(1, ROUNDS):
        for j in range(BC):
            tt = Kd[r][j]
            Kd[r][j] = (((U1[((tt >> 24) & 255)] ^ U2[((tt >> 16) & 255)]) ^ U3[((tt >> 8) & 255)]) ^ U4[(tt & 255)])
    self.Ke = Ke
    self.Kd = Kd