I wrote a little benchmark, comparing the PyCrypto and cryptography python modules.
You can find the script here.
results
Most symmetric ciphers are significantly faster in pyCrypto for small blocksizes.
but cryptography is much faster for larger data.
The ratio is the byterate of pycrypto divided by the byterate of cryptography.
So values less than 1 mean: cryptography is faster, values larger than 1: pycrypto is faster.
I found that the cryptography library is generally faster for large data volumes, while pycrypto
is faster for encrypting small items.
symmetric crypto
Both pycrypto and cryptography have some call overhead.
for pycrypto the byterate stabilizes for messages over 1K,
while for `cryptography this happens for messages over 16K.
message size = 32 bytes, in Mbyte/sec
| pycrypto | cryptography | ratio | cipher |
|---|---|---|---|
| 154 | 102 | 1.51 | aes |
| 129 | 91 | 1.41 | blowfish |
| 88 | 88 | 1.00 | cast |
| 52 | 71 | 0.74 | des128 |
| 58 | 71 | 0.82 | des192 |
| 102 | 73 | 1.41 | des64 |
| 187 | 97 | 1.92 | rc4 |
message size = 1048576 bytes, in Mbyte/sec
| pycrypto | cryptography | ratio | cipher |
|---|---|---|---|
| 2054 | 22920 | 0.09 | aes |
| 326 | 936 | 0.35 | blowfish |
| 144 | 871 | 0.17 | cast |
| 79 | 231 | 0.34 | des128 |
| 78 | 231 | 0.34 | des192 |
| 212 | 234 | 0.90 | des64 |
| 486 | 5050 | 0.10 | rc4 |
hash algorithms
Both pycrypto and cryptography have some call overhead.
for pycrypto the byterate stabilizes for messages over 16K,
while for `cryptography this happens for messages over 1M.
message size = 32 bytes, in Mbyte/sec
| pycrypto | cryptography | ratio | algorithm |
|---|---|---|---|
| 120 | 14 | 8.17 | md5 |
| 114 | 14 | 7.65 | ripemd |
| 112 | 18 | 6.19 | sha1 |
| 112 | 17 | 6.44 | sha224 |
| 134 | 17 | 7.57 | sha256 |
| 89 | 16 | 5.25 | sha384 |
| 90 | 16 | 5.42 | sha512 |
message size = 1048576 bytes, in Mbyte/sec
| pycrypto | cryptography | ratio | algorithm |
|---|---|---|---|
| 5596 | 5231 | 1.07 | md5 |
| 322 | 1660 | 0.19 | ripemd |
| 7871 | 6141 | 1.28 | sha1 |
| 439 | 3498 | 0.13 | sha224 |
| 390 | 3451 | 0.11 | sha256 |
| 651 | 5219 | 0.12 | sha384 |
| 611 | 5186 | 0.12 | sha512 |
blocksize dependency
The Symmetric ciphers.
| AES | BLOWFISH | CAST | DES128 | DES192 | DES64 | RC4 | msgsize |
|---|---|---|---|---|---|---|---|
| 1.51 | 1.41 | 1.00 | 0.74 | 0.82 | 1.41 | 1.92 | 32 |
| 1.30 | 1.12 | 0.65 | 0.59 | 0.63 | 1.36 | 1.23 | 64 |
| 1.21 | 0.85 | 0.38 | 0.48 | 0.49 | 1.23 | 0.88 | 128 |
| 0.99 | 0.68 | 0.30 | 0.38 | 0.44 | 1.22 | 0.47 | 256 |
| 0.78 | 0.62 | 0.25 | 0.38 | 0.38 | 1.16 | 0.35 | 512 |
| 0.56 | 0.51 | -.– | 0.38 | -.– | -.– | 0.22 | 1024 |
| 0.36 | 0.52 | 0.16 | 0.35 | 0.38 | 1.09 | 0.15 | 2048 |
| 0.24 | 0.44 | 0.17 | 0.33 | 0.39 | 1.00 | 0.13 | 4096 |
| 0.17 | 0.43 | 0.17 | 0.31 | 0.37 | 0.99 | 0.10 | 8192 |
| 0.12 | 0.39 | 0.17 | 0.32 | 0.36 | 1.03 | 0.10 | 16384 |
| 0.11 | 0.40 | 0.17 | 0.33 | 0.36 | 1.03 | 0.10 | 32768 |
| 0.09 | 0.36 | 0.17 | 0.37 | 0.35 | 1.06 | 0.08 | 65536 |
| 0.10 | 0.40 | 0.17 | 0.30 | 0.32 | 0.99 | 0.08 | 131072 |
| 0.09 | 0.37 | 0.15 | 0.33 | 0.35 | 0.85 | 0.07 | 262144 |
| 0.09 | 0.40 | 0.17 | 0.32 | 0.34 | 0.99 | 0.11 | 524288 |
| 0.09 | 0.35 | 0.17 | 0.34 | 0.34 | 0.90 | 0.10 | 1048576 |
And for hashing algorithms.
For the SHAxxx algorithms cryptography is faster for messages over 1K.
While for MD5 and SHA1 pyCrypto is always faster.
| MD5 | RIPEMD | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 | msgsize |
|---|---|---|---|---|---|---|---|
| 8.17 | 7.65 | 6.19 | 6.44 | 7.57 | 5.25 | 5.42 | 32 |
| 7.36 | 4.33 | 6.31 | 4.23 | 4.99 | 6.08 | 5.66 | 64 |
| 7.32 | 3.06 | 6.22 | 3.76 | 3.60 | 3.74 | 3.63 | 128 |
| 6.06 | 2.14 | 6.10 | 2.27 | 2.34 | 2.57 | 2.52 | 256 |
| 5.42 | 1.29 | 5.54 | 1.43 | 1.42 | 1.78 | 1.76 | 512 |
| 4.75 | 0.73 | 5.07 | 0.76 | 0.86 | 1.20 | 1.07 | 1024 |
| 3.17 | 0.45 | 3.67 | 0.51 | 0.48 | 0.72 | 0.65 | 2048 |
| 2.38 | 0.34 | 2.96 | 0.33 | 0.32 | 0.42 | 0.40 | 4096 |
| 1.79 | 0.30 | 2.26 | 0.20 | 0.23 | 0.29 | 0.27 | 8192 |
| 1.70 | 0.26 | 1.65 | 0.17 | 0.18 | 0.23 | 0.19 | 16384 |
| 1.32 | 0.24 | 1.31 | 0.14 | 0.16 | 0.16 | 0.16 | 32768 |
| 1.10 | 0.23 | 1.20 | 0.14 | 0.14 | 0.15 | 0.15 | 65536 |
| 1.05 | 0.23 | 1.05 | 0.13 | 0.14 | 0.13 | 0.13 | 131072 |
| 1.03 | 0.25 | 1.05 | 0.14 | 0.13 | 0.11 | 0.12 | 262144 |
| 1.04 | 0.21 | 1.00 | 0.13 | 0.13 | 0.12 | 0.12 | 524288 |
| 1.07 | 0.19 | 1.28 | 0.13 | 0.11 | 0.12 | 0.12 | 1048576 |
asymmetric crypto
in encryptions per second, all using a 512 bit message.
| pow() || pycrypto | cryptography | ratio | modulus bits | | ——:| ——:| —–:| —-:| —–:| | 17267| 11827 | 34152 | 0.35 | 1024 | | 4920| 5014 | 17657 | 0.28 | 2048 | | 1440| 1717 | 6247 | 0.27 | 4096 |
So the cryptography library is generally faster.
The pycrypto performance is roughly equal to using the pow() function.
random numbers
in Mbyte/sec
| random | sysrand | pycrypto | r/s | s/p | msgsize |
|---|---|---|---|---|---|
| 478.0 | 55.9 | 2.0 | 8.6 | 27.4 | 32 |
| 726.4 | 70.9 | 3.1 | 10.2 | 22.6 | 64 |
| 1148.9 | 81.0 | 3.8 | 14.2 | 21.1 | 128 |
| 1476.4 | 88.1 | 4.4 | 16.8 | 20.1 | 256 |
| 1757.5 | 93.4 | 3.9 | 18.8 | 24.2 | 512 |
| 2141.6 | 94.3 | 2.6 | 22.7 | 36.6 | 1024 |
| 2339.3 | 100.2 | 1.9 | 23.3 | 53.4 | 2048 |
| 2405.1 | 94.8 | 1.1 | 25.4 | 83.1 | 4096 |
| 2361.0 | 101.9 | 0.6 | 23.2 | 158.7 | 8192 |
| 2568.1 | 97.7 | 0.3 | 26.3 | 286.8 | 16384 |
Conclusion: secure random numbers are expensive.