Why does AES encryption take more time than decryption?

While I was studying the time consumed by some methods I found that encryption take more time than decryption. Is this right? I am using AES (the same steps will be taken during the enc and dec)

• Fun fact: when using AES-NI for accelerating AES, decryption is actually slower because an additional instruction, `AESIMC`, must be used every round. Commented Mar 7, 2018 at 10:09
• @forest `aesimc` is used on each round key, not every round. The decryption keys can be expanded before decrypting. Commented Jun 7 at 16:50

Several symmetric block ciphers (specifically ones like AES, DES, Blowfish, RC5) will take the same amount of time (within measurement error) for encryption and decryption, when operating on a single block (e.g., 128-bits for AES).

However, there are a couple reasons why it appears different when encrypting/decrypting multiple blocks. For example, with cipher-block chaining (CBC), encryption must be done sequentially (encrypt block 0 before you can encrypt block 1 before you can encrypt block 2 ...), while decryption can be parallelized as the XOR step (with the previous block of ciphertext) is done after the block cipher is applied.

See the diagrams below (XOR is denoted with a circled plus ⊕). To encrypt the second block of plaintext `p[1]`, you use `c[1] = AES_Encrypt(p[1] XOR c[0])`, this means you can't generate `c[1]` until you are finished generating `c[0]`.

Meanwhile to decrypt the second block of ciphertext, you use `p[1] = c[0] XOR AES_Decrypt(c[1])`. This is not dependent on the previous block of plaintext `p[0]` so can be completely parallelized (and can run much faster on multi-core systems).

If you want fast decryption and encryption, you may consider using CTR as it can be parallelized on both encryption and decryption.

You also potentially should be wary of tests that are skewed because of caches on your system. If you randomly decide to read a file from disk and encrypt it, it will take several milliseconds to read each chunk of the file; however the next time you access it the file will generally be cached in memory and be accessed much quicker. Meanwhile for your decryption test that encrypted file that was recently written to disk will likely still be in a cache in memory and will not suffer the penalty from reading from disk.

CTR Timing

``````\$ time openssl aes-256-ctr -e -salt -pass pass:passwd -in Fedora_64-bit.vmdk -out vmdk.encrypted

real    0m58.217s
user    0m5.788s
sys     0m8.493s
\$ time openssl aes-256-ctr -e -salt -pass pass:passwd -in Fedora_64-bit.vmdk -out vmdk.encrypted

real    0m34.780s
user    0m4.800s
sys     0m7.748s
\$ time openssl aes-256-ctr -e -salt -pass pass:passwd -in Fedora_64-bit.vmdk -out vmdk.encrypted

real    0m34.989s
user    0m4.120s
sys     0m6.444s
\$ time openssl aes-256-ctr -d -salt -pass pass:passwd -in vmdk.encrypted -out decrypted

real    0m35.944s
user    0m4.140s
sys     0m7.008s
``````

The first three encryptions show the effect of the disk cache, where the first access of a file was much slower than subsequent accesses. It also shows that for CTR that both encryption / decryption of this 7.4 G virtual machine took roughly 35 seconds. (On repetition occasionally, decryption would be faster or slower).

• There are block ciphers where encrypt/decrypt have slightly different cost. These aren't just based on external effects like mode, or caches. You could see that difference with ECB mode. Threefish is one of them, but I don't know if this applies to AES as well. Commented Jun 26, 2013 at 17:30
• @CodesInChaos - Good point. I was trying to speak concretely about AES where the steps for encryption / decryption have exact analogs of each other in a decent implementation (Round Key generation / SubBytes vs InvSubBytes / ShiftRows vs InvShiftRows / MixColumns vs InvMixColumns). The similar block ciphers was specifically referring to Luby-Rackoff block ciphers (which AES is not an example of) built from Feistel network should have this property as encryption decryption are the same applications of the same pseudo-random function (just in opposite order to opposite halves of the block). Commented Jun 26, 2013 at 18:13
• Just wanted to say that this is a great answer, and I wish there were more like this on the SE network! Commented Jun 26, 2013 at 19:15
• If you use ram (e.g. `/tmp`) to store the files shouldn't you be able to test without being affected by disk io? Commented Jun 27, 2013 at 6:21
• @CodesInChaos - While I can't demonstrate that all symmetric key ciphers take same time on one block for enc/decrypting. However, looking at threefish's implementation (section 2.2 ), it should take the same time to encrypt/decrypt. Tests in python3 for threefish show the same running time; e.g., encrypting 50000 random 64-byte blocks takes 23.134 +/- 0.183 ms, while decrypting 50000 random 64-byte ASCII blocks takes 23.135 +/- 0.095 ms. Here's a pastebin of the python3 tests. Commented Jun 28, 2013 at 16:26