This is an AES implementation in Python.
The block cipher mode of operation is CTR. The implementation supports AES-128, AES-192, and AES-256 (default). The AES key and HMAC key are generated from a user password using hashlib's scrypt and a random 16-byte salt (a key that's twice as long as it needs to be is created and split in half for each key). The CTR IV is created by a random 10 byte nonce and a 6 byte counter that starts at 0. The salt is written as the first block of the ciphertext, followed by the CTR IV as the second block. Lastly, the HMAC value of the ciphertext is created using the HMAC key and written as the last two blocks of the ciphertext. Before decrypting, the HMAC value is checked against the rest of the ciphertext and if the value matches the decryption begins.
I have tried two different ways to optimize the code and get a faster run:
- Regular: This is the unoptimized version of the code -- slow.
- Parallelized: This version uses parallelization thorugh multiprocessing -- faster.
- Numba: This version uses Numba, a JIT compiler that translates a subset of Python and NumPy code into fast machine code -- fastest.
Learn more about AES:
python encrypt_decrypt.py [-h] (-e | -d) input_file output_file
positional arguments:
input_file
output_file
optional arguments:
-h, --help usage message and exit
-e, --encrypt
-d, --decrypt
AES-256
Plaintext:
Plaintext.bin
Password:
bluekeybo
Ciphertext:
Ciphertext.bin
AES-128
Plaintext:
0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa 0xbb 0xcc 0xdd 0xee 0xff
Key:
0xf0 0xb8 0xa5 0x4b 0x41 0x28 0xe5 0x3c 0xf9 0x00 0x5a 0xe1 0x25 0x2b 0x87 0xe6
Ciphertext:
0xb8 0x5e 0x08 0x3f 0x4e 0x9e 0x62 0x01 0xb4 0x53 0x40 0x9d 0x28 0x96 0x07 0x77
AES-192
Plaintext:
0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa 0xbb 0xcc 0xdd 0xee 0xff
Key:
0xb7 0x4a 0xb3 0x22 0xc3 0xdb 0x1b 0x44 0x1f 0x1c 0xed 0x77 0xfe 0x08 0x2a 0xe5 0xd2 0x78 0xef 0x5c 0xb9 0x23 0xea 0xe6
Ciphertext:
0x3e 0x66 0x3e 0x69 0xe9 0x4b 0xdc 0x79 0x98 0xc7 0x1e 0x16 0xa5 0x36 0xf9 0x7e
AES-256
Plaintext:
0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa 0xbb 0xcc 0xdd 0xee 0xff
Key:
0xb1 0x88 0xd8 0x8e 0xa3 0x07 0x0e 0x62 0x9a 0xcb 0xb4 0xa7 0xc9 0x4d 0x91 0xd2 0xf1 0x91 0xdc 0xfe 0x84 0x92 0x24 0x10 0x00 0x16 0x29 0x1a 0x17 0xe6 0x2d 0x3d
Ciphertext:
0xb4 0x21 0x72 0xc3 0xa0 0x48 0x91 0x46 0xd9 0xfa 0x1a 0xef 0x0d 0xd4 0x21 0x69