Page MenuHome GnuPG

Slow symmetric decryption speed
Closed, ResolvedPublic

Description

GnuPG appears to have quite slow symmetric decryption speed compared to encryption and other tools. This then shows up when users benchmark GnuPG against other tools (for example here: https://www.osso.nl/blog/encryption-decryption-speed-gnupg-openssl/).

Problem appears to be the extra hash contexts enable at: https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=g10/mainproc.c;h=1ee5b9a6e4c1e49ffb4d49024eddd79d1b96a229;hb=HEAD#l917.

With those manually disabled, symmetric AES256 decryption speeds up by 3x on current generation x86-64 cpu. I think it would be good if we could find way to disable those hash contexts when processing data encrypted with current GnuPG versions. Currently we needlessly waste users' time and computation power to support handling pre-2440 input. Also performance advances in libgcrypt go pretty much unnoticed because this extra computation. Maybe we could use some heuristic (packet version? etc) to avoid enabling extra SHA1 & RMD160 hashing?

Event Timeline

Breaking the flawless decryption of existing old data is unfortunately a highly controversy topic. Recall the no-more-v3 packet support or the required MDC. It was technically okay and 99.99% of the users didn't even notice it. But some were very vocational.

I think that a pretty save assumption is to depend this decision on the use of ECC. A not so safe one would be to make it depend on AES256 and no use of Elgamal. In any case the --rfc2440 switch could be used to renable the old hacks. I would say to start with "all recipients use ECC".

Benchmarking blog post that I linked tested GnuPG in symmetric mode, gpg --symmetric. I think symmetric case is important too from performance point of view, there is tools that use gpg --symmetric as bulk encryption/decryption backend (for example duplicity backup tool). Such encrypted files have tag3 (symmetric-key ESK) packet followed tag18 (encrypted and MDC) packet. Could existence of Tag18 packet in input be used as marker for input being rfc4880 and allow disabling those extra hash contexts? As I understand those hashes should not be needed with rfc4880 input (but I don't know all the historical details).

werner added a project: gnupg (gpg23).

Let's try this for 2.3

Cool. I did some quick tests with 2.2 on my pretty old X220 and it really makes sense to apply the patch there as well.:

Encrypt using gpg 2.3:

$ time -p gpg -z0 -evr wk@gnupg.org  --batch --yes  Jimi_plays_Monterey.mpg 

real    0m10.649s
user    0m6.840s
sys     0m2.500s

-rw-r-----  1 wk wk 1.6G Feb 24 13:00  Jimi_plays_Monterey.mpg.gpg

Decrypt with gpg 2.2 and libgcrypt 1.9 (w/o and with patch):

$ time -p gpg -d <Jimi_plays_Monterey.mpg.gpg >/dev/null
gpg: encrypted with 384-bit ECDH key, ID 2B999FA9CE046B1B, created 2021-06-28
      "wk@gnupg.org"

real    0m14.043s
user    0m13.284s
sys     0m0.652s
$ time -p gpg -d <Jimi_plays_Monterey.mpg.gpg >/dev/null
gpg: encrypted with 384-bit ECDH key, ID 2B999FA9CE046B1B, created 2021-06-28
      "wk@gnupg.org"

real    0m4.917s
user    0m4.147s
sys     0m0.644s

Decrypt with gpg 2.2 and libgcrypt 1.8:

$ time -p gpg -vd <Jimi_plays_Monterey.mpg.gpg >/dev/null
gpg: encrypted with 384-bit ECDH key, ID 2B999FA9CE046B1B, created 2021-06-28
      "wk@gnupg.org"
gpg: AES encrypted data
gpg: original file name='Jimi_plays_Monterey.mpg'

real 14.44
user 13.77
sys 0.56
$ time -p gpg -vd <Jimi_plays_Monterey.mpg.gpg >/dev/null
gpg: encrypted with 384-bit ECDH key, ID 2B999FA9CE046B1B, created 2021-06-28
      "wk@gnupg.org"
gpg: AES encrypted data
gpg: original file name='Jimi_plays_Monterey.mpg'

real 5.23
user 4.33
sys 0.65
werner claimed this task.