diff --git a/draft-ietf-lamps-pq-composite-kem.md b/draft-ietf-lamps-pq-composite-kem.md index 7788d83..4591dd4 100644 --- a/draft-ietf-lamps-pq-composite-kem.md +++ b/draft-ietf-lamps-pq-composite-kem.md @@ -162,6 +162,7 @@ informative: RFC8446: RFC8551: RFC9180: + I-D.draft-connolly-cfrg-xwing-kem-06: I-D.draft-ietf-tls-hybrid-design-04: I-D.draft-ietf-pquip-pqt-hybrid-terminology-04: I-D.draft-ietf-pquip-hybrid-signature-spectrums-00: @@ -538,7 +539,6 @@ Key Generation Process: 4. Output the composite keys return (pk, sk) - ~~~ {: #alg-composite-keygen title="Composite KeyGen(pk, sk)"} @@ -549,7 +549,7 @@ In order to ensure fresh keys, the key generation functions MUST be executed for Note that in step 2 above, both component key generation processes are invoked, and no indication is given about which one failed. This SHOULD be done in a timing-invariant way to prevent side-channel attackers from learning which component algorithm failed. -## Composite-ML-KEM.Encap +## Composite-ML-KEM.Encap {#sect-composite-encaps} The `Encap(pk)` of a Composite ML-KEM algorithm is designed to behave exactly the same as `ML-KEM.Encaps(ek)` defined in Algorithm 20 in Section 7.2 of [FIPS.203]. Specifically, `Composite-ML-KEM.Encap(pk)` produces a 256-bit shared secret key that can be used directly with any symmetric-key cryptographic algorithm. In this way, Composite ML-KEM can be used as a direct drop-in replacement anywhere that ML-KEM is used. @@ -875,19 +875,18 @@ EDNOTE: these are prototyping OIDs to be replaced by IANA. | Composite ML-KEM Algorithm | OID | First Algorithm | Second Algorithm | KDF | |--------- | ----------------- | ---------- | ---------- | -------- | -| id-MLKEM768-RSA2048 | <CompKEM>.21 | MLKEM768 | RSA-OAEP 2048 | HKDF-SHA256/256 | -| id-MLKEM768-RSA3072 | <CompKEM>.22 | MLKEM768 | RSA-OAEP 3072 | HKDF-SHA256/256 | -| id-MLKEM768-RSA4096 | <CompKEM>.23 | MLKEM768 | RSA-OAEP 4096 | HKDF-SHA256/256 | +| id-MLKEM768-RSA2048 | <CompKEM>.21 | MLKEM768 | RSA-OAEP 2048 | SHA3-256 | +| id-MLKEM768-RSA3072 | <CompKEM>.22 | MLKEM768 | RSA-OAEP 3072 | SHA3-256 | +| id-MLKEM768-RSA4096 | <CompKEM>.23 | MLKEM768 | RSA-OAEP 4096 | SHA3-256 | | id-MLKEM768-X25519 | <CompKEM>.24 | MLKEM768 | X25519 | SHA3-256 | -| id-MLKEM768-ECDH-P384 | <CompKEM>.25 | MLKEM768 | ECDH-P384 | HKDF-SHA256/256 | -| id-MLKEM768-ECDH-brainpoolP256r1 | <CompKEM>.26 | MLKEM768 | ECDH-brainpoolp256r1 | HKDF-SHA256/256 | +| id-MLKEM768-ECDH-P256 | <CompKEM>.25 | MLKEM768 | ECDH-P256 | SHA3-256 | +| id-MLKEM768-ECDH-P384 | <CompKEM>.25 | MLKEM768 | ECDH-P384 | SHA3-256 | +| id-MLKEM768-ECDH-brainpoolP256r1 | <CompKEM>.26 | MLKEM768 | ECDH-brainpoolp256r1 | SHA3-256 | | id-MLKEM1024-ECDH-P384 | <CompKEM>.27 | MLKEM1024 | ECDH-P384 | SHA3-256 | | id-MLKEM1024-ECDH-brainpoolP384r1 | <CompKEM>.28 | MLKEM1024 | ECDH-brainpoolP384r1 | SHA3-256 | | id-MLKEM1024-X448 | <CompKEM>.29 | MLKEM1024 | X448 | SHA3-256 | {: #tab-kem-algs title="Composite ML-KEM key types"} -For the use of HKDF [RFC5869]: a salt is not provided; ie the default salt (all zeroes of length HashLen) will be used. The output length of HKDF is the same as the block size of the underlying hash function; in particular, `HKDF-SHA256/256` means HKDF-SHA256 with an output length `L` of 256 bits (32 octets). - Full specifications for the referenced algorithms can be found in {{appdx_components}}. @@ -901,6 +900,7 @@ The KEM combiner defined in section {{sec-kem-combiner}} requires a domain separ | id-MLKEM768-RSA3072 | 060B6086480186FA6B50050216 | | id-MLKEM768-RSA4096 | 060B6086480186FA6B50050217 | | id-MLKEM768-X25519 | 060B6086480186FA6B5005021A | +| id-MLKEM768-ECDH-P256 | 060B6086480186FA6B5005021E | | id-MLKEM768-ECDH-P384 | 060B6086480186FA6B50050218 | | id-MLKEM768-ECDH-brainpoolP256r1 | 060B6086480186FA6B50050219 | | id-MLKEM1024-ECDH-P384 | 060B6086480186FA6B5005021B | @@ -949,6 +949,80 @@ where: Note: The mask length, according to [RFC8017], is `k - hLen - 1`, where `k` is the size of the RSA modulus. Since the choice of hash function and the RSA key size is fixed for each composite algorithm, implementations could choose to pre-compute and hard-code the mask length. +# Use in HPKE + +This section describes how composite ML-KEM satisfies the HPKE KEM interface in {{RFC9180}}. The `SerializePublicKey` and `DeserializePublicKey` functions are implemented as specified in [TODO]. The `GenerateKeyPair` function is implemented by `KeyGen` in [TODO]. `DeriveKeyPair()` is implemented as follows: + +~~~ +DeriveKeyPair(ikm) -> (pk, sk) + +Explicit Inputs: + ikm A fixed-length seed of 32 bytes + +Implicit Input: + ML-KEM A placeholder for the specific ML-KEM algorithm and + parameter set to use, for example, could be "ML-KEM-65". + + Trad A placeholder for the specific traditional algorithm and + parameter set to use, for example "RSA-OAEP" or "X25519". + +Output: + (pk, sk) The composite keypair. + +Key Generation Process: + + 1. Validate input keying material length + + if len(seed) != 32: + output "Invalid seed error" + + 2. Expand the input keying material + + expanded = SHAKE256(message=ikm, outlen=Nsk) + + 3. Derive component keys + + (mlkemPK, mlkemSK) = ML-KEM.KeyGen_internal(expanded[0:32], expanded[32:64]) + (tradPK, tradSK) = Trad.KeyGen(expanded[64:]) + + 4. Check for component key gen failure + if NOT (mlkemPK, mlkemSK) or NOT (tradPK, tradSK): + output "Key derivation error" + + 5. Encode the component keys into composite structures + + pk = CompositeKEMPublicKey(mlkemPK, tradPK) + sk = CompositeKEMPrivateKey(mlkemSK, tradSK) + + 6. Output the composite keys + + return (pk, sk) +~~~ + +`Encap()` is `Encapsulate()` from {{sect-composite-encaps}}, where an ML-KEM encapsulation key check failure causes an HPKE `EncapError`. `Decap()` is `Decapsulate()` from {{sect-composite-decaps}}. + +Composite ML-KEM is not an authenticated KEM: it does not support `AuthEncap()` and `AuthDecap()` from {{RFC9180}}. + +Nsecret, Nenc, Npk, and Nsk are defined in the following registry updates for a subset of the composite ML-KEM instances in this document. These registry updates are made to the "HPKE KEM Identifiers" registry. An HPKE KEM Identifier codepoint has already been allocated for id-MLKEM768-X25519 in {{I-D.connolly-cfrg-xwing-kem}}. + +* id-MLKEM768-ECDH-P256 + * Value: 0xTODO (please) + * KEM: id-MLKEM768-ECDH-P256 + * Nsecret: 32 + * Nenc: 1153 + * Npk: 1249 + * Nsk: 96 + * Auth: no + * Reference: This document +* id-MLKEM768-ECDH-P384 + * Value: 0xTODO (please) + * KEM: id-MLKEM768-ECDH-P384 + * Nsecret: 32 + * Nenc: 1185 + * Npk: 1281 + * Nsk: 112 + * Auth: no + * Reference: This document # Use in CMS @@ -968,6 +1042,7 @@ A compliant implementation MUST support the following algorithm combinations for | id-MLKEM768-RSA3072 | id-alg-hkdf-with-sha256 | id-aes128-wrap | | id-MLKEM768-RSA4096 | id-alg-hkdf-with-sha256 | id-aes128-wrap | | id-MLKEM768-X25519 | id-kmac256 | id-aes128-wrap | +| id-MLKEM768-ECDH-P256 | id-kmac256 | id-aes128-wrap | | id-MLKEM768-ECDH-P384 | id-alg-hkdf-with-sha256 | id-aes256-wrap | | id-MLKEM768-ECDH-brainpoolP256r1 | id-alg-hkdf-with-sha256 | id-aes256-wrap | | id-MLKEM1024-ECDH-P384 | id-kmac256 | id-aes256-wrap |