PQ/T Composite Schemes for OpenPGP using NIST and Brainpool Elliptic Curve Domain Parameters
Internet-Draft draft-ehlen-openpgp-nist-bp-comp-00
Quynh Dang
NIST
USA
quynh.dang@nist.gov
Stephan Ehlen
BSI
Germany
stephan.ehlen@bsi.bund.de
Johannes Roth
MTG AG
Germany
johannes.roth@mtg.de
Falko Strenzke
MTG AG
Germany
falko.strenzke@mtg.de
08 July 2024
sec
Network Working Group
Internet-Draft
This document defines PQ/T composite schemes based on ML-KEM and ML-DSA combined with ECC algorithms using the NIST and Brainpool domain parameters for the OpenPGP protocol.
About This Document
Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ehlen-openpgp-nist-bp-comp/.
Discussion of this document takes place on the WG Working Group mailing list (mailto:openpgp@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/openpgp/. Subscribe at https://www.ietf.org/mailman/listinfo/openpgp/.
Source for this draft and an issue tracker can be found at https://github.com/openpgp-pqc/draft-ehlen-openpgp-nist-bp-comp.
Introduction
This document defines PQ/T composite schemes based on ML-KEM and ML-DSA combined with ECDH and ECDSA using the NIST and Brainpool domain parameters for the OpenPGP protocol. As such it extends [draft-ietf-openpgp-pqc-03], which introduces post-quantum cryptography in OpenPGP. The ML-KEM and ML-DSA composite schemes defined in that document are built with ECC algorithms using the Edwards Curves defined in [RFC8032] and [RFC7748]. This document extends the set of algorithms given in [draft-ietf-openpgp-pqc-03] by further combinations of ML-KEM and ML-DSA with the NIST [SP800-186] and Brainpool [RFC5639] domain parameters. The support of NIST and Brainpool domain parameters is required in various applications related to certain regulatory environments.
Conventions used in this Document
Terminology for Multi-Algorithm Schemes
The terminology in this document is oriented towards the definitions in [draft-driscoll-pqt-hybrid-terminology]. Specifically, the terms "multi-algorithm", "composite" and "non-composite" are used in correspondence with the definitions therein. The abbreviation "PQ" is used for post-quantum schemes. To denote the combination of post-quantum and traditional schemes, the abbreviation "PQ/T" is used. The short form "PQ(/T)" stands for PQ or PQ/T.
Post-Quantum Cryptography
This section describes the individual post-quantum cryptographic schemes. All schemes listed here are believed to provide security in the presence of a cryptographically relevant quantum computer.
[Note to the reader: This specification refers to the NIST PQC draft standards FIPS 203 and FIPS 204 as if they were a final specification. This is a temporary solution until the final versions of these documents are available. The goal is to provide a sufficiently precise specification of the algorithms already at the draft stage of this specification, so that it is possible for implementers to create interoperable implementations. Furthermore, we want to point out that, depending on possible future changes to the draft standards by NIST, this specification may be updated as soon as corresponding information becomes available.]
ML-KEM
ML-KEM [FIPS-203] is based on the hardness of solving the Learning with Errors problem in module lattices (MLWE). The scheme is believed to provide security against cryptanalytic attacks by classical as well as quantum computers. This specification defines ML-KEM only in composite combination with ECC-based encryption schemes in order to provide a pre-quantum security fallback.
ML-DSA
ML-DSA [FIPS-204] is a signature scheme that, like ML-KEM, is based on the hardness of solving the Learning With Errors problem and a variant of the Short Integer Solution problem in module lattices (MLWE and SelfTargetMSIS). Accordingly, this specification only defines ML-DSA in composite combination with ECC-based signature schemes.
Elliptic Curve Cryptography
The ECC-based encryption is defined here as a KEM. This is in contrast to [I-D.ietf-openpgp-crypto-refresh] where the ECC-based encryption is defined as a public-key encryption scheme.
All elliptic curves for the use in the composite combinations are taken from [I-D.ietf-openpgp-crypto-refresh].
For interoperability this extension offers ML-* in composite combinations with the NIST curves P-256, P-384 defined in [SP800-186] and the Brainpool curves brainpoolP256r1, brainpoolP384r1 defined in [RFC5639].
Applicable Specifications for the use of PQC Algorithms in OpenPGP
This document is to be understood as an extension of [draft-ietf-openpgp-pqc-03], which introduced PQC in OpenPGP, in that it defines further algorithm code points. All general specifications in [draft-ietf-openpgp-pqc-03] that pertain to the ML-KEM and ML-DSA composite schemes or generally cryptographic schemes defined therein equally apply to the schemes specified in this document.
Preliminaries
This section provides some preliminaries for the definitions in the subsequent sections.
Elliptic curves
SEC1 EC Point Wire Format
Elliptic curve points of the generic prime curves are encoded using the SEC1 (uncompressed) format as the following octet string:

B = 04 || X || Y

where X and Y are coordinates of the elliptic curve point P = (X, Y), and each coordinate is encoded in the big-endian format and zero-padded to the adjusted underlying field size. The adjusted underlying field size is the underlying field size rounded up to the nearest 8-bit boundary, as noted in the "Field size" column in Table 3, Table 4, or Table 7. This encoding is compatible with the definition given in [SEC1].
Measures to Ensure Secure Implementations
In the following measures are described that ensure secure implementations according to existing best practices and standards defining the operations of Elliptic Curve Cryptography.
Even though the zero point, also called the point at infinity, may occur as a result of arithmetic operations on points of an elliptic curve, it MUST NOT appear in any ECC data structure defined in this document.
Furthermore, when performing the explicitly listed operations in Section 5.1.1.1 it is REQUIRED to follow the specification and security advisory mandated from the respective elliptic curve specification.
Supported Public Key Algorithms
This section specifies the composite ML-KEM + ECC and ML-DSA + ECC schemes. All of these schemes are fully specified via their algorithm ID, i.e., they are not parametrized.
Algorithm Specifications
For encryption, the following composite KEM schemes are specified:
KEM algorithm specifications
ID | Algorithm | Requirement | Definition
TBD | ML-KEM-512+ECDH-NIST-P-256 | MAY | Section 5.2
TBD | ML-KEM-768+ECDH-NIST-P-384 | MAY | Section 5.2
TBD | ML-KEM-1024+ECDH-NIST-P-384 | MAY | Section 5.2
TBD | ML-KEM-768+ECDH-brainpoolP256r1 | MAY | Section 5.2
TBD | ML-KEM-1024+ECDH-brainpoolP384r1 | MAY | Section 5.2
For signatures, the following (composite) signature schemes are specified:
Signature algorithm specifications
ID | Algorithm | Requirement | Definition
TBD | ML-DSA-44+ECDSA-NIST-P-256 | MAY | Section 6.2
TBD | ML-DSA-65+ECDSA-NIST-P-384 | MAY | Section 6.2
TBD | ML-DSA-87+ECDSA-NIST-P-384 | MAY | Section 6.2
TBD | ML-DSA-65+ECDSA-brainpoolP256r1 | MAY | Section 6.2
TBD | ML-DSA-87+ECDSA-brainpoolP384r1 | MAY | Section 6.2
Experimental Codepoints for Interop Testing
[ Note: this section to be removed before publication ]
Algorithms indicated as MAY are not assigned a codepoint in the current state of the draft since there are not enough private/experimental code points available to cover all newly introduced public-key algorithm identifiers.
The use of private/experimental codepoints during development are intended to be used in non-released software only, for experimentation and interop testing purposes only. An OpenPGP implementation MUST NOT produce a formal release using these experimental codepoints. This draft will not be sent to IANA without every listed algorithm having a non-experimental codepoint.
Algorithm Combinations
Composite KEMs
The ML-KEM + ECC public-key encryption involves both the ML-KEM and an ECC-based KEM in an a priori non-separable manner. This is achieved via KEM combination, i.e. both key encapsulations/decapsulations are performed in parallel, and the resulting key shares are fed into a key combiner to produce a single shared secret for message encryption.
Composite Signatures
The ML-DSA + ECC signature consists of independent ML-DSA and ECC signatures, and an implementation MUST successfully validate both signatures to state that the ML-DSA + ECC signature is valid.
Composite KEM schemes
Building Blocks
ECC-Based KEMs
In this section we define the encryption, decryption, and data formats for the ECDH component of the composite algorithms.
Table 3 and Table 4 describe the ECC-KEM parameters and artifact lengths.
NIST curves parameters and artifact lengths
| NIST P-256 | NIST P-384
Algorithm ID reference | TBD (ML-KEM-512+ECDH-NIST-P-256) | TBD (ML-KEM-768+ECDH-NIST-P-384, ML-KEM-1024+ECDH-NIST-P-384, )
Field size | 32 octets | 48 octets
ECC-KEM | ecdhKem (Section 5.1.1.1) | ecdhKem (Section 5.1.1.1)
ECDH public key | 65 octets of SEC1-encoded public point | 97 octets of SEC1-encoded public point
ECDH secret key | 32 octets big-endian encoded secret scalar | 48 octets big-endian encoded secret scalar
ECDH ephemeral | 65 octets of SEC1-encoded ephemeral point | 97 octets of SEC1-encoded ephemeral point
ECDH share | 65 octets of SEC1-encoded shared point | 97 octets of SEC1-encoded shared point
Key share | 32 octets | 64 octets
Hash | SHA3-256 | SHA3-512
Brainpool curves parameters and artifact lengths
| brainpoolP256r1 | brainpoolP384r1
Algorithm ID reference | TBD (ML-KEM-768+ECDH-brainpoolP256r1) | TBD (ML-KEM-1024+ECDH-brainpoolP384r1)
Field size | 32 octets | 48 octets
ECC-KEM | ecdhKem (Section 5.1.1.1) | ecdhKem (Section 5.1.1.1)
ECDH public key | 65 octets of SEC1-encoded public point | 97 octets of SEC1-encoded public point
ECDH secret key | 32 octets big-endian encoded secret scalar | 48 octets big-endian encoded secret scalar
ECDH ephemeral | 65 octets of SEC1-encoded ephemeral point | 97 octets of SEC1-encoded ephemeral point
ECDH share | 65 octets of SEC1-encoded shared point | 97 octets of SEC1-encoded shared point
Key share | 32 octets | 64 octets
Hash | SHA3-256 | SHA3-512
The SEC1 format for point encoding is defined in Section 2.1.1.
The various procedures to perform the operations of an ECC-based KEM are defined in the following subsections. Specifically, each of these subsections defines the instances of the following operations:

(eccCipherText, eccKeyShare) <- ECC-KEM.Encaps(eccPublicKey)

and

(eccKeyShare) <- ECC-KEM.Decaps(eccSecretKey, eccCipherText, eccPublicKey)

To instantiate ECC-KEM, one must select a parameter set from Table 3 or Table 4.
ECDH-KEM
The operation ecdhKem.Encaps() is defined as follows: 1. Generate an ephemeral key pair {v, V=vG} as defined in [SP800-186] or [RFC5639] where v is a random scalar with 0 < v < n, n being the base point order of the elliptic curve domain parameters
1. Compute the shared point S = vR, where R is the component public key eccPublicKey, according to [SP800-186] or [RFC5639]
2. Extract the X coordinate from the SEC1 encoded point S = 04 || X || Y as defined in section 2.1.1
3. Set the output eccCipherText to the SEC1 encoding of V
4. Set the output eccKeyShare to Hash(X || eccCipherText || eccPublicKey), with Hash chosen according to Table 3 or Table 4
The operation ecdhKem.Decaps() is defined as follows:
1. Compute the shared Point S as rV, where r is the eccSecretKey and V is the eccCipherText, according to [SP800-186] or [RFC5639]
2. Extract the X coordinate from the SEC1 encoded point S = 04 || X || Y as defined in section 2.1.1
3. Set the output eccKeyShare to Hash(X || eccCipherText || eccPublicKey), with Hash chosen according to Table 3 or Table 4
ML-KEM
ML-KEM features the following operations:

(mlkemCipherText, mlkemKeyShare) <- ML-KEM.Encaps(mlkemPublicKey)

and

(mlkemKeyShare) <- ML-KEM.Decaps(mlkemCipherText, mlkemSecretKey)

The above are the operations ML-KEM.Encaps and ML-KEM.Decaps defined in [FIPS-203]. Note that mlkemPublicKey is the encapsulation and mlkemSecretKey is the decapsulation key.
ML-KEM has the parametrization with the corresponding artifact lengths in octets as given in Table 5. All artifacts are encoded as defined in [FIPS-203].
ML-KEM parameters artifact lengths in octets
Algorithm ID reference | ML-KEM | Public key | Secret key | Ciphertext | Key share
TBD | ML-KEM-512 | 800 | 1632 | 768 | 32
TBD | ML-KEM-768 | 1184 | 2400 | 1088 | 32
TBD | ML-KEM-1024 | 1568 | 3168 | 1568 | 32
To instantiate ML-KEM, one must select a parameter set from the column "ML-KEM" of Table 5.
The procedure to perform ML-KEM.Encaps() is as follows:
1. Invoke (mlkemCipherText, mlkemKeyShare) <- ML-KEM.Encaps(mlkemPublicKey), where mlkemPublicKey is the recipient's public key
2. Set mlkemCipherText as the ML-KEM ciphertext
3. Set mlkemKeyShare as the ML-KEM symmetric key share
The procedure to perform ML-KEM.Decaps() is as follows:
1. Invoke mlkemKeyShare <- ML-KEM.Decaps(mlkemCipherText, mlkemSecretKey)
2. Set mlkemKeyShare as the ML-KEM symmetric key share
Composite Encryption Schemes with ML-KEM
Table 1 specifies the following ML-KEM + ECC composite public-key encryption schemes:
ML-KEM + ECC composite schemes
Algorithm ID reference | ML-KEM | ECC-KEM | ECC-KEM curve
TBD (ML-KEM-512+ECDH-NIST-P-256) | ML-KEM-512 | ecdhKem | NIST P-256
TBD (ML-KEM-768+ECDH-NIST-P-384) | ML-KEM-768 | ecdhKem | NIST P-384
TBD (ML-KEM-1024+ECDH-NIST-P-384) | ML-KEM-1024 | ecdhKem | NIST P-384
TBD (ML-KEM-768+ECDH-brainpoolP256r1) | ML-KEM-768 | ecdhKem | brainpoolP256r1
TBD (ML-KEM-1024+ECDH-brainpoolP384r1) | ML-KEM-1024 | ecdhKem | brainpoolP384r1
The ML-KEM + ECC composite public-key encryption schemes are built according to the following principal design:
- The ML-KEM encapsulation algorithm is invoked to create an ML-KEM ciphertext together with an ML-KEM symmetric key share.
- The encapsulation algorithm of an ECDH-KEM is invoked to create an ECC ciphertext together with an ECC symmetric key share.
- A Key-Encryption-Key (KEK) is computed as the output of a key combiner that receives as input both of the above created symmetric key shares and the protocol binding information.
- The session key for content encryption is then encrypted with the AES Key Wrap Algorithm [RFC3394] with AES-256 as the encryption algorithm and using the KEK as the encryption key.
- The PKESK package's algorithm-specific parts are made up of the ML-KEM ciphertext, the ECC ciphertext, and the wrapped session key.
Fixed information
For the composite KEM schemes defined in Table 1 the following fixed information, which is identical to one specified in [draft-ietf-openpgp-pqc-03], MUST be used in the subsequently described key combiner Section 5.2.2.

//   Input:
//   algID - the algorithm ID encoded as octet
//
//   Constants:
//   domSeparation - the UTF-8 encoding of the string
//                   "OpenPGPCompositeKDFv1"

fixedInfo = algID || domSeparation

The value of domSeparation is the UTF-8 encoding of the string "OpenPGPCompositeKDFv1" and MUST be the following octet sequence:

domSeparation := 4F 70 65 6E 50 47 50 43 6F 6D 70 6F 73 69 74 65 4B
                 44 46 76 31

Key combiner
For the composite KEM schemes defined in Table 1 the following procedure, which is identical to one described in [draft-ietf-openpgp-pqc-03], MUST be used to compute the KEK that wraps a session key. The construction is a one-step key derivation function compliant to [SP800-56C], Section 4, based on SHA3-256. It is given by the following algorithm, which computes the key encryption key KEK that is used to wrap, i.e., encrypt, the session key.
[Note to the reader: the key combiner defined in the current version of this draft is not actually compliant to [SP800-56C], since the NIST standard requires that the shared secret is fed to the KDF first whereas the combiner defined here feeds the key shares of the two component schemes, which together form the shared secret, in two parts with public information in between. The combiner will be reworked to fix this defect in conformance to the combiner defined in draft-ietf-openpgp-pqc. The change is planned to be integrated into both drafts prior to IETF 121.]

//   multiKeyCombine(ecdhKeyShare, ecdhCipherText, ecdhPublicKey, mlkemKeyShare,
//                   mlkemCipherText, mlkemPublicKey, fixedInfo)
//
//   Input:
//   ecdhKeyShare    - the ECDH key share encoded as an octet string
//   ecdhCipherText  - the ECDH ciphertext encoded as an octet string
//   mlkemKeyShare   - the ML-KEM key share encoded as an octet string
//   mlkemCipherText - the ML-KEM ciphertext encoded as an octet string
//   ecdhPublicKey   - The ECDH public key of the recipient as an octet string
//   mlkemPublicKey  - The ML-KEM public key of the recipient as an octet string
//   fixedInfo       - the fixed information octet string
//
//   Constants:
//   counter - the 4 byte value 00 00 00 01

ecdhData = ecdhKeyShare || ecdhCipherText || ecdhPublicKey
mlkemData = mlkemKeyShare || mlkemCipherText || mlkemPublicKey

KEK = SHA3-256(counter || ecdhData || mlkemData || fixedInfo)
return KEK

The value of counter MUST be set to the following octet sequence:

counter :=  00 00 00 01

The value of fixedInfo MUST be set according to Section 5.2.1.
Key generation procedure
The implementation MUST independently generate the ML-KEM and the ECC component keys. ML-KEM key generation follows the specification [FIPS-203] and the artifacts are encoded as fixed-length octet strings as defined in Section 5.1.2. For ECC this is done following the relative specification in [SP800-186] or [RFC5639], and encoding the outputs as fixed-length octet strings in the format specified in Table 3 or Table 4.
Encryption procedure
The procedure to perform public-key encryption with an ML-KEM + ECC composite scheme is as follows:
1. Take the recipient's authenticated public-key packet pkComposite and sessionKey as input
2. Parse the algorithm ID from pkComposite
3. Extract the eccPublicKey and mlkemPublicKey component from the algorithm specific data encoded in pkComposite with the format specified in Section 5.3.2.
4. Instantiate the ECC-KEM and the ML-KEM depending on the algorithm ID according to Table 6
5. Compute (eccCipherText, eccKeyShare) := ECC-KEM.Encaps(eccPublicKey)
6. Compute (mlkemCipherText, mlkemKeyShare) := ML-KEM.Encaps(mlkemPublicKey)
7. Compute fixedInfo as specified in Section 5.2.1
8. Compute KEK := multiKeyCombine(eccKeyShare, eccCipherText, eccPublicKey, mlkemKeyShare, mlkemCipherText, mlkemPublicKey, fixedInfo) as defined in Section 5.2.2
9. Compute C := AESKeyWrap(KEK, sessionKey) with AES-256 as per [RFC3394] that includes a 64 bit integrity check
10. Output the algorithm specific part of the PKESK as eccCipherText || mlkemCipherText len(symAlgId, C) || (|| symAlgId) || C, where both symAlgId and len(C, symAlgId) are single octet fields, symAlgId denotes the symmetric algorithm ID used and is present only for a v3 PKESK, and len(C, symAlgId) denotes the combined octet length of the fields specified as the arguments.
Decryption procedure
The procedure to perform public-key decryption with an ML-KEM + ECC composite scheme is as follows:
1. Take the matching PKESK and own secret key packet as input
2. From the PKESK extract the algorithm ID and the encryptedKey, i.e., the wrapped session key
3. Check that the own and the extracted algorithm ID match
4. Parse the eccSecretKey and mlkemSecretKey from the algorithm specific data of the own secret key encoded in the format specified in Section 5.3.2
5. Instantiate the ECC-KEM and the ML-KEM depending on the algorithm ID according to Table 6
6. Parse eccCipherText, mlkemCipherText, and C from encryptedKey encoded as eccCipherText || mlkemCipherText || len(symAlgId, C) (|| symAlgId) || C as specified in Section 5.3.1, where symAlgId is present only in the case of a v3 PKESK.
7. Compute (eccKeyShare) := ECC-KEM.Decaps(eccCipherText, eccSecretKey, eccPublicKey)
8. Compute (mlkemKeyShare) := ML-KEM.Decaps(mlkemCipherText, mlkemSecretKey)
9. Compute fixedInfo as specified in Section 5.2.1
10. Compute KEK := multiKeyCombine(eccKeyShare, eccCipherText, eccPublicKey, mlkemKeyShare, mlkemCipherText, mlkemPublicKey, fixedInfo) as defined in Section 5.2.2
11. Compute sessionKey := AESKeyUnwrap(KEK, C) with AES-256 as per [RFC3394], aborting if the 64 bit integrity check fails
12. Output sessionKey
Packet specifications
Public-Key Encrypted Session Key Packets (Tag 1)
The algorithm-specific fields consists of the output of the encryption procedure described in Section 5.2.4:
- A fixed-length octet string representing an ECC ephemeral public key in the format associated with the curve as specified in Section 5.1.1.
- A fixed-length octet string of the ML-KEM ciphertext, whose length depends on the algorithm ID as specified in Table 5.
- A one-octet size of the following fields.
- Only in the case of a v3 PKESK packet: a one-octet symmetric algorithm identifier.
- The wrapped session key represented as an octet string.
Note that like in the case of the algorithms X25519 and X448 specified in [I-D.ietf-openpgp-crypto-refresh], for the ML-KEM+ECC composite schemes, in the case of a v3 PKESK packet, the symmetric algorithm identifier is not encrypted. Instead, it is placed in plaintext after the mlkemCipherText and before the length octet preceding the wrapped session key. In the case of v3 PKESK packets for ML-KEM composite schemes, the symmetric algorithm used MUST be AES-128, AES-192 or AES-256 (algorithm ID 7, 8 or 9).
In the case of a v3 PKESK, a receiving implementation MUST check if the length of the unwrapped symmetric key matches the symmetric algorithm identifier, and abort if this is not the case.
Key Material Packets
The algorithm-specific public key is this series of values:
- A fixed-length octet string representing an EC point public key, in the point format associated with the curve specified in Section 5.1.1.
- A fixed-length octet string containing the ML-KEM public key, whose length depends on the algorithm ID as specified in Table 5.
The algorithm-specific secret key is these two values:
- A fixed-length octet string of the encoded secret scalar, whose encoding and length depend on the algorithm ID as specified in Section 5.1.1.
- A fixed-length octet string containing the ML-KEM secret key, whose length depends on the algorithm ID as specified in Table 5.
Composite Signature Schemes
Building blocks
ECDSA-Based signatures
To sign and verify with ECDSA the following operations are defined:

(ecdsaSignatureR, ecdsaSignatureS) <- ECDSA.Sign(ecdsaSecretKey,
                                                 dataDigest)

and

(verified) <- ECDSA.Verify(ecdsaPublicKey, ecdsaSignatureR,
                           ecdsaSignatureS, dataDigest)

Here, the operation ECDSA.Sign() is defined as the algorithm in Section "6.4.1 ECDSA Signature Generation Algorithm" of [SP800-186-5], however, excluding Step 1: H = Hash(M) in that algorithm specification, as in this specification the message digest H is a direct input to the operation ECDSA.Sign(). Equivalently, the operation ECDSA.Sign() can be understood as representing the algorithm under Section "4.2.1.1. Signature Algorithm" in [TR-03111], again with the difference that in this specification the message digest H_Tau(M) appearing in Step 5 of the algorithm specification is the direct input to the operation ECDSA.Sign() and thus the hash computation is not carried out. The same statement holds for the definition of the verification operation ECDSA.Verify(): it is given either through the algorithm defined in Section "6.4.2 ECDSA Signature Verification Algorithm" of [SP800-186-5] omitting the message digest computation in Step 2 or by the algorithm in Section "4.2.1.2. Verification Algorithm" of [TR-03111] omitting the message digest computation in Step 3.
The public keys MUST be encoded in SEC1 format as defined in section 2.1.1. The secret key, as well as both values R and S of the signature MUST each be encoded as a big-endian integer in a fixed-length octet string of the specified size.
The following table describes the ECDSA parameters and artifact lengths:
ECDSA parameters and artifact lengths in octets
Algorithm ID reference | Curve | Field size | Public key | Secret key | Signature value R | Signature value S
TBD (ML-DSA-44+ECDSA-NIST-P-256) | NIST P-256 | 32 | 65 | 32 | 32 | 32
TBD (ML-DSA-65+ECDSA-NIST-P-384,ML-DSA-87+ECDSA-NIST-P-384) | NIST P-384 | 48 | 97 | 48 | 48 | 48
TBD (ML-DSA-65+ECDSA-brainpoolP256r1) | brainpoolP256r1 | 32 | 65 | 32 | 32 | 32
TBD (ML-DSA-87+ECDSA-brainpoolP384r1) | brainpoolP384r1 | 48 | 97 | 48 | 48 | 48
ML-DSA signatures
For ML-DSA signature generation the default hedged version of ML-DSA.Sign given in [FIPS-204] is used. That is, to sign with ML-DSA the following operation is defined:

(mldsaSignature) <- ML-DSA.Sign(mldsaSecretKey, dataDigest)

For ML-DSA signature verification the algorithm ML-DSA.Verify given in [FIPS-204] is used. That is, to verify with ML-DSA the following operation is defined:

(verified) <- ML-DSA.Verify(mldsaPublicKey, dataDigest, mldsaSignature)

ML-DSA has the parametrization with the corresponding artifact lengths in octets as given in Table 8. All artifacts are encoded as defined in [FIPS-204].
ML-DSA parameters and artifact lengths in octets
Algorithm ID reference | ML-DSA | Public key | Secret key | Signature value
TBD | ML-DSA-44 | 1312 | 2528 | 2420
TBD | ML-DSA-65 | 1952 | 4032 | 3293
TBD | ML-DSA-87 | 2592 | 4896 | 4595
Composite Signature Schemes with ML-DSA
Signature data digest
Signature data (i.e. the data to be signed) is digested prior to signing operations, see [I-D.ietf-openpgp-crypto-refresh], Section 5.2.4. Composite ML-DSA + ECC signatures MUST use the associated hash algorithm as specified in Table 9 for the signature data digest. Signatures using other hash algorithms MUST be considered invalid.
An implementation supporting a specific ML-DSA + ECC algorithm MUST also support the matching hash algorithm.
Binding between ML-DSA + ECDSA and signature data digest
Algorithm ID reference | Hash function | Hash function ID reference
TBD (ML-DSA-44 IDs) | SHA3-256 | 12
TBD (ML-DSA-65 IDs) | SHA3-512 | 14
TBD (ML-DSA-87 IDs) | SHA3-512 | 14
Key generation procedure
The implementation MUST independently generate the ML-DSA and the ECC component keys. ML-DSA key generation follows the specification [FIPS-204] and the artifacts are encoded as fixed-length octet strings as defined in Section 6.1.2. For ECC this is done following the relative specification in [SP800-186] or [RFC5639], and encoding the artifacts as specified in Section 6.1.1 as fixed-length octet strings.
Signature Generation
To sign a message M with ML-DSA + ECDSA the following sequence of operations has to be performed:
1. Generate dataDigest according to [I-D.ietf-openpgp-crypto-refresh], Section 5.2.4
2. Create the ECDSA signature over dataDigest with ECDSA.Sign() from Section 6.1.1
3. Create the ML-DSA signature over dataDigest with ML-DSA.Sign() from Section 6.1.2
4. Encode the ECDSA and ML-DSA signatures according to the packet structure given in Section 6.3.1.
Signature Verification
To verify an ML-DSA + ECDSA signature the following sequence of operations has to be performed:
1. Verify the ECDSA signature with ECDSA.Verify() from Section 6.1.1
2. Verify the ML-DSA signature with ML-DSA.Verify() from Section 6.1.2
As specified in Section 4.2 an implementation MUST validate both signatures, i.e. ECDSA and ML-DSA, successfully to state that a composite ML-DSA + ECC signature is valid.
Packet Specifications
Signature Packet (Tag 2)
The composite ML-DSA + ECC schemes MUST be used only with v6 signatures, as defined in [I-D.ietf-openpgp-crypto-refresh].
The algorithm-specific v6 signature parameters for ML-DSA + ECDSA signatures consist of:
- A fixed-length octet string of the big-endian encoded ECDSA value R, whose length depends on the algorithm ID as specified in Table 7.
- A fixed-length octet string of the big-endian encoded ECDSA value S, whose length depends on the algorithm ID as specified in Table 7.
- A fixed-length octet string of the ML-DSA signature value, whose length depends on the algorithm ID as specified in Table 8.
Key Material Packets
The composite ML-DSA + ECC schemes MUST be used only with v6 keys, as defined in [I-D.ietf-openpgp-crypto-refresh].
The algorithm-specific public key for ML-DSA + ECDSA keys is this series of values:
- A fixed-length octet string representing the ECDSA public key in SEC1 format, as specified in section 2.1.1 and with length specified in Table 7.
- A fixed-length octet string containing the ML-DSA public key, whose length depends on the algorithm ID as specified in Table 8.
The algorithm-specific secret key for ML-DSA + ECDSA keys is this series of values:
- A fixed-length octet string representing the ECDSA secret key as a big-endian encoded integer, whose length depends on the algorithm used as specified in Table 7.
- A fixed-length octet string containing the ML-DSA secret key, whose length depends on the algorithm ID as specified in Table 8.
Security Considerations
TBD
IANA Considerations
IANA is requested to add the algorithm IDs defined in Table 10 to the existing registry OpenPGP Public Key Algorithms. The field specifications enclosed in brackets for the ML-KEM + ECDH composite algorithms denote fields that are only conditionally contained in the data structure.
[Note: Once the working group has agreed on the actual algorithm choice, the following table with the requested IANA updates will be filled out.]
IANA updates for registry 'OpenPGP Public Key Algorithms'
ID | Algorithm | Public Key Format | Secret Key Format | Signature Format | PKESK Format | Reference
TBD | ML-DSA-65+TBD | TBD octets TBD public key , TBD octets ML-DSA-65 public key (Table 8) | TBD octets TBD secret key , TBD octets ML-DSA-65 secret (Table 8) | TBD octets TBD signature , TBD octets ML-DSA-65 signature (Table 8) | N/A | Section 6.2
Changelog
Contributors
Stavros Kousidis
References
Normative References
[RFC7748]

Elliptic Curves for Security
A. Langley
M. Hamburg
S. Turner
January 2016
RFC 7748
DOI 10.17487/RFC7748
[RFC8032]

Edwards-Curve Digital Signature Algorithm (EdDSA)
S. Josefsson
I. Liusvaara
January 2017
RFC 8032
DOI 10.17487/RFC8032
[RFC3394]

Advanced Encryption Standard (AES) Key Wrap Algorithm
J. Schaad
R. Housley
September 2002
RFC 3394
DOI 10.17487/RFC3394
[RFC8126]

Guidelines for Writing an IANA Considerations Section in RFCs
M. Cotton
B. Leiba
T. Narten
June 2017
BCP 26
RFC 8126
DOI 10.17487/RFC8126
[I-D.ietf-openpgp-crypto-refresh]

OpenPGP
Paul Wouters
Aiven
Daniel Huigens
Proton AG
Justus Winter
Sequoia-PGP
Niibe Yutaka
FSIJ
4 January 2024
Internet-Draft draft-ietf-openpgp-crypto-refresh-13
[draft-ietf-openpgp-pqc-03]

Post-Quantum Cryptography in OpenPGP (draft-ietf-openpgp-pqc-03)
Stavros Kousidis
Johannes Roth
Falko Strenzke
Aron Wussler
2024
Informative References
[RFC5639]

Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation
M. Lochter
J. Merkle
March 2010
RFC 5639
DOI 10.17487/RFC5639
[NIST-PQC]

Post-Quantum Cryptography Standardization
Lily Chen
Dustin Moody
Yi-Kai Liu
December 2016
[NISTIR-8413]

Status Report on the Third Round of the NIST Post-Quantum Cryptography Standardization Process
Gorjan Alagic
Daniel Apon
David Cooper
Quynh Dang
Thinh Dang
John Kelsay
Jacob Lichtinger
Carl Miller
Dustin Moody
Rene Peralta
Ray Perlner
Angela Robinson
Daniel Smith-Tone
Yi-Kai Liu
September 2022
NIST IR 8413
[SP800-56C]

Recommendation for Key-Derivation Methods in Key-Establishment Schemes
Elaine Barker
Lily Chen
Richard Davis
August 2020
NIST Special Publication 800-56C Rev. 2
[SP800-185]

SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash, and ParallelHash
John Kelsey
Shu-jen Chang
Ray Perlner
December 2016
NIST Special Publication 800-185
[SP800-56A]

Recommendation for Pair-Wise Key-Establishment Schemes Using Discrete Logarithm Cryptography
Elaine Barker
Lily Chen
Allen Roginsky
Apostol Vassilev
Richard Davis
April 2018
NIST Special Publication 800-56A Rev. 3
[SP800-186]

Recommendations for Discrete Logarithm-Based Cryptography: Elliptic Curve Domain Parameters
Lily Chen
Dustin Moody
Andrew Regenscheid
Karen Randall
February 2023
NIST Special Publication 800-186
[SP800-186-5]

Digital Signature Standard (DSS)
Information Technology Laboratory, National Institute of Standards and Technology
February 2023
NIST Special Publication 800-186
[SEC1]

Standards for Efficient Cryptography 1 (SEC 1)
Standards for Efficient Cryptography Group
May 2009
[FIPS-203]

Module-Lattice-Based Key-Encapsulation Mechanism Standard
National Institute of Standards and Technology
August 2023
[FIPS-204]

Module-Lattice-Based Digital Signature Standard
National Institute of Standards and Technology
August 2023
[FIPS-205]

Stateless Hash-Based Digital Signature Standard
National Institute of Standards and Technology
August 2023
[TR-03111]

Technical Guideline BSI TR-03111 – Elliptic Curve Cryptography, Version 2.1
Federal Office for Information Security, Germany
June 2018
[draft-driscoll-pqt-hybrid-terminology]

Terminology for Post-Quantum Traditional Hybrid Schemes
Florence Driscoll
March 2023
[GHP18]

KEM Combiners
Federico Giacon
Felix Heuer
Bertram Poettering
2018
[BDPA08]

On the Indifferentiability of the Sponge Construction
Guido Bertoni
Joan Daemen
Michael Peters
Gilles van Assche
2008
[CS03]

Design and Analysis of Practical Public-Key Encryption Schemes Secure against Adaptive Chosen Ciphertext Attack
Ronald Cramer
Victor Shoup
2003
Test Vectors
TBD
Sample v6 PQC Subkey Artifacts
TBD ## V4 PQC Subkey Artifacts
TBD
Acknowledgments