Skip to content

Commit

Permalink
Add P-256 variant, drop HKDF as the combiner KDF, and add HPKE integr…
Browse files Browse the repository at this point in the history
…ation section
  • Loading branch information
chris-wood committed Nov 19, 2024
1 parent 8810bc0 commit c34c5af
Showing 1 changed file with 84 additions and 9 deletions.
93 changes: 84 additions & 9 deletions draft-ietf-lamps-pq-composite-kem.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -538,7 +539,6 @@ Key Generation Process:
4. Output the composite keys

return (pk, sk)

~~~
{: #alg-composite-keygen title="Composite KeyGen(pk, sk)"}

Expand All @@ -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.

Expand Down Expand Up @@ -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}}.


Expand All @@ -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 |
Expand Down Expand Up @@ -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

Expand All @@ -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 |
Expand Down

0 comments on commit c34c5af

Please sign in to comment.