-
|
Hi, I’ve been experimenting with OpenSSL 3 + OQS provider on embedded Linux/raspberrypi5 (ARM64) and benchmarking TLS 1.3 handshake latency: I’m observing something counter-intuitive in the results:
I'm a bit puzzeld by the results since I have expected: X25519 < Hybrid < Pure PQC Has anyone observed similar behavior? My Nginx configs are:
|
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 2 replies
-
|
Hey! Those results are actually plausible: MLKEM768 can be faster than X25519 on some hardware due to highly optimized AVX2/NEON implementations and smaller ciphertext sizes. The hybrid (X25519MLKEM768) combines both, so it may sit between them. Also, TLS 1.3 handshake latency is dominated by round trips and crypto operations; if the PQC code is better optimized or fits in cache, it can beat classical ECDH. Ensure you're testing with cold caches, same CPU frequency, and that the OpenSSL OQS provider is built with optimal flags. Interesting data — thanks for sharing! |
Beta Was this translation helpful? Give feedback.
-
|
yes I built But I suppose that OpenSSL build also benefits from optimization while using Before I ran the benchmark I set cpu(s) governor to |
Beta Was this translation helpful? Give feedback.
-
|
I tried the benchmark on an still that hybrid KEX is faster than |
Beta Was this translation helpful? Give feedback.
-
|
Can I ask @embetrix which exact Your very own embetrix/meta-oqs@e46e227 can easily explain why OQS MLKEM768 may be faster than OpenSSL X25519... However,
indeed is a statement that also surprises me if indeed the One last comment: Handshakes are a "pretty heavy" operation with many "moving parts" that may contribute to these results. At the time OQS had benchmarking support for TLS handshakes (a few years back) those results were among the least reliable, certainly when compared to pure |
Beta Was this translation helpful? Give feedback.
-
|
@baentsch thanks for your suggestion: I made OpenSSL speed tests: 1. Classicalroot@raspberrypi5-c8-bf-64:~# openssl speed ecdhx25519
Doing 253 bits ecdh ops for 10s: 60366 253-bits ECDH ops in 10.00s
version: 3.2.6
built on: Tue Sep 30 13:05:05 2025 UTC
options: bn(64,64)
compiler: aarch64-poky-linux-gcc -mcpu=cortex-a76+crypto -mbranch-protection=standard -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=recipe-sysroot -O2 -pipe -g -feliminate-unused-debug-types -fcanon-prefix-map -fmacro-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG
CPUINFO: OPENSSL_armcap=0xbd
op op/s
253 bits ecdh (X25519) 0.0002s 6036.62. Hybridroot@raspberrypi5-c8-bf-64:~# openssl speed X25519MLKEM768
Doing X25519MLKEM768 keygen ops for 10s: 98080 X25519MLKEM768 KEM keygen ops in 9.95s
Doing X25519MLKEM768 encaps ops for 10s: 37174 X25519MLKEM768 KEM encaps ops in 9.97s
Doing X25519MLKEM768 decaps ops for 10s: 36587 X25519MLKEM768 KEM decaps ops in 10.00s
version: 3.2.6
built on: Tue Sep 30 13:05:05 2025 UTC
options: bn(64,64)
compiler: aarch64-poky-linux-gcc -mcpu=cortex-a76+crypto -mbranch-protection=standard -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=recipe-sysroot -O2 -pipe -g -feliminate-unused-debug-types -fcanon-prefix-map -fmacro-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG
CPUINFO: OPENSSL_armcap=0xbd
keygen encaps decaps keygens/s encaps/s decaps/s
X25519MLKEM768 0.000101s 0.000268s 0.000273s 9857.3 3728.6 3658.73. PQCroot@raspberrypi5-c8-bf-64:~# openssl speed mlkem768
Doing mlkem768 keygen ops for 10s: 287919 mlkem768 KEM keygen ops in 9.94s
Doing mlkem768 encaps ops for 10s: 296703 mlkem768 KEM encaps ops in 9.94s
Doing mlkem768 decaps ops for 10s: 253984 mlkem768 KEM decaps ops in 10.00s
version: 3.2.6
built on: Tue Sep 30 13:05:05 2025 UTC
options: bn(64,64)
compiler: aarch64-poky-linux-gcc -mcpu=cortex-a76+crypto -mbranch-protection=standard -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=recipe-sysroot -O2 -pipe -g -feliminate-unused-debug-types -fcanon-prefix-map -fmacro-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -fdebug-prefix-map= -fmacro-prefix-map= -fdebug-prefix-map= -DOPENSSL_USE_NODELETE -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG
CPUINFO: OPENSSL_armcap=0xbd
keygen encaps decaps keygens/s encaps/s decaps/s
mlkem768 0.000035s 0.000034s 0.000039s 28965.7 29849.4 25398.4As expected Hybrid > Classical but PQC smoke classical kex :-) |
Beta Was this translation helpful? Give feedback.
-
|
I think that if I remove In this case: Enable back In this case: from another side |
Beta Was this translation helpful? Give feedback.
-
|
you are right, specifying the exchange method as curl option give more logical results:
|
Beta Was this translation helpful? Give feedback.
you are right, specifying the exchange method as curl option give more logical results:
x25519X25519MLKEM768mlkem768