Comparison of signature verification between ECC and RSA certificates.

The following are very crude measurements of the time taken for the openssl command, running in Bash, to verify signatures generated using ECC and RSA keys, to see whether ECC client certificate represent a significant burden on a Gemini server.

The 'testfile' that gets signed is 1024 bytes from /dev/urandom. The same file is used throughout, because I want to measure relative computation time, though in practice ECC certificates are smaller.

To summarise the results, in short, I don't think there's a significant difference in computation burden between RSA and ECC verification. The average time for openssl to run a verify is around 2.8ms, and running in a shell like this is perhaps the worst-case scenario imaginable (other than paper and pen!).

I figure that the 'user' time value is the most relevant, since the verification process is largely CPU bound, so I've included the millisecond average time-per-verify time based on this.

Sign a file, verify 10,000 times...

# Scripts create one digest, and verifies 10,000 times.
$ ./test_ecc.sh ; ./test_rsa.sh ; ./test_ecc.sh ; ./test_rsa.sh

ECC1
====
real    0m39.326s
user    0m28.461s    2.8ms
sys     0m11.338s

RSA1
====
real    0m37.670s
user    0m26.903s    2.7ms
sys     0m11.229s

ECC2
====
real    0m39.307s
user    0m27.813s    2.8ms
sys     0m11.963s

RSA2
====
real    0m37.715s
user    0m26.678s    2.7ms
sys     0m11.485s

Sign the file 1,000 times, verify each signature.

The purpose of this test is to mitigate possible optimisations for frequently used keys (e.g. caching pre-caclulated values)

# Scripts create 1,000 digests and verifies each.
$ ./test_rsa.sh ; ./test_ecc.sh

RSA
===
real    0m3.745s
user    0m2.729s    2.7ms
sys     0m1.050s

ECC
===
real    0m3.905s
user    0m2.805s    2.8ms
sys     0m1.141s

Bash scripts used are shown below

The scripts used for the above two tests are shown below. The previous tests (single digest) were almost identical, but without the iteration for digest creation.

$ cat test_ecc.sh
#!/bin/bash -
#===============================================================================
#          FILE: test_ecc.sh
#        AUTHOR: Kevin Sangeelee, kevin@susa.net
#       CREATED: 22/07/20 13:42:05
#===============================================================================

# Get our chosen curve parameters in a PEM file.
openssl ecparam -name prime256v1 -out prime256v1.pem

# Use this to generate my EC private key.
openssl ecparam -in prime256v1.pem -genkey -out prime256v1.key

# Create my X509 certificate.
openssl req -nodes -x509 -sha256 -key ./prime256v1.key -subj '/CN=Kevin' \
    -out ./prime256v1.crt

# Sign file 1000 times with my private key, generate  SHA256 digests.
for i in {1..1000}; do openssl dgst -sha256 -sign ./prime256v1.key \
    -out testfile.sha256.${i} testfile; done

# Extract my public key to verify my signed file
openssl x509 -in ./prime256v1.crt -pubkey -noout -out prime256v1.pub

# Verify that the signature verifies given my public key.
time for i in {1..1000}; do openssl dgst -sha256 -verify prime256v1.pub \
    -signature testfile.sha256.${i} testfile 2>&1 >/dev/null; done


$ cat test_rsa.sh
#!/bin/bash -
#===============================================================================
#          FILE: test_rsa.sh
#        AUTHOR: Kevin Sangeelee, kevin@susa.net
#       CREATED: 22/07/20 13:42:05
#===============================================================================

# Create a 2048 bit RSA key and X509 certificate
openssl req -x509 -newkey rsa:2048 -nodes -keyout rsa2048.key \
    -out rsa2048.crt -days 3650 -subj '/CN=Kevin'

# Sign the test file 1000 times with my private key, generate a digest.
for i in {1..1000}; do openssl dgst -sha256 -sign ./rsa2048.key \
    -out testfile.sha256.${i} testfile; done

# Extract my public key to verify my signed file
openssl x509 -in ./rsa2048.crt -pubkey -noout -out rsa2048.pub

# Verify that the signature verifies given my public key.
time for i in {1..1000}; do openssl dgst -sha256 -verify rsa2048.pub \
    -signature testfile.sha256.${i} testfile 2>&1 >/dev/null; done

Hardware used

Intel(R) Xeon(R) CPU X3470 @ 2.93GHz (8 cores)
16GB RAM

My choice of ECC curve was taken from 'gemcert':