Post-quantum cryptography

Post-quantum cryptography

Post-quantum cryptography (PQC) #

Post-quantum cryptography (PQC) is a branch of cryptography that develops algorithms which are thought to be secure against attacks using hypothetical quantum computers (which don’t exist right now, but may be developed in the future).

Development and deployment of such algorithms defends against potential future attacks (in case relevant quantum computers materialize).

Defense against potential future attacks with quantum computers is of particular interest for encryption. In particular when it is relevant if an attacker might store encrypted communication and decrypt it in the future. Defending against such an attack requires deployment of countermeasures well before the attack becomes practical.

PQC in OpenPGP #

To enable OpenPGP users to defend against potential future attacks by quantum computers, the German BSI issued a tender in 2021 for development of PQC extensions in the OpenPGP ecosystem.

The presentation “Post-Quantum Policy & Roadmap” from 2023 offers some more insights into the BSIs goals and planning.

Presumably, the BSI is funding these efforts in part because it uses OpenPGP internally, and is aiming to protect its communications with PQC mechanisms. Part of the BSI-funded work is performed by MTG AG.

Draft and implementations #

The process to add PQC support to OpenPGP has produced the proposed standard draft-ietf-openpgp-pqc (which is currently in “working group last call”).

The draft was developed by a set of stakeholders including the German BSI and Proton AG, in collaboration with the larger OpenPGP IETF working group.

Implementations of the draft exist for multiple OpenPGP libraries (some funded by BSI, some developed independently):

Test builds of these implementations can currently be seen at work in the OpenPGP interoperability test suite, as “rnp 0.17.1+pqc”, “GopenPGP 3.0.0+pqc”, “OpenPGP.js 6.0.0+pqc” and “rpgpie 0.6.0+pqc”, respectively.

(Note that the long-established GnuPG software is also planning to roll out PQC algorithms. However, its implementation uses a home-grown variation of the format in draft-ietf-openpgp-pqc. GnuPG’s variant is incompatible with all other implementations.1)

PQC-enabled test build of rsop #

An experimental version of the rsop SOP CLI tool (based on rPGP) can currently be installed via:

$ cargo install --git https://codeberg.org/heiko/rsop.git --branch pqc rsop

Note that the formats produced by this binary reflect the format described in draft-ietf-openpgp-pqc-08, which is not yet finalized!

The outputs of this tool are strictly for testing only - they must not be used in production contexts!

OpenPGP PQC encryption with rsop #

That said, let’s play with OpenPGP using an algorithm from draft-ietf-openpgp-pqc-08.

(If you’re not familiar with the process of using SOP to encrypt messages with OpenPGP, you may first want to read the “Hello World” in OpenPGP article).

Generating a test key #

We start by generating a test key:

$ rsop generate-key --profile draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519 "<alice@test.example>"
-----BEGIN PGP PRIVATE KEY BLOCK-----

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
cnu2d+TkoKQK
=vtpI
-----END PGP PRIVATE KEY BLOCK-----

Note that we use the key generation profile draft-ietf-openpgp-pqc-08-v4-ed25519-mlkem768x25519.

This produces a regular OpenPGP “v4” key (with a traditional Ed25519 primary key). Only the encryption subkey deviates from currently commonly used OpenPGP keys: It uses a PQC algorithm, specifically the composite “ML-KEM-768 + X25519” scheme.

We store this transferable secret key (TSK) as alice-pqc.tsk, and extract the corresponding certificate (public key):

$ cat alice-pqc.tsk | rsop extract-cert
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
CBLuSLjwwOk5V3J7tnfk5KCkCg==
=H2lA
-----END PGP PUBLIC KEY BLOCK-----

We store this certificate in the file alice-pqc.cert.

Encrypting to Alice’s PQC certificate #

Now we can produce a PQC encrypted message for Alice, like this:

$ echo "hello alice" | rsop encrypt alice-pqc.cert
-----BEGIN PGP MESSAGE-----

wcPUA0/9japGJjCoI8kR/xadQ62uqJjJJD5OWNiQU8IVusoebr+72CJCJUtjXa3f
6sJx04HOCW7/sXMlrC13OfK+1tWOR8jwU39avGUmpBRYB0XMy5/pMWcNgQTTwcTA
Jm5UtuG5ZM1OzsgnbLo8iH9zzl6GnvZU+HoQ5y/rve3cw8PgUxJOmEueL2ODPYYw
7VPEDuRk6WGIhOW1DuFMcGmVsOUdLCjFxrGpuRImcM2vPWU4Z1AP6xBKyM6e/0gs
NPPVmQpEb4111SCPFwY3D6N0EzLz2EriE9cuw52W+L3QnJ2l5ucazg6y3LGnfWSJ
TYxQTuCiXoU5y1BVkBJ4JnBjA5z1rZWEEjCwpS6jyBAfHvrz/Kc/V8ZmEq+L7yw3
580Xka4o6s6IJD1LLfEg/b6/7xFdqZY6cMlDzOGxQfNE3AzpmyoLTKfXJvhyo7nR
IOv+ewoRKGZH7vjhTqhRYBUymVglJjqLSAnON42dFuMrlrdGMrilGrnzgzihgXdj
KtapMq9eW6WCUKUvrA1w2tFEzN9qbwzY672miqNltGJhOkRZzUiBZuuHiOfvhGWG
JL5FU+jgf/S/574mLSPqM0wqkydfTCdOr9pEFuescd+amUcy7KzLm/Y0Rm8rSghY
+KS0K+6Eg8sgwgZetqLTnWgeUmfpq6s039MPhsjT8Rq6J8dtPya12a08XHQUXxDS
v3PhfGuJG6tJ2lvJgj4KHQ5PX75SsPtIlRsLzMs6ufAkEwZXWVpoAZRoEdqJrR7R
R2IziigsnINqy9sOYi8zZ1qsvvKrwa/JnLHQOyygn3tEjvTF8KJMSplwlcDtjIOC
/WtwnDMurzsMKUEjLcwhYA3Jj0IomdshJ5OoDXd8O3lXWSKJD3cp+8XF8d2deZAn
vLW/wbHfAxsOM0ZbKIHiaVndK0hgMYBJXmglJTXkjtUGspr2v+SbP82m1etRu83A
WlRmHEV+ggsJbwSQ+bOKU9ja8UgqeEbeURuDfsgNOnrNdqtK24Z74VHSbUz56vqj
n7+V6ZAkiL3BW5Wwa854RFNtMPddJJJeCd5zN1ezQZbzMCcPiPFOzNQUT/xN5hbY
fQXtlTxhB1qcEbEG9y4XMUS/mUqDIezIOTEI34wuCzmfxgGBiXzL5dpv7G74+N5O
USC+4d0pXWldRrJTN0nWaZzSrv9SldsCWDlRZXt0yE1hqxdSbPSe8LXy+x9wVMvB
LhplAuy83fwua/HvF7GSdMa4j7oz2aIaF5WxAdLtReHAfMhbRL2xd4OLsr+zZy5n
iyfjeujXfv8W5LFVYn61NvudfBHrfgKI282Cwh7/uoHnZw5ZeQJ9YASHcs5BZBsS
qZ0S+qHVMYTVfMye5Wp4R2yJZs2bgMUho3lgf+YG5f70g01jqXqNeAmBJZCVKryP
zLXmzy6UbMzrzxnLw95sRp52PSH/nERpQjPo9jNNiOwGjxyR2bsOO3qioYkv6Zwc
f9BhLyQw7YZg8thCElj1RFMTFcBI/+xrKAoiBMwpCeIb7gwIBYQZc75AqBjpKHux
/3xC8mp/dL6QVt86ji+Q92rlROqg9NrSPQH3vQVqsNI97X52PzaPNLnJ8pL07KwY
bPo57RzNbsp7tqel+xbwm4IPVNBxPoJifIKZ9NR9aV4sdn01Ee8=
=gc6W
-----END PGP MESSAGE-----

This message is now protected by the algorithm of Alice’s (public) encryption subkey: A hybrid that internally combines the two algorithms ML-KEM-768 (also known under its original name “Kyber”, or as FIPS 203) and the traditional X25519.

An attacker would need to break both of these mechanisms in order to retrieve the plaintext of the message. As long as one of the two internally used algorithms holds up to attackers, the message’s confidentiality is assured.

We store this message as pqc-to-alice.msg.

Decrypting the message with Alice’s private key #

Alice can now decrypt is using her private key:

$ cat pqc-to-alice.msg | rsop decrypt alice-pqc.tsk
hello alice

Conclusion #

From an end-user perspective, PQC encryption and decryption look and feel exactly like encryption and decryption with traditional (non-PQC) algorithms.

Both PQC key material and messages are noticeably larger, and the computational cost of processing them is somewhat higher. But in most context, these differences won’t be crucial.


  1. GnuPG was one of the early Free Software implementations of OpenPGP.
    In its 2.5.x series, it began rolling out some support for PQC algorithms. However, GnuPG’s PQC formats are deviating from draft-ietf-openpgp-pqc. For unclear-to-me reasons, GnuPG has opted to implement a similar but subtly different and incompatible PQC scheme.
    This means that GnuPG’s current PQC formats are incompatible with the entire rest of the OpenPGP ecosystem.
    I hope that GnuPG will implement support for the IETF-standardized ML-KEM-768 + X25519 PQC encryption format in the future (this algorithm is explicitly intended for use with OpenPGP v4, as implemented by GnuPG).
    In the meantime, I’d strongly recommend against using GnuPG’s non-standard PQC support. ↩︎