aes.py (16130B)
1 from __future__ import unicode_literals 2 3 from math import ceil 4 5 from .compat import compat_b64decode 6 from .utils import bytes_to_intlist, intlist_to_bytes 7 8 BLOCK_SIZE_BYTES = 16 9 10 11 def aes_ctr_decrypt(data, key, counter): 12 """ 13 Decrypt with aes in counter mode 14 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) 22 block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES)) 23 24 decrypted_data = [] 25 for i in range(block_count): 26 counter_block = counter.next_value() 27 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES] 28 block += [0] * (BLOCK_SIZE_BYTES - len(block)) 29 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)] 33 34 return decrypted_data 35 36 37 def aes_cbc_decrypt(data, key, iv): 38 """ 39 Decrypt with aes in CBC mode 40 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)) 48 49 decrypted_data = [] 50 previous_cipher_block = iv 51 for i in range(block_count): 52 block = data[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES] 53 block += [0] * (BLOCK_SIZE_BYTES - len(block)) 54 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)] 59 60 return decrypted_data 61 62 63 def 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 91 def key_expansion(data): 92 """ 93 Generate key schedule 94 95 @param {int[]} data 16/24/32-Byte cipher key 96 @returns {int[]} 176/208/240-Byte expanded key 97 """ 98 data = data[:] # copy 99 rcon_iteration = 1 100 key_size_bytes = len(data) 101 expanded_key_size_bytes = (key_size_bytes // 4 + 7) * BLOCK_SIZE_BYTES 102 103 while len(data) < expanded_key_size_bytes: 104 temp = data[-4:] 105 temp = key_schedule_core(temp, rcon_iteration) 106 rcon_iteration += 1 107 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes]) 108 109 for _ in range(3): 110 temp = data[-4:] 111 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes]) 112 113 if key_size_bytes == 32: 114 temp = data[-4:] 115 temp = sub_bytes(temp) 116 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes]) 117 118 for _ in range(3 if key_size_bytes == 32 else 2 if key_size_bytes == 24 else 0): 119 temp = data[-4:] 120 data += xor(temp, data[-key_size_bytes: 4 - key_size_bytes]) 121 data = data[:expanded_key_size_bytes] 122 123 return data 124 125 126 def aes_encrypt(data, expanded_key): 127 """ 128 Encrypt one block with aes 129 130 @param {int[]} data 16-Byte state 131 @param {int[]} expanded_key 176/208/240-Byte expanded key 132 @returns {int[]} 16-Byte cipher 133 """ 134 rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1 135 136 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES]) 137 for i in range(1, rounds + 1): 138 data = sub_bytes(data) 139 data = shift_rows(data) 140 if i != rounds: 141 data = mix_columns(data) 142 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]) 143 144 return data 145 146 147 def aes_decrypt(data, expanded_key): 148 """ 149 Decrypt one block with aes 150 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 156 157 for i in range(rounds, 0, -1): 158 data = xor(data, expanded_key[i * BLOCK_SIZE_BYTES: (i + 1) * BLOCK_SIZE_BYTES]) 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]) 164 165 return data 166 167 168 def 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' 175 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 182 183 data = bytes_to_intlist(compat_b64decode(data)) 184 password = bytes_to_intlist(password.encode('utf-8')) 185 186 key = password[:key_size_bytes] + [0] * (key_size_bytes - len(password)) 187 key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes // BLOCK_SIZE_BYTES) 188 189 nonce = data[:NONCE_LENGTH_BYTES] 190 cipher = data[NONCE_LENGTH_BYTES:] 191 192 class Counter(object): 193 __value = nonce + [0] * (BLOCK_SIZE_BYTES - NONCE_LENGTH_BYTES) 194 195 def next_value(self): 196 temp = self.__value 197 self.__value = inc(self.__value) 198 return temp 199 200 decrypted_data = aes_ctr_decrypt(cipher, key, Counter()) 201 plaintext = intlist_to_bytes(decrypted_data) 202 203 return plaintext 204 205 206 RCON = (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36) 207 SBOX = (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) 223 SBOX_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) 239 MIX_COLUMN_MATRIX = ((0x2, 0x3, 0x1, 0x1), 240 (0x1, 0x2, 0x3, 0x1), 241 (0x1, 0x1, 0x2, 0x3), 242 (0x3, 0x1, 0x1, 0x2)) 243 MIX_COLUMN_MATRIX_INV = ((0xE, 0xB, 0xD, 0x9), 244 (0x9, 0xE, 0xB, 0xD), 245 (0xD, 0x9, 0xE, 0xB), 246 (0xB, 0xD, 0x9, 0xE)) 247 RIJNDAEL_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) 263 RIJNDAEL_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) 279 280 281 def sub_bytes(data): 282 return [SBOX[x] for x in data] 283 284 285 def sub_bytes_inv(data): 286 return [SBOX_INV[x] for x in data] 287 288 289 def rotate(data): 290 return data[1:] + [data[0]] 291 292 293 def key_schedule_core(data, rcon_iteration): 294 data = rotate(data) 295 data = sub_bytes(data) 296 data[0] = data[0] ^ RCON[rcon_iteration] 297 298 return data 299 300 301 def xor(data1, data2): 302 return [x ^ y for x, y in zip(data1, data2)] 303 304 305 def rijndael_mul(a, b): 306 if(a == 0 or b == 0): 307 return 0 308 return RIJNDAEL_EXP_TABLE[(RIJNDAEL_LOG_TABLE[a] + RIJNDAEL_LOG_TABLE[b]) % 0xFF] 309 310 311 def mix_column(data, matrix): 312 data_mixed = [] 313 for row in range(4): 314 mixed = 0 315 for column in range(4): 316 # xor is (+) and (-) 317 mixed ^= rijndael_mul(data[column], matrix[row][column]) 318 data_mixed.append(mixed) 319 return data_mixed 320 321 322 def mix_columns(data, matrix=MIX_COLUMN_MATRIX): 323 data_mixed = [] 324 for i in range(4): 325 column = data[i * 4: (i + 1) * 4] 326 data_mixed += mix_column(column, matrix) 327 return data_mixed 328 329 330 def mix_columns_inv(data): 331 return mix_columns(data, MIX_COLUMN_MATRIX_INV) 332 333 334 def shift_rows(data): 335 data_shifted = [] 336 for column in range(4): 337 for row in range(4): 338 data_shifted.append(data[((column + row) & 0b11) * 4 + row]) 339 return data_shifted 340 341 342 def shift_rows_inv(data): 343 data_shifted = [] 344 for column in range(4): 345 for row in range(4): 346 data_shifted.append(data[((column - row) & 0b11) * 4 + row]) 347 return data_shifted 348 349 350 def inc(data): 351 data = data[:] # copy 352 for i in range(len(data) - 1, -1, -1): 353 if data[i] == 255: 354 data[i] = 0 355 else: 356 data[i] = data[i] + 1 357 break 358 return data 359 360 361 __all__ = ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text']