I am comparing the performance of the ECDSAP256 signature algorithm and RSA3072 on OpenSSL.

I first used openssl speed to test algorithm performance:

  • RSA3072 signs 356.2 time/second and verify 17625.1 time/second;

  • ECDSAP256 signs 28096.7 time/second and verify 9462.5 time/second;

Then I created a server with a P256 certificate and a server with an RSA3072 certificate. Both of them are signed by a self-signed root CA. All these certificates are created using the OpenSSL command. They are stored in folder ecc_test and rsa_test respectively.

I tested the handshake performance using openssl s_server and openssl s_time on TLS 1.3. The result showed here:

  • RSA3072:
7380 connections in 5.02s; 1470.12 connections/user sec, bytes read 0
7380 connections in 31 real seconds, 0 bytes read per connection
  • P256
19755 connections in 16.49s; 1198.00 connections/user sec, bytes read 0
19755 connections in 31 real seconds, 0 bytes read per connection

The testing commands are here, $1 need to be replaced by the folder name ecc_test or rsa_test:

openssl s_server -key $1/server/server.key -cert $1/server/server.pem -accept 4330 
-CAfile $1/rootCA/demoCA/root.pem -verify_return_error -state -WWW
openssl s_time -connect localhost:4330 -CAfile $1/rootCA/demoCA/root.pem -new

I first thought the result is reasonable since RSA3072 verify faster than P256. But then I realize that in TLS 1.3 server needs to send a CertificateVerify which is signed using the server's private key. Therefore, in theory, the server using the P256 certificate should set up the handshake faster than the server using the RSA3072 certificate.

Then I run s_client with -msg and I found that the CertificateVerify was indeed generated and sent. Both servers use x25519 for key exchange.

Is there any error in my experiment?

How did the CertificateVerify generate? Could it be generated before the handshake?

1 Answer 1


By default, the openssl s_time command performs two types of connection in sequence. The first is a normal connection as if it were a brand new client, and the second is a resumption re-using the session ID from that previous connection. Session resumptions do not require a full handshake with a CertificateVerify, and they are much faster (particularly in TLS 1.3) than a regular connection. This explains why you're seeing more than twice as many connections per second for RSA than you are in the openssl speed test - half of the connections aren't doing any RSA signature operations at all.

This explains why your results are coming out skewed. You can fix this with the -new flag, which tells openssl s_time to only perform new connections and no session resumptions.

It's also worth keeping in mind that 660 signs per second means just 1.5 milliseconds are spent performing the RSA portion of the handshake. ECDSA is obviously faster (about 19 microseconds) but it won't make a huge difference in practical handshake time over the internet because each network round trip typically takes 10-30ms, and TLS 1.3 handshakes require two round trips (ignoring 0-RTT). The main benefit of moving to ECDSA is the lower compute cost (i.e. less CPU overhead and lower energy usage) rather than the comparatively small decrease in per-handshake time.

  • 3
    Another benefit of ECDSA is the reduced size of keys, signatures and certificates. This matters when you have very little bandwidth, typically for IoT devices that only want to transmit a handful of bytes and for which the certificate chain is a huge fraction of the bandwidth usage. Mar 24, 2022 at 21:03
  • Thanks for your reply. I am using OpenSSL 1.1.1. The default s_time command will perform new connections and give the results of new connections first. Then it will perform resumptions again and give the result for session resumptions. The previous data I posted is the speed of new connections so it should be the same as adding the -new flag. To be hundred percent convinced, I added the -new flag in s_time and tested again. The result does not change much. Mar 25, 2022 at 3:52
  • Some data changed because I specify the same CPU running frequency for both algorithm testing and handshake. The previous data is incorrect and I am sorry for the error. Mar 25, 2022 at 3:59
  • I add a -msg flag on the server-side and then I tried to run s_time with -new for the first time and -reuse flag for the second time. I found that CertificateVerify messages are sent in both situations. Is it a bug in OpenSSL or are there any errors in my command? Mar 25, 2022 at 8:15
  • @JIQINGCHEN Not a bug. If you only specify -reuse, openssl still has to send full handshakes to get a valid session IDs so that it can perform the reuse timing. It just doesn't time the full handshakes.
    – Polynomial
    Mar 25, 2022 at 21:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.