def ShiftRows(st, verbose=1): """ tvn: miscs array inv [-r_3_3 + st_2_3 == 0, r_2_0 - st_2_0 == 0, r_3_1 - st_0_1 == 0, -r_1_3 + st_0_3 == 0, -r_2_2 + st_0_2 == 0, r_1_0 - st_1_0 == 0, r_0_1 - st_1_1 == 0, -r_0_3 + st_3_3 == 0, r_3_0 - st_3_0 == 0, r_0_0 - st_0_0 == 0, -r_3_2 + st_1_2 == 0, r_1_1 - st_2_1 == 0, -r_0_2 + st_2_2 == 0, r_2_1 - st_3_1 == 0, -r_2_3 + st_1_3 == 0, r_1_2 - st_3_2 == 0] >>> ShiftRows([[1,3,4,255],[1,2,3,4],[7,8,10,52],[0,1,2,15]],verbose=0) [[1, 2, 10, 15], [1, 8, 2, 255], [7, 1, 4, 4], [0, 3, 3, 52]] >>> ShiftRows([[1,13,4,55],[1,22,3,4],[7,18,10,52],[0,1,2,15]],verbose=0) [[1, 22, 10, 15], [1, 18, 2, 55], [7, 1, 4, 4], [0, 13, 3, 52]] """ assert is_state(st) r = [[st[0][0], st[1][1], st[2][2], st[3][3]], [st[1][0], st[2][1], st[3][2], st[0][3]], [st[2][0], st[3][1], st[0][2], st[1][3]], [st[3][0], st[0][1], st[1][2], st[2][3]]] if verbose >= 1: #tvn traces print 'l0: r st' print 'l0: ', r, st assert is_state(r) return r
def KeyScheduleMod2(W, Nr, verbose=1): # return key_schedule assert is_key_schedule(W) assert Nr in nr_vals rk = deepcopy(W) for i in range(1, Nr): st = [W[4 * i], W[4 * i + 1], W[4 * i + 2], W[4 * i + 3]] assert is_state(st) st = InvMixColumns(st, verbose=0) rk[4 * i] = st[0] rk[4 * i + 1] = st[1] rk[4 * i + 2] = st[2] rk[4 * i + 3] = st[3] # assert 1 <= i and i <= Nr-1 and Nr = Nr% and # (for all p in Integer range 1 .. i => # (rk(4*p ) = InvMixColumns([W(4*p), W(4*p+1), W(4*p+2), W(4*p+3)))(0) and # rk(4*p+1) = InvMixColumns([W(4*p), W(4*p+1), W(4*p+2), W(4*p+3)))(1) and # rk(4*p+2) = InvMixColumns([W(4*p), W(4*p+1), W(4*p+2), W(4*p+3)))(2) and # rk(4*p+3) = InvMixColumns([W(4*p), W(4*p+1), W(4*p+2), W(4*p+3)))(3))) and # (for all j in Integer range 0 .. 3 => # (rk(j) = W(j))) and # (for all j in Integer range 4*Nr .. 4*(MAXNR+1)-1 => # (rk(j) = W(j))) assert is_key_schedule(rk) if verbose >= 1: print 'l0: W rk' print 'l0: ', W, rk return rk
def AddRoundKey(st, rk0, rk1, rk2, rk3, verbose=1): """ *nested* array r[i][j] = xor(st[i][j], rk[i][j]) """ assert is_state(st), st assert (is_word(rk0) and is_word(rk1) and is_word(rk2) and is_word(rk3)), (rk0, rk1, rk2, rk3) if verbose >= 1: print 'l1: st rk0 rk1 rk2 rk3' print 'l1: ', st, rk0, rk1, rk2, rk3 r = [[ xor(st[0][0], rk0[0]), xor(st[0][1], rk0[1]), xor(st[0][2], rk0[2]), xor(st[0][3], rk0[3]) ], [ xor(st[1][0], rk1[0]), xor(st[1][1], rk1[1]), xor(st[1][2], rk1[2]), xor(st[1][3], rk1[3]) ], [ xor(st[2][0], rk2[0]), xor(st[2][1], rk2[1]), xor(st[2][2], rk2[2]), xor(st[2][3], rk2[3]) ], [ xor(st[3][0], rk3[0]), xor(st[3][1], rk3[1]), xor(st[3][2], rk3[2]), xor(st[3][3], rk3[3]) ]] if verbose >= 1: print 'l0: st rk0 rk1 rk2 rk3 r' print 'l0: ', st, rk0, rk1, rk2, rk3, r assert is_state(r) return r
def AddRoundKey_vn(st, rk, verbose=1): """ Similar to AddRoundKey except using rk=[rk0,..,rk3]instead of 4 individual inputs rk0,..,rk3 """ assert is_state(st) if verbose >= 1: print 'l1: st rk' print 'l1: ', st, rk r = [[ xor(st[0][0], rk[0][0]), xor(st[0][1], rk[0][1]), xor(st[0][2], rk[0][2]), xor(st[0][3], rk[0][3]) ], [ xor(st[1][0], rk[1][0]), xor(st[1][1], rk[1][1]), xor(st[1][2], rk[1][2]), xor(st[1][3], rk[1][3]) ], [ xor(st[2][0], rk[2][0]), xor(st[2][1], rk[2][1]), xor(st[2][2], rk[2][2]), xor(st[2][3], rk[2][3]) ], [ xor(st[3][0], rk[3][0]), xor(st[3][1], rk[3][1]), xor(st[3][2], rk[3][2]), xor(st[3][3], rk[3][3]) ]] if verbose >= 1: print 'l0: st rk r' print 'l0: ', st, rk, r assert is_state(r) return r
def InvSubBytes(st, verbose=1): """ tvn: *nested* array r[i,j] = Si[st[i,j]] """ assert is_state(st) r = [[Si[st[0][0]], Si[st[0][1]], Si[st[0][2]], Si[st[0][3]]], [Si[st[1][0]], Si[st[1][1]], Si[st[1][2]], Si[st[1][3]]], [Si[st[2][0]], Si[st[2][1]], Si[st[2][2]], Si[st[2][3]]], [Si[st[3][0]], Si[st[3][1]], Si[st[3][2]], Si[st[3][3]]]] if verbose >= 1: #tvn traces print 'l0: r st' print 'l0: ', r, st assert is_state(r) return r
def InvShiftRows(st, verbose=1): """ tvn: miscs array inv [-r_1_3 + st_2_3 == 0, -r_0_2 + st_2_2 == 0, r_3_1 - st_2_1 == 0, -r_3_3 + st_0_3 == 0, -r_2_2 + st_0_2 == 0, -r_2_1 + st_1_1 == 0, r_0_1 - st_3_1 == 0, r_2_0 - st_2_0 == 0, r_3_0 - st_3_0 == 0, r_0_0 - st_0_0 == 0, -r_3_2 + st_1_2 == 0, r_1_1 - st_0_1 == 0, r_1_0 - st_1_0 == 0, r_2_3 - st_3_3 == 0, -r_0_3 + st_1_3 == 0, r_1_2 - st_3_2 == 0] """ assert is_state(st) if verbose >= 1: #tvn traces print 'l1: st' print 'l1: ', st r = [[st[0][0], st[3][1], st[2][2], st[1][3]], [st[1][0], st[0][1], st[3][2], st[2][3]], [st[2][0], st[1][1], st[0][2], st[3][3]], [st[3][0], st[2][1], st[1][2], st[0][3]]] if verbose >= 1: #tvn traces print 'l0: r st' print 'l0: ', r, st assert is_state(r) return r
def Block2State(t, verbose=1): """ tvn: multidim array inv r[i][j] = t[4i+j] """ assert is_block(t) #inv : should get this: r00 = t0 , r01 = t1 .... r = [[t[0], t[1], t[2], t[3]], [t[4], t[5], t[6], t[7]], [t[8], t[9], t[10], t[11]], [t[12], t[13], t[14], t[15]]] #tvn traces if verbose >= 1: print 'l0: r t' print 'l0: ', r, t assert is_state(r) return r
def State2Block(st, verbose=1): """ tvn: multidim array inv r[4*i+j] = st[i][j] """ assert is_state(st) #inv: should get this:r0 = st00 ... r = [ st[0][0], st[0][1], st[0][2], st[0][3], st[1][0], st[1][1], st[1][2], st[1][3], st[2][0], st[2][1], st[2][2], st[2][3], st[3][0], st[3][1], st[3][2], st[3][3] ] #tvn traces if verbose >= 1: print 'l0: r st' print 'l0: ', r, st assert is_block(r) return r
def InvMixColumns(st, verbose=1): assert is_state(st) r = [[ myxor([ mul(14, st[0][0], verbose=0), mul(11, st[0][1], verbose=0), mul(13, st[0][2], verbose=0), mul(9, st[0][3], verbose=0) ]), myxor([ mul(9, st[0][0], verbose=0), mul(14, st[0][1], verbose=0), mul(11, st[0][2], verbose=0), mul(13, st[0][3], verbose=0) ]), myxor([ mul(13, st[0][0], verbose=0), mul(9, st[0][1], verbose=0), mul(14, st[0][2], verbose=0), mul(11, st[0][3], verbose=0) ]), myxor([ mul(11, st[0][0], verbose=0), mul(13, st[0][1], verbose=0), mul(9, st[0][2], verbose=0), mul(14, st[0][3], verbose=0) ]) ], [ myxor([ mul(14, st[1][0], verbose=0), mul(11, st[1][1], verbose=0), mul(13, st[1][2], verbose=0), mul(9, st[1][3], verbose=0) ]), myxor([ mul(9, st[1][0], verbose=0), mul(14, st[1][1], verbose=0), mul(11, st[1][2], verbose=0), mul(13, st[1][3], verbose=0) ]), myxor([ mul(13, st[1][0], verbose=0), mul(9, st[1][1], verbose=0), mul(14, st[1][2], verbose=0), mul(11, st[1][3], verbose=0) ]), myxor([ mul(11, st[1][0], verbose=0), mul(13, st[1][1], verbose=0), mul(9, st[1][2], verbose=0), mul(14, st[1][3], verbose=0) ]) ], [ myxor([ mul(14, st[2][0], verbose=0), mul(11, st[2][1], verbose=0), mul(13, st[2][2], verbose=0), mul(9, st[2][3], verbose=0) ]), myxor([ mul(9, st[2][0], verbose=0), mul(14, st[2][1], verbose=0), mul(11, st[2][2], verbose=0), mul(13, st[2][3], verbose=0) ]), myxor([ mul(13, st[2][0], verbose=0), mul(9, st[2][1], verbose=0), mul(14, st[2][2], verbose=0), mul(11, st[2][3], verbose=0) ]), myxor([ mul(11, st[2][0], verbose=0), mul(13, st[2][1], verbose=0), mul(9, st[2][2], verbose=0), mul(14, st[2][3], verbose=0) ]) ], [ myxor([ mul(14, st[3][0], verbose=0), mul(11, st[3][1], verbose=0), mul(13, st[3][2], verbose=0), mul(9, st[3][3], verbose=0) ]), myxor([ mul(9, st[3][0], verbose=0), mul(14, st[3][1], verbose=0), mul(11, st[3][2], verbose=0), mul(13, st[3][3], verbose=0) ]), myxor([ mul(13, st[3][0], verbose=0), mul(9, st[3][1], verbose=0), mul(14, st[3][2], verbose=0), mul(11, st[3][3], verbose=0) ]), myxor([ mul(11, st[3][0], verbose=0), mul(13, st[3][1], verbose=0), mul(9, st[3][2], verbose=0), mul(14, st[3][3], verbose=0) ]) ]] assert is_state(r) if verbose >= 1: #tvn traces print 'l0: r st' print 'l0: ', r, st return r