]> jfr.im git - yt-dlp.git/blame - youtube_dlc/aes.py
[skip travis] renaming
[yt-dlp.git] / youtube_dlc / aes.py
CommitLineData
dcddc10a
PH
1from __future__ import unicode_literals
2
f3bcebb1 3from math import ceil
4
cf282071 5from .compat import compat_b64decode
0012690a 6from .utils import bytes_to_intlist, intlist_to_bytes
48ea9cea 7
f3bcebb1 8BLOCK_SIZE_BYTES = 16
9
5f6a1245 10
f3bcebb1 11def aes_ctr_decrypt(data, key, counter):
12 """
13 Decrypt with aes in counter mode
5f6a1245 14
f3bcebb1 15 @param {int[]} data cipher
16 @param {int[]} key 16/24/32-Byte cipher key
17 @param {instance} counter Instance whose next_value function (@returns {int[]} 16-Byte block)
18 returns the next counter block
19 @returns {int[]} decrypted data
20 """
21 expanded_key = key_expansion(key)
6e74bc41 22 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
5f6a1245
JW
23
24 decrypted_data = []
f3bcebb1 25 for i in range(block_count):
26 counter_block = counter.next_value()
2514d263
JW
27 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
28 block += [0] * (BLOCK_SIZE_BYTES - len(block))
5f6a1245 29
f3bcebb1 30 cipher_counter_block = aes_encrypt(counter_block, expanded_key)
31 decrypted_data += xor(block, cipher_counter_block)
32 decrypted_data = decrypted_data[:len(data)]
5f6a1245 33
f3bcebb1 34 return decrypted_data
35
5f6a1245 36
c8434e83 37def aes_cbc_decrypt(data, key, iv):
38 """
39 Decrypt with aes in CBC mode
5f6a1245 40
c8434e83 41 @param {int[]} data cipher
42 @param {int[]} key 16/24/32-Byte cipher key
43 @param {int[]} iv 16-Byte IV
44 @returns {int[]} decrypted data
45 """
46 expanded_key = key_expansion(key)
47 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
5f6a1245
JW
48
49 decrypted_data = []
c8434e83 50 previous_cipher_block = iv
51 for i in range(block_count):
2514d263
JW
52 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
53 block += [0] * (BLOCK_SIZE_BYTES - len(block))
5f6a1245 54
c8434e83 55 decrypted_block = aes_decrypt(block, expanded_key)
56 decrypted_data += xor(decrypted_block, previous_cipher_block)
57 previous_cipher_block = block
58 decrypted_data = decrypted_data[:len(data)]
5f6a1245 59
c8434e83 60 return decrypted_data
61
5f6a1245 62
c9619f0a
YCH
63def aes_cbc_encrypt(data, key, iv):
64 """
65 Encrypt with aes in CBC mode. Using PKCS#7 padding
66
67 @param {int[]} data cleartext
68 @param {int[]} key 16/24/32-Byte cipher key
69 @param {int[]} iv 16-Byte IV
70 @returns {int[]} encrypted data
71 """
72 expanded_key = key_expansion(key)
73 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES))
74
75 encrypted_data = []
76 previous_cipher_block = iv
77 for i in range(block_count):
78 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]
79 remaining_length = BLOCK_SIZE_BYTES - len(block)
80 block += [remaining_length] * remaining_length
81 mixed_block = xor(block, previous_cipher_block)
82
83 encrypted_block = aes_encrypt(mixed_block, expanded_key)
84 encrypted_data += encrypted_block
85
86 previous_cipher_block = encrypted_block
87
88 return encrypted_data
89
90
f3bcebb1 91def key_expansion(data):
92 """
93 Generate key schedule
5f6a1245 94
f3bcebb1 95 @param {int[]} data 16/24/32-Byte cipher key
5f6a1245 96 @returns {int[]} 176/208/240-Byte expanded key
f3bcebb1 97 """
5f6a1245 98 data = data[:] # copy
f3bcebb1 99 rcon_iteration = 1
100 key_size_bytes = len(data)
48ea9cea 101 expanded_key_size_bytes = (key_size_bytes // 4 + 7) * BLOCK_SIZE_BYTES
5f6a1245 102
f3bcebb1 103 while len(data) < expanded_key_size_bytes:
104 temp = data[-4:]
105 temp = key_schedule_core(temp, rcon_iteration)
106 rcon_iteration += 1
2514d263 107 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
5f6a1245 108
f3bcebb1 109 for _ in range(3):
110 temp = data[-4:]
2514d263 111 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
5f6a1245 112
f3bcebb1 113 if key_size_bytes == 32:
114 temp = data[-4:]
115 temp = sub_bytes(temp)
2514d263 116 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
5f6a1245 117
b74e86f4 118 for _ in range(3 if key_size_bytes == 32 else 2 if key_size_bytes == 24 else 0):
f3bcebb1 119 temp = data[-4:]
2514d263 120 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes])
f3bcebb1 121 data = data[:expanded_key_size_bytes]
5f6a1245 122
f3bcebb1 123 return data
124
5f6a1245 125
f3bcebb1 126def aes_encrypt(data, expanded_key):
127 """
128 Encrypt one block with aes
5f6a1245 129
f3bcebb1 130 @param {int[]} data 16-Byte state
5f6a1245 131 @param {int[]} expanded_key 176/208/240-Byte expanded key
f3bcebb1 132 @returns {int[]} 16-Byte cipher
133 """
48ea9cea 134 rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1
c8434e83 135
f3bcebb1 136 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES])
2514d263 137 for i in range(1, rounds + 1):
f3bcebb1 138 data = sub_bytes(data)
139 data = shift_rows(data)
140 if i != rounds:
141 data = mix_columns(data)
2514d263 142 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES])
c8434e83 143
144 return data
145
5f6a1245 146
c8434e83 147def aes_decrypt(data, expanded_key):
148 """
149 Decrypt one block with aes
5f6a1245 150
c8434e83 151 @param {int[]} data 16-Byte cipher
152 @param {int[]} expanded_key 176/208/240-Byte expanded key
153 @returns {int[]} 16-Byte state
154 """
155 rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1
5f6a1245 156
c8434e83 157 for i in range(rounds, 0, -1):
2514d263 158 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES])
c8434e83 159 if i != rounds:
160 data = mix_columns_inv(data)
161 data = shift_rows_inv(data)
162 data = sub_bytes_inv(data)
163 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES])
5f6a1245 164
f3bcebb1 165 return data
166
5f6a1245 167
f3bcebb1 168def aes_decrypt_text(data, password, key_size_bytes):
169 """
170 Decrypt text
171 - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter
172 - The cipher key is retrieved by encrypting the first 16 Byte of 'password'
173 with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's)
174 - Mode of operation is 'counter'
5f6a1245 175
f3bcebb1 176 @param {str} data Base64 encoded string
177 @param {str,unicode} password Password (will be encoded with utf-8)
178 @param {int} key_size_bytes Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit
179 @returns {str} Decrypted data
180 """
181 NONCE_LENGTH_BYTES = 8
5f6a1245 182
cf282071 183 data = bytes_to_intlist(compat_b64decode(data))
48ea9cea 184 password = bytes_to_intlist(password.encode('utf-8'))
5f6a1245 185
2514d263 186 key = password[:key_size_bytes] + [0] * (key_size_bytes - len(password))
48ea9cea 187 key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes // BLOCK_SIZE_BYTES)
5f6a1245 188
f3bcebb1 189 nonce = data[:NONCE_LENGTH_BYTES]
190 cipher = data[NONCE_LENGTH_BYTES:]
5f6a1245 191
080e0955 192 class Counter(object):
2514d263 193 __value = nonce + [0] * (BLOCK_SIZE_BYTES - NONCE_LENGTH_BYTES)
5f6a1245 194
f3bcebb1 195 def next_value(self):
196 temp = self.__value
197 self.__value = inc(self.__value)
198 return temp
5f6a1245 199
f3bcebb1 200 decrypted_data = aes_ctr_decrypt(cipher, key, Counter())
0012690a 201 plaintext = intlist_to_bytes(decrypted_data)
5f6a1245 202
f3bcebb1 203 return plaintext
204
582be358 205
f3bcebb1 206RCON = (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36)
207SBOX = (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
208 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
209 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
210 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
211 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
212 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
213 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
214 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
215 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
216 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
217 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
218 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
219 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
220 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
221 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
222 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
c8434e83 223SBOX_INV = (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
224 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
225 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
226 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
227 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
228 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
229 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
230 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
231 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
232 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
233 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
234 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
235 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
236 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
237 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
238 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
5f6a1245
JW
239MIX_COLUMN_MATRIX = ((0x2, 0x3, 0x1, 0x1),
240 (0x1, 0x2, 0x3, 0x1),
241 (0x1, 0x1, 0x2, 0x3),
242 (0x3, 0x1, 0x1, 0x2))
243MIX_COLUMN_MATRIX_INV = ((0xE, 0xB, 0xD, 0x9),
244 (0x9, 0xE, 0xB, 0xD),
245 (0xD, 0x9, 0xE, 0xB),
246 (0xB, 0xD, 0x9, 0xE))
c8434e83 247RIJNDAEL_EXP_TABLE = (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
248 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
249 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
250 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
251 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
252 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
253 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
254 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
255 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
256 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
257 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
258 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
259 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
260 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
261 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
262 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01)
263RIJNDAEL_LOG_TABLE = (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03,
264 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1,
265 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78,
266 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e,
267 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38,
268 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10,
269 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba,
270 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57,
271 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8,
272 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0,
273 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7,
274 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d,
275 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1,
276 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab,
277 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5,
278 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07)
f3bcebb1 279
5f6a1245 280
f3bcebb1 281def sub_bytes(data):
48ea9cea 282 return [SBOX[x] for x in data]
f3bcebb1 283
5f6a1245 284
c8434e83 285def sub_bytes_inv(data):
286 return [SBOX_INV[x] for x in data]
287
5f6a1245 288
f3bcebb1 289def rotate(data):
290 return data[1:] + [data[0]]
291
5f6a1245 292
f3bcebb1 293def key_schedule_core(data, rcon_iteration):
294 data = rotate(data)
295 data = sub_bytes(data)
296 data[0] = data[0] ^ RCON[rcon_iteration]
5f6a1245 297
f3bcebb1 298 return data
299
5f6a1245 300
f3bcebb1 301def xor(data1, data2):
2514d263 302 return [x ^ y for x, y in zip(data1, data2)]
f3bcebb1 303
5f6a1245 304
c8434e83 305def rijndael_mul(a, b):
5f6a1245 306 if(a == 0 or b == 0):
c8434e83 307 return 0
308 return RIJNDAEL_EXP_TABLE[(RIJNDAEL_LOG_TABLE[a] + RIJNDAEL_LOG_TABLE[b]) % 0xFF]
309
5f6a1245 310
c8434e83 311def mix_column(data, matrix):
f3bcebb1 312 data_mixed = []
313 for row in range(4):
314 mixed = 0
315 for column in range(4):
c8434e83 316 # xor is (+) and (-)
317 mixed ^= rijndael_mul(data[column], matrix[row][column])
f3bcebb1 318 data_mixed.append(mixed)
319 return data_mixed
320
5f6a1245 321
c8434e83 322def mix_columns(data, matrix=MIX_COLUMN_MATRIX):
f3bcebb1 323 data_mixed = []
324 for i in range(4):
2514d263 325 column = data[i * 4: (i + 1) * 4]
c8434e83 326 data_mixed += mix_column(column, matrix)
f3bcebb1 327 return data_mixed
328
5f6a1245 329
c8434e83 330def mix_columns_inv(data):
331 return mix_columns(data, MIX_COLUMN_MATRIX_INV)
332
5f6a1245 333
f3bcebb1 334def shift_rows(data):
335 data_shifted = []
336 for column in range(4):
337 for row in range(4):
5f6a1245 338 data_shifted.append(data[((column + row) & 0b11) * 4 + row])
f3bcebb1 339 return data_shifted
340
5f6a1245 341
c8434e83 342def shift_rows_inv(data):
343 data_shifted = []
344 for column in range(4):
345 for row in range(4):
5f6a1245 346 data_shifted.append(data[((column - row) & 0b11) * 4 + row])
c8434e83 347 return data_shifted
348
5f6a1245 349
f3bcebb1 350def inc(data):
5f6a1245 351 data = data[:] # copy
2514d263 352 for i in range(len(data) - 1, -1, -1):
f3bcebb1 353 if data[i] == 255:
354 data[i] = 0
355 else:
356 data[i] = data[i] + 1
357 break
358 return data
f36f92f4 359
582be358 360
f36f92f4 361__all__ = ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text']