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