Which one is faster GCM AES-128 or Curve25519? As I know the symmetric encryption algorithms are faster than asymmetric encryption algorithms. But when I test GCM AES-128 and Curve25519 encryption time, I find Curve25519 is faster than GCM AES-128.
Is that normal?
Is GCM AES-128 slow?

By the way, I use these python libraries for the comparison:


PyNaCl for Curve25519 (using the box)
Cryptography.io for AES-GCM


I performed the tests with Ubuntu 16.04 64-bit on an Intel Core i7-2640M and ran the tests multiple times with differing input lengths.

The speeds for curve25519 are (1 kB):
Encryption 6.29425048828e-05 sec
Decryption 2.31266021729e-05 sec

The speeds for GCM are (1 kB):
Encryption 0.000115156173706 sec
Decryption 0.000576972961426 sec
You are not just using Curve25519. You are using a Python wrapper to NaCl, which is a high level crypto library that uses Curve25519 for Diffie-Hellman computation to derive a secret value. This secret is then used to encrypt with a particular algorithm, defaulting to Salsa20/Poly1305. So this library performs hybrid cryptography, where the data itself is encrypted with a fast, authenticated stream cipher. Although functionally the API is high level, execution certainly isn't: it's a highly focused, minimal implementation that is focused on both speed and security.

The cryptography library on the other part uses OpenSSL to speed up AES-GCM implementations. If a high enough OpenSSL library is used then AES-NI as well as CMUL for the GMAC operations should be available on high end CPU's that support it. However, it is completely possible to use an older library or one that isn't compiled for AES-NI. OpenSSL is an old generic library that may also have some more overhead; it isn't targeted forspeed in the same way that NaCL is.

If you have larger messages then the speed difference is simply due to speed differences in implementation of Salsa20/Poly1305 and AES in GCM mode. Salsa20 is a fast stream cipher, while GCM mode can generally be accelerated by hardware.



Beware that testing for speed is particularly tricky, especially on higher level languages. Differences in startup time of the compiler parser may already influence the results. You need a loop for the startup time and a loop for the testing. Both loops should contain the algorithm.

Also note that the random number generation may be pretty different on each platform.