In the following speed table, smaller numbers are better.
The numbers are median single-core cycle counts on various microarchitectures.
Overclocking is disabled.
OpenSSL 3.1.1 cycle counts are reported as a baseline for comparison.
For comparability to OpenSSL's speed-testing utility,
the OpenSSL cycle counts omit various OpenSSL overheads; see below for details.
The lib25519 cycle counts include all overheads.
Each library is assigned one color in the table.
| uarch | software | X key | X dh | X batch | Ed key | Ed sign | Ed verif | Ed MSM |
| :---- | :------- | ----: | ---: | ------: | -----: | ------: | -------: | -----: |
| Zen 3 | OpenSSL | 119875 | 114972 | | 124406 | 110711 | 370539 | |
| | lib25519 | 26519 | 73086 | 47795 | 27287 | 30659 | 112326 | 41542
| Tiger Lake | OpenSSL | 115612 | 118735 | | 118894 | 110714 | 370523 | |
| | lib25519 | 26494 | 64627 | 21658 | 27278 | 31373 | 116180 | 39693
| Goldmont | OpenSSL | 248978 | 273332 | | 263920 | 226717 | 740570 | |
| | lib25519 | 88613 | 286276 | 280821 | 91012 | 100814 | 346731 | 95274
| Skylake | OpenSSL | 134236 | 118455 | | 139969 | 125875 | 410016 | |
| | lib25519 | 28293 | 88082 | 62417 | 28928 | 32588 | 113410 | 41775
| Airmont | OpenSSL | 310990 | 618831 | | 329070 | 276825 | 853552 | |
| | lib25519 | 143599 | 449168 | 449232 | 147183 | 162634 | 543339 | 155019
| Broadwell | OpenSSL | 128083 | 121267 | | 133816 | 120153 | 392282 | |
| | lib25519 | 29669 | 117858 | 72444 | 30654 | 34379 | 122012 | 41516
| Haswell | OpenSSL | 174947 | 165650 | | 180558 | 165981 | 428332 | |
| | lib25519 | 41449 | 115378 | 76555 | 42339 | 46362 | 160084 | 57325
| Core 2 | OpenSSL | 302407 | 341190 | | 311866 | 267854 | 755291 | |
| | lib25519 | 95106 | 306362 | 306431 | 98459 | 107278 | 363231 | 105382
In the lib25519 distribution,
`command/lib25519-speed.c` measures lib25519;
`speedcomparison/openssl/openssl25519speed.c` measures OpenSSL;
`benchmarks/*-*` is the output of `lib25519-speed` on various machines;
`speedcomparison/openssl/*-*` is the output of `openssl25519speed` on various machines;
and `autogen/md-speed` extracts the table from those outputs.
Microarchitectures in the table are listed in reverse chronological order of their introduction.
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 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 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_.