In the following speed table, smaller numbers are better.
The numbers are median single-core cycle counts on various microarchitectures.
Overclocking is disabled.
The table reports cycle counts from lib25519 and, for comparison,
OpenSSL and s2n-bignum.
For comparability to OpenSSL's speed-testing utility,
the OpenSSL cycle counts omit various OpenSSL overheads; see below for details.
The s2n-bignum and lib25519 cycle counts include all overheads.
There is also a lib25519+s2n line showing separate measurements of lib25519
after the optional pre-configuration `./use-s2n-bignum` step.
| μarch | software | X key | X dh | X batch | Ed key | Ed sign | Ed verif | Ed MSM |
| :---- | :------- | ----: | ---: | ------: | -----: | ------: | -------: | -----: |
| Golden Cove (2021) | OpenSSL | 119777 | 103594 | | 121526 | 95750 | 319234 | |
| | lib25519 | 23332 | 69037 | 49966 | 24373 | 28697 | 91956 | 37103
| | lib25519+s2n | 23889 | 68964 | 49907 | 24401 | 28030 | 93962 | 36701
| | s2n-bignum | 24257 | 75395 | | | | | |
| Firestorm (2020) | OpenSSL | 59900 | 65400 | | 60800 | 55900 | 195400 | |
| | lib25519 | 28500 | 57100 | 56750 | 28500 | 31300 | 204200 | 59900
| | lib25519+s2n | 21700 | 57900 | 56831 | 29500 | 32400 | 215900 | 61662
| | s2n-bignum | 14300 | 44200 | | | | | |
| Zen 3 (2020) | OpenSSL | 121785 | 112526 | | 124551 | 111757 | 372577 | |
| | lib25519 | 25621 | 73101 | 47967 | 26438 | 29800 | 111248 | 41567
| | lib25519+s2n | 25614 | 73250 | 47816 | 26476 | 29876 | 111301 | 41346
| | s2n-bignum | 26238 | 89699 | | | | | |
| Tiger Lake (2020) | OpenSSL | 116192 | 119125 | | 119341 | 111360 | 371294 | |
| | lib25519 | 26662 | 64680 | 21684 | 27321 | 31241 | 107766 | 39736
| | lib25519+s2n | 26245 | 64685 | 21695 | 27542 | 31152 | 108605 | 39347
| | s2n-bignum | 26474 | 83168 | | | | | |
| Zen 2 (2019) | OpenSSL | 131187 | 114889 | | 133766 | 121192 | 393580 | |
| | lib25519 | 27538 | 100750 | 73662 | 28448 | 31621 | 130793 | 46115
| | lib25519+s2n | 26700 | 94659 | 74817 | 28253 | 31487 | 130884 | 46111
| | s2n-bignum | 27058 | 92075 | | | | | |
| Goldmont (2016) | OpenSSL | 255650 | 273638 | | 269190 | 228278 | 746606 | |
| | lib25519 | 93894 | 280998 | 282937 | 182176 | 106552 | 348154 | 111511
| | lib25519+s2n | 76252 | 255310 | 258451 | 97018 | 106718 | 341734 | 97353
| | s2n-bignum | 77436 | 255312 | | | | | |
| Cortex-A72 (2016) | OpenSSL | 165596 | 424757 | | 173844 | 134485 | 423509 | |
| | lib25519 | 107170 | 331177 | 331403 | 108422 | 116220 | 407344 | 118316
| | lib25519+s2n | 66463 | 136554 | 136521 | 108048 | 115264 | 410675 | 117761
| | s2n-bignum | 67271 | 136516 | | | | | |
| Skylake (2015) | OpenSSL | 134951 | 118458 | | 138768 | 124961 | 411673 | |
| | lib25519 | 27802 | 83452 | 62451 | 28608 | 32026 | 107652 | 41742
| | lib25519+s2n | 27816 | 83223 | 63022 | 28583 | 31979 | 105726 | 41853
| | s2n-bignum | 28806 | 84561 | | | | | |
| Airmont (2015) | OpenSSL | 314248 | 618875 | | 326604 | 276991 | 852228 | |
| | lib25519 | 143716 | 449155 | 449333 | 151077 | 167509 | 555437 | 155354
| | lib25519+s2n | 115797 | 432042 | 432588 | 150556 | 168440 | 557483 | 155190
| | s2n-bignum | 116864 | 432414 | | | | | |
| Broadwell (2014) | OpenSSL | 128717 | 121228 | | 132360 | 120321 | 393241 | |
| | lib25519 | 29156 | 84649 | 73313 | 29705 | 33972 | 109784 | 41100
| | lib25519+s2n | 29034 | 87200 | 72483 | 29905 | 33799 | 109508 | 41852
| | s2n-bignum | 31396 | 87934 | | | | | |
| Haswell (2013) | OpenSSL | 134317 | 163773 | | 139345 | 125387 | 407967 | |
| | lib25519 | 41558 | 115276 | 76694 | 42365 | 46236 | 153852 | 58279
| | lib25519+s2n | 41508 | 117407 | 76569 | 42406 | 46859 | 155814 | 57725
| | s2n-bignum | 45860 | 160318 | | | | | |
| Cortex-A53 (2012) | OpenSSL | 271122 | 523848 | | 277838 | 216810 | 547938 | |
| | lib25519 | 152424 | 467492 | 466748 | 154103 | 163666 | 598089 | 173073
| | lib25519+s2n | 116946 | 163009 | 165112 | 153300 | 162717 | 600206 | 170632
| | s2n-bignum | 120158 | 163155 | | | | | |
| Core 2 (2006) | OpenSSL | 274293 | 326943 | | 282501 | 240597 | 741906 | |
| | lib25519 | 95814 | 301014 | 299719 | 99243 | 108216 | 359289 | 105870
| | lib25519+s2n | 73170 | 262746 | 262705 | 99027 | 108315 | 360225 | 105163
| | s2n-bignum | 80703 | 262971 | | | | | |
Microarchitectures are listed in reverse chronological order of when they were introduced.
Each library is assigned one foreground color in the table.
In the lib25519 distribution,
`command/lib25519-speed.c` measures lib25519;
`benchmarks/*-*` is the output of `lib25519-speed` on various machines;
`speedcomparison/openssl/*` has code to measure OpenSSL, and measurements from various machines;
`speedcomparison/s2n/*` has code to measure s2n-bignum, and measurements from various machines;
and `autogen/md-speed` extracts the table from those measurements.
OpenSSL benchmarks use version 3.2.1 (2024.01.30);
s2n-bignum benchmarks use commit acbb18e6343f12a7944de72c1ec0991739600f8c (2024.03.18).
The table reports only median cycle counts;
see the full output files
for differences between multiple measurements and the median.
The table reports the following major operations:
* "X key": Generating an X25519 public key and secret key.
This is `dh_x25519_keypair selected 32` in the `lib25519-speed` output
(`lib25519_dh_keypair` in the stable API).
For s2n-bignum,
this is `x25519-keygen` in the `s2n25519speed` output,
measuring the cost of `curve25519_x25519base_byte_alt`,
or `curve25519_x25519base_byte` on machines where that works and is faster.
For OpenSSL,
this is `x25519-keygen-main` in the `openssl25519speed` output,
measuring the cost of `EVP_PKEY_Q_keygen(0,0,"X25519")`.
This does not include small OpenSSL overheads for converting the public key and secret key to storage format.
* "X dh":
Generating an X25519 shared secret.
This is `dh_x25519 selected 32` in the `lib25519-speed` output
(`lib25519_dh` in the stable API).
For s2n-bignum,
this is `x25519-dh` in the `s2n25519speed` output,
measuring the cost of `curve25519_x25519_byte_alt`,
or `curve25519_x25519_byte` on machines where that works and is faster.
For OpenSSL,
this is `x25519-dh-main` in the `openssl25519speed` output,
measuring the cost of `EVP_PKEY_derive`
(as in OpenSSL's speed-testing utility).
This does not include the cost of `EVP_PKEY_new_raw_public_key`
to decode the public key (8376 cycles on Tiger Lake),
`EVP_PKEY_CTX_new` and `EVP_PKEY_derive_init` and `EVP_PKEY_derive_set_peer` for initialization
(together 7660 cycles on Tiger Lake),
and
`EVP_PKEY_new_raw_private_key` to decode the secret key if it is not decoded already
(113498 cycles on Tiger Lake).
* "X batch":
Cost _per secret_ of generating 16 separate shared secrets.
This is `nPbatch_montgomery25519 selected 16` in the `lib25519-speed` output _divided by 16_.
* "Ed key": Generating an Ed25519 public key and secret key.
This is `sign_ed25519_keypair selected 32` in the `lib25519-speed` output
(`lib25519_sign_keypair` in the stable API).
For OpenSSL,
this is `ed25519-keygen-main` in the `openssl25519speed` output,
measuring the cost of `EVP_PKEY_Q_keygen(0,0,"ED25519")`.
This does not include small OpenSSL overheads for converting the public key and secret key to storage format.
* "Ed sign": Generating an Ed25519 signature of a 59-byte message.
This is `sign_ed25519 selected 59` in the `lib25519-speed` output
(`lib25519_sign` in the stable API).
For OpenSSL,
this is `ed25519-sign-main` in the `openssl25519speed` output,
measuring the cost of `EVP_DigestSign`
(as in OpenSSL's speed-testing utility).
This does not include the cost of
`EVP_MD_CTX_new` and
`EVP_DigestSignInit`
(together 6258 cycles on Tiger Lake),
and `EVP_PKEY_new_raw_private_key` to decode the secret key if it is not decoded already
(116808 cycles on Tiger Lake).
* "Ed verif": Verifying an Ed25519 signature and recovering a 59-byte message.
This is `sign_ed25519_open selected 59` in the `lib25519-speed` output
(`lib25519_sign_open` in the stable API).
For OpenSSL,
this is `ed25519-verify-main` in the `openssl25519speed` output,
measuring the cost of `EVP_DigestVerify`
(as in OpenSSL's speed-testing utility).
This does not include the cost of
`EVP_MD_CTX_new` and
`EVP_DigestVerifyInit`
(together 6054 cycles on Tiger Lake),
and `EVP_PKEY_new_raw_public_key`
to decode the public key being used for verification
(9560 cycles on Tiger Lake).
* "Ed MSM": Cost _per point_ of multi-scalar multiplication with 16 points and 16 full-size scalars.
This is `multiscalar_ed25519 selected 16` in the `lib25519-speed` output _divided by 16_.