All CPU threads
Robert J. Hansen
rjh at sixdemonbag.org
Sun Sep 10 04:07:04 CEST 2023
> Thank you for reply. I was thinking about speeding up the encryption
> process. But if that's not possible then that's how it is.
Thank you for sending a plain-text email to the list! :)
The answer is a little complicated, but this should be an
accurate-enough explanation.
Encryption speed is dominated by disk speed first and foremost. If
you're encrypting a 1Mb file, you have to read in the file and write it
out again when you're done: your absolute minimum time is given by
however long it takes to read and write a 1Mb file.
This is unfortunate, because disk I/O is *slow*. Even SSDs, which are
about ten to twenty times as fast as older spinning metal platter hard
drives, can't completely bridge this gap. So at the end of the day,
your bottleneck for encryption is going to be disk I/O.
There are various games people play, like keeping an in-memory
filesystem. If you're doing that, then we can look at other places for
speed improvement. Remember, as you read what follows: we're doing all
of these weird things to improve things by a very tiny bit -- the
bottleneck is in disk I/O!
=====
Encryption generates a random session key and encrypts that with your
recipient's public key. Here's your next problem: there are *so many*
algorithms GnuPG supports, and there isn't a single effective
parallelization strategy for all of them. Take RSA as an example: the
expensive part of the encryption operation is P = C^e (mod n), or as
normal humans call it, "modular exponentiation".
I've got an IEEE paper on my desk (by Budikafa and Pulungan) dating from
2017 that says you can parallelize modular exponentiation to get up to a
28% speed improvement. That's really nice! The problem is the phrase
"up to" a 28% speed improvement, and the fact that only RSA uses modular
exponentiation, so if your correspondent is using ECC you're kind of out
of luck.
So, when it comes to the asymmetric part of the encryption: a sequential
version takes a couple of milliseconds, and best-case scenario by
throwing multiple threads at it you can save 28% on two milliseconds.
This is not a big enough win to justify the multithreading.
Once you've encrypted the random session key for each recipient, now you
have to process the file 16 bytes at a time. For each block after the
first, the result of the last block's encryption is an input to the
current block's encryption. Block 0 (which is the first -- remember,
computer scientists are weird, we start counting at zero) doesn't depend
on anything; block 1 depends on having the output of block 0; block 2
depends on having the output of block 1; and so on. Even if you were to
spin up one thread per block you'd still get no speed improvement.
You'd be encrypting sequentially, one block at a time until you were
complete. Multi-threading is thus theoretically possible, but offers no
advantages.
(Note that Phil Rogaway kind of disagrees with me: he characterizes
parallelizing cipher feedback modes as possible "but awkward". When
Phil Rogaway, one of the sharpest cryptographers in the world, describes
an optimization as "awkward", I very quietly turn around and start
moving in the opposite direction. Clearly I am in over my head and I
need to escape.)
https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf -- search for the
words "but awkward".
Etcetera, etcetera. Speeding up encryption operations with multiple
threads is a *deeply* challenging cryptographic engineering problem, and
for the vast majority of users isn't worth it. The easy wins (28% cost
savings on RSA encryption! Whee, almost half a millisecond!) are too
trivial, and the big wins are somewhere between "Rogaway says it's
awkward" and "Rogaway says it's impossible".
That said, the next RFC draft -- when it comes out -- will be offering
new encryption modes that may offer better parallelization performance.
I'm sure that if and when the next RFC is officially released, there
will be interest in getting parallelization support for them.
More information about the Gnupg-users
mailing list