OLD | NEW |
| 1 # Author: Trevor Perrin |
| 2 # See the LICENSE file for legal information regarding use of this file. |
| 3 |
1 """Pure-Python AES implementation.""" | 4 """Pure-Python AES implementation.""" |
2 | 5 |
3 from cryptomath import * | 6 from .cryptomath import * |
4 | 7 |
5 from aes import * | 8 from .aes import * |
6 from rijndael import rijndael | 9 from .rijndael import rijndael |
7 | 10 |
8 def new(key, mode, IV): | 11 def new(key, mode, IV): |
9 return Python_AES(key, mode, IV) | 12 return Python_AES(key, mode, IV) |
10 | 13 |
11 class Python_AES(AES): | 14 class Python_AES(AES): |
12 def __init__(self, key, mode, IV): | 15 def __init__(self, key, mode, IV): |
13 AES.__init__(self, key, mode, IV, "python") | 16 AES.__init__(self, key, mode, IV, "python") |
14 self.rijndael = rijndael(key, 16) | 17 self.rijndael = rijndael(key, 16) |
15 self.IV = IV | 18 self.IV = IV |
16 | 19 |
17 def encrypt(self, plaintext): | 20 def encrypt(self, plaintext): |
18 AES.encrypt(self, plaintext) | 21 AES.encrypt(self, plaintext) |
19 | 22 |
20 plaintextBytes = stringToBytes(plaintext) | 23 plaintextBytes = plaintext[:] |
21 chainBytes = stringToBytes(self.IV) | 24 chainBytes = self.IV[:] |
22 | 25 |
23 #CBC Mode: For each block... | 26 #CBC Mode: For each block... |
24 for x in range(len(plaintextBytes)/16): | 27 for x in range(len(plaintextBytes)//16): |
25 | 28 |
26 #XOR with the chaining block | 29 #XOR with the chaining block |
27 blockBytes = plaintextBytes[x*16 : (x*16)+16] | 30 blockBytes = plaintextBytes[x*16 : (x*16)+16] |
28 for y in range(16): | 31 for y in range(16): |
29 blockBytes[y] ^= chainBytes[y] | 32 blockBytes[y] ^= chainBytes[y] |
30 blockString = bytesToString(blockBytes) | |
31 | 33 |
32 #Encrypt it | 34 #Encrypt it |
33 encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString)) | 35 encryptedBytes = self.rijndael.encrypt(blockBytes) |
34 | 36 |
35 #Overwrite the input with the output | 37 #Overwrite the input with the output |
36 for y in range(16): | 38 for y in range(16): |
37 plaintextBytes[(x*16)+y] = encryptedBytes[y] | 39 plaintextBytes[(x*16)+y] = encryptedBytes[y] |
38 | 40 |
39 #Set the next chaining block | 41 #Set the next chaining block |
40 chainBytes = encryptedBytes | 42 chainBytes = encryptedBytes |
41 | 43 |
42 self.IV = bytesToString(chainBytes) | 44 self.IV = chainBytes[:] |
43 return bytesToString(plaintextBytes) | 45 return plaintextBytes |
44 | 46 |
45 def decrypt(self, ciphertext): | 47 def decrypt(self, ciphertext): |
46 AES.decrypt(self, ciphertext) | 48 AES.decrypt(self, ciphertext) |
47 | 49 |
48 ciphertextBytes = stringToBytes(ciphertext) | 50 ciphertextBytes = ciphertext[:] |
49 chainBytes = stringToBytes(self.IV) | 51 chainBytes = self.IV[:] |
50 | 52 |
51 #CBC Mode: For each block... | 53 #CBC Mode: For each block... |
52 for x in range(len(ciphertextBytes)/16): | 54 for x in range(len(ciphertextBytes)//16): |
53 | 55 |
54 #Decrypt it | 56 #Decrypt it |
55 blockBytes = ciphertextBytes[x*16 : (x*16)+16] | 57 blockBytes = ciphertextBytes[x*16 : (x*16)+16] |
56 blockString = bytesToString(blockBytes) | 58 decryptedBytes = self.rijndael.decrypt(blockBytes) |
57 decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString)) | |
58 | 59 |
59 #XOR with the chaining block and overwrite the input with output | 60 #XOR with the chaining block and overwrite the input with output |
60 for y in range(16): | 61 for y in range(16): |
61 decryptedBytes[y] ^= chainBytes[y] | 62 decryptedBytes[y] ^= chainBytes[y] |
62 ciphertextBytes[(x*16)+y] = decryptedBytes[y] | 63 ciphertextBytes[(x*16)+y] = decryptedBytes[y] |
63 | 64 |
64 #Set the next chaining block | 65 #Set the next chaining block |
65 chainBytes = blockBytes | 66 chainBytes = blockBytes |
66 | 67 |
67 self.IV = bytesToString(chainBytes) | 68 self.IV = chainBytes[:] |
68 return bytesToString(ciphertextBytes) | 69 return ciphertextBytes |
OLD | NEW |