You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
15 KiB

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