class
AES:
def
__init__(
self
,key):
self
.key
=
key
self
.Ke
=
[]
self
.Kd
=
[]
self
.prepare()
def
prepare(
self
):
key_len
=
len
(
self
.key)
rounds
=
10
for
i
in
range
(
11
):
self
.Ke.append([
0
,
0
,
0
,
0
])
self
.Kd.append([
0
,
0
,
0
,
0
])
roundKeyCount
=
44
kc
=
4
tk
=
convert_to_int32(
self
.key)
index
=
None
for
i
in
range
(kc):
index
=
i >>
2
self
.Ke[index][i
%
4
]
=
tk[i]
self
.Kd[rounds
-
index][i
%
4
]
=
tk[i]
rconpointer
=
0
t
=
kc
tt
=
None
while
t < roundKeyCount:
tt
=
tk[kc
-
1
]
tk[
0
] ^
=
S[tt >>
16
&
255
] <<
24
^ S[tt >>
8
&
255
] <<
16
^ S[tt &
255
] <<
8
^ S[tt >>
24
&
255
] ^ rcon[rconpointer] <<
24
rconpointer
+
=
1
if
kc !
=
8
:
for
_i
in
range
(
1
, kc):
tk[_i] ^
=
tk[_i
-
1
]
else
:
for
_i2
in
range
(
1
, kc
/
/
2
):
tk[_i2] ^
=
tk[_i2
-
1
]
tt
=
tk[kc
/
/
2
-
1
]
tk[kc
/
/
2
] ^
=
S[tt &
255
] ^ S[tt >>
8
&
255
] <<
8
^ S[tt >>
16
&
255
] <<
16
^ S[tt >>
24
&
255
] <<
24
for
_i3
in
range
(kc
/
/
2
+
1
, kc):
tk[_i3] ^
=
tk[_i3
-
1
]
i
=
0
r
=
None
c
=
None
while
i < kc
and
t < roundKeyCount:
r
=
t >>
2
c
=
t
%
4
self
.Ke[r][c]
=
tk[i]
self
.Kd[rounds
-
r][c]
=
tk[i]
i
+
=
1
t
+
=
1
for
r
in
range
(
1
, rounds):
for
c
in
range
(
4
):
tt
=
self
.Kd[r][c]
self
.Kd[r][c]
=
U1[tt >>
24
&
255
] ^ U2[tt >>
16
&
255
] ^ U3[tt >>
8
&
255
] ^ U4[tt &
255
]
def
decrypt(
self
,ciphertext):
rounds
=
len
(
self
.Kd)
-
1
a
=
[
0
,
0
,
0
,
0
]
t
=
convert_to_int32(ciphertext)
for
i
in
range
(
4
):
t[i] ^
=
self
.Kd[
0
][i]
for
r
in
range
(
1
, rounds):
for
i
in
range
(
4
):
a[i]
=
T5[t[i] >>
24
&
255
] ^ T6[t[(i
+
3
)
%
4
] >>
16
&
255
] ^ T7[t[(i
+
2
)
%
4
] >>
8
&
255
] ^ T8[t[(i
+
1
)
%
4
] &
255
] ^
self
.Kd[r][i]
t
=
a[:]
result
=
[
0
]
*
16
tt
=
None
for
i
in
range
(
4
):
tt
=
self
.Kd[rounds][i]
result[
4
*
i]
=
(Si[t[i] >>
24
&
255
] ^ tt >>
24
) &
255
result[
4
*
i
+
1
]
=
(Si[t[(i
+
3
)
%
4
] >>
16
&
255
] ^ tt >>
16
) &
255
result[
4
*
i
+
2
]
=
(Si[t[(i
+
2
)
%
4
] >>
8
&
255
] ^ tt >>
8
) &
255
result[
4
*
i
+
3
]
=
(Si[t[(i
+
1
)
%
4
] &
255
] ^ tt) &
255
return
result