def shiftRows(state):
for i in range(4):
state[i::4] = rotate(state[i::4],i)
def shiftRowsInv(state):
for i in range(4):
state[i::4] = rotate(state[i::4],-i)
def mixColumns(state):
for i in range(4):
column = []
# create the column by taking the same item out of each "virtual" row
for j in range(4):
column.append(state[i*4+j])
# apply mixColumn on our virtual column
mixColumn(column)
# transfer the new values back into the state table
for j in range(4):
state[i*4+j] = column[j]
def mixColumnsInv(state):
for i in range(4):
column = []
# create the column by taking the same item out of each "virtual" row
for j in range(4):
column.append(state[i*4+j])
# apply mixColumn on our virtual column
mixColumnInv(column)
# transfer the new values back into the state table
for j in range(4):
state[i*4+j] = column[j]
ZGVmIHNoaWZ0Um93cyhzdGF0ZSk6CiAgICBmb3IgaSBpbiByYW5nZSg0KToKICAgICAgICBzdGF0ZVtpOjo0XSA9IHJvdGF0ZShzdGF0ZVtpOjo0XSxpKQoKZGVmIHNoaWZ0Um93c0ludihzdGF0ZSk6CiAgICBmb3IgaSBpbiByYW5nZSg0KToKICAgICAgICBzdGF0ZVtpOjo0XSA9IHJvdGF0ZShzdGF0ZVtpOjo0XSwtaSkKCmRlZiBtaXhDb2x1bW5zKHN0YXRlKToKICAgIGZvciBpIGluIHJhbmdlKDQpOgogICAgICAgIGNvbHVtbiA9IFtdCiAgICAgICAgIyBjcmVhdGUgdGhlIGNvbHVtbiBieSB0YWtpbmcgdGhlIHNhbWUgaXRlbSBvdXQgb2YgZWFjaCAidmlydHVhbCIgcm93CiAgICAgICAgZm9yIGogaW4gcmFuZ2UoNCk6CiAgICAgICAgICAgIGNvbHVtbi5hcHBlbmQoc3RhdGVbaSo0K2pdKQoKICAgICAgICAjIGFwcGx5IG1peENvbHVtbiBvbiBvdXIgdmlydHVhbCBjb2x1bW4KICAgICAgICBtaXhDb2x1bW4oY29sdW1uKQoKICAgICAgICAjIHRyYW5zZmVyIHRoZSBuZXcgdmFsdWVzIGJhY2sgaW50byB0aGUgc3RhdGUgdGFibGUKICAgICAgICBmb3IgaiBpbiByYW5nZSg0KToKICAgICAgICAgICAgc3RhdGVbaSo0K2pdID0gY29sdW1uW2pdCiAgICAgICAgICAgIApkZWYgbWl4Q29sdW1uc0ludihzdGF0ZSk6CiAgICBmb3IgaSBpbiByYW5nZSg0KToKICAgICAgICBjb2x1bW4gPSBbXQogICAgICAgICMgY3JlYXRlIHRoZSBjb2x1bW4gYnkgdGFraW5nIHRoZSBzYW1lIGl0ZW0gb3V0IG9mIGVhY2ggInZpcnR1YWwiIHJvdwogICAgICAgIGZvciBqIGluIHJhbmdlKDQpOgogICAgICAgICAgICBjb2x1bW4uYXBwZW5kKHN0YXRlW2kqNCtqXSkKCiAgICAgICAgIyBhcHBseSBtaXhDb2x1bW4gb24gb3VyIHZpcnR1YWwgY29sdW1uCiAgICAgICAgbWl4Q29sdW1uSW52KGNvbHVtbikKCiAgICAgICAgIyB0cmFuc2ZlciB0aGUgbmV3IHZhbHVlcyBiYWNrIGludG8gdGhlIHN0YXRlIHRhYmxlCiAgICAgICAgZm9yIGogaW4gcmFuZ2UoNCk6CiAgICAgICAgICAgIHN0YXRlW2kqNCtqXSA9IGNvbHVtbltqXQ==