GiM's gemlog - 2025-10-10 It's 2025, and you're still using RSA (or dsa)?
I wasn't really sure if I should publish this or not, but here you go.
I want to argue, that you shouldn't be using RSA keys. Not for SSH, not for your web-server and not for your capsule.
Public key sizes
There's quite a lot of handwaving, when comparing strenghts of different public-key crypto algorithms, but usually 2048-bit RSA key is compared to 224-bit elliptic curve key.
And it's said that 256-bit ecc key should be as strong as 3072-bit RSA key.
It doesn't make much sense to compare private keys, as they are rarely "in transit", so here's 2048-bit rsa public key in PEM format:
> openssl genrsa -out rsa.key 2048
> openssl rsa -pubout -in rsa.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6I0qpl9IcCWgSNa+7q1+
oQoNFaHovaLOUHCyVuLk8LeCzjsZUihTfiu6g+0NUnvs4beKxt2fUetZ8t/9nzI8
QBXlV/6WUC13m4UXWOup0Z5VOaNSGhtZTy7A/XAnxQtvta7BfH44azksfxa7cgKO
ryO+IQvFZ85n62ELmO2ftCiEqscOxnvGgPJMi/dvocEj9zeTxdskORLVyt9fSoDA
81vtjfx+wSVslJ6twUgA19iLFO3vrqtxzq/gVrICcFH/qPUEq8CL2tnrUR3U7LkO
VeZAqHUy+H7Fs4Efh9HagJPEYMGhOj7p8wwQ1bl5VP3e3rjwe+yJL0Wtt3IzjwOx
rQIDAQAB
-----END PUBLIC KEY-----
And here's 256-bit ed25519 public key.
> openssl genpkey -out ed25519.key -algorithm ed25519
> openssl pkey -pubout -in ed25519.key
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAAUTAyz7GYFzsPoJr951qGx+g/hKPXlLoJGx2jIkzje4=
-----END PUBLIC KEY-----
So - as expected - RSA public key is 8 times larger than ed25519 public key.
Small side-note before we proceed. 2048-bit key, should keep you safe maybe for next 20 years. There's interesting writeup (describing thinking behind it) on crypto exchange:
How big an RSA key is considered secure today?
Cert sizes
But that's not all, the difference in size of certificates will be even larger, cause (certificate) signature itself will also have noticable difference in size. In case of RSA, the signature will be comparable to size of modulus (so roughly 2048 bits, 256 bytes), while in case of ed25519, the signature is always 64 bytes.
> openssl req -config openssl.cnf -subj "/CN=dummy-rsa" -x509 -nodes -key rsa.key -out rsa.cert
> openssl req -config openssl.cnf -subj "/CN=dummy-ed2" -x509 -nodes -key ed25519.key -out ed25519.cert
> openssl x509 -in rsa.cert -outform der | wc -c
711
> openssl x509 -in ed25519.cert -outform der | wc -c
248
This difference in size is also visible in TLS handshake. In case of TLS1.3, right after initial exchange of "Hellos", there is encrypted data send right away, the very first part is usually certificate. You likely won't be able to observe this difference in old web, but you might observe the difference using wireshark if you try to connect to two different gemini capsules, one having cert with ED25519 key other having cert with rsa key.
While we're at it, another small side-note, your client (and server) - be it web-browser, ssh or gemini client - is likely using elliptic curve-based diffie-hellman exchange (ECDHE) for initial key negotiation. In case of web in general, this change did not happen instantly, but it happened, and you might guess there had to be good reason for this.
Speed
I understand the size itself might not convince you to use ed25519, after all the difference is pretty small, and in case of TLS exchage, server certificate - independent which one - will likely be split across two (likely three in case of rsa>2048) tcp packets anyway.
However, I hope that both size + speed should convince you - or at least make you think twice.
When it comes to speed of signing, ed25519 completly destroys RSA. When compared against rsa-3072, the difference in speed is lightly two ORDERS of magnitude.
But what's IMO most important from client PoV is verify speed. This usually is quite good in RSA, due to choice of public exponent, but take a look at following results and draw your own conclusions. I have deliberately added ed448 as well (which security is believed to be > rsa 8192 bit).
Results from a pretty good machine:
> openssl speed rsa2048 rsa4096 ed25519 ed448
...
sign verify sign/s verify/s
rsa 2048 bits 0.003618s 0.000071s 276.4 14147.8
rsa 3072 bits 0.008762s 0.000158s 114.1 6314.3
rsa 4096 bits 0.021987s 0.000253s 45.5 3952.9
253 bits EdDSA (Ed25519) 0.0000s 0.0001s 31578.7 10899.9
456 bits EdDSA (Ed448) 0.0004s 0.0005s 2235.6 2169.2
Results from tiny ARM vps:
sign verify sign/s verify/s
rsa 2048 bits 0.003233s 0.000087s 309.3 11435.3
rsa 3072 bits 0.009950s 0.000163s 100.5 6118.4
rsa 4096 bits 0.022698s 0.000278s 44.1 3591.5
253 bits EdDSA (Ed25519) 0.0001s 0.0001s 18003.7 7430.8
456 bits EdDSA (Ed448) 0.0004s 0.0006s 2279.1 1615.9
Final side-note
This was over 10y ago, when ed25519 wasn't all over the place yet. Where I worked, I suggested switching some terribly slow in-house RSA that we were using (we couldn't use openssl for multiple reasons), to ed25519. This saved us a lot of build times (the modules that were built were signed), verification time, and some negligible, but still storage (due to much smaller signatures).
$ published: 2025-10-10 12:00:20 $
$ last-edit: 2025-10-10 12:00:20 $
---
✍️ Notify me about mention (cert required)
Mentions: