Skip to content

Commit 376764e

Browse files
committed
feat: ML-KEM change key combiner to latest draft
See: openpgp-pqc/draft-openpgp-pqc#161
1 parent 970040c commit 376764e

File tree

3 files changed

+696
-175
lines changed

3 files changed

+696
-175
lines changed

openpgp/mlkem_ecdh/mlkem_ecdh.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
const (
2020
maxSessionKeyLength = 64
2121
MlKemSeedLen = 64
22+
kdfContext = "OpenPGPCompositeKDFv1"
2223
)
2324

2425
type PublicKey struct {
@@ -138,16 +139,11 @@ func Decrypt(priv *PrivateKey, kEphemeral, ecEphemeral, ciphertext []byte) (msg
138139
return keywrap.Unwrap(kek, ciphertext)
139140
}
140141

141-
// buildKey implements the composite KDF 2a from
142-
// https://mailarchive.ietf.org/arch/msg/openpgp/NMTCy707LICtxIhP3Xt1U5C8MF0/
142+
// buildKey implements the composite KDF from
143+
// https://github.com/openpgp-pqc/draft-openpgp-pqc/pull/161
143144
func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemKeyShare, mlkemEphemeral []byte, mlkemPublicKey kem.PublicKey) ([]byte, error) {
144-
h := sha3.New256()
145-
146-
// SHA3 never returns error
147-
_, _ = h.Write(eccSecretPoint)
148-
_, _ = h.Write(eccEphemeral)
149-
_, _ = h.Write(eccPublicKey)
150-
eccKeyShare := h.Sum(nil)
145+
/// Set the output `ecdhKeyShare` to `eccSecretPoint`
146+
eccKeyShare := eccSecretPoint
151147

152148
serializedMlkemPublicKey, err := mlkemPublicKey.MarshalBinary()
153149
if err != nil {
@@ -162,16 +158,17 @@ func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemK
162158
// eccEphemeral - the ECDH ciphertext encoded as an octet string
163159
// eccPublicKey - The ECDH public key of the recipient as an octet string
164160

165-
// 2a. SHA3-256(mlkemKeyShare || eccKeyShare || eccEphemeral || eccPublicKey || Domain)
166-
// where Domain is "Domain" for LAMPS, and "mlkemEphemeral || mlkemPublicKey || algId" for OpenPGP
167-
h.Reset()
161+
// SHA3-256(mlkemKeyShare || eccKeyShare || eccEphemeral || eccPublicKey ||
162+
// mlkemEphemeral || mlkemPublicKey || algId || "OpenPGPCompositeKDFv1")
163+
h := sha3.New256()
168164
_, _ = h.Write(mlkemKeyShare)
169165
_, _ = h.Write(eccKeyShare)
170166
_, _ = h.Write(eccEphemeral)
171167
_, _ = h.Write(eccPublicKey)
172168
_, _ = h.Write(mlkemEphemeral)
173169
_, _ = h.Write(serializedMlkemPublicKey)
174170
_, _ = h.Write([]byte{pub.AlgId})
171+
_, _ = h.Write([]byte(kdfContext))
175172
return h.Sum(nil), nil
176173
}
177174

openpgp/read_test.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -967,13 +967,12 @@ var pqcDraftVectors = map[string]struct {
967967
fingerprints []string
968968
armoredMessages []string
969969
}{
970-
// Update with fresh vectors
971-
//"v6_Ed25519_ML-KEM-768+X25519": {
972-
// v6Ed25519Mlkem768X25519PrivateTestVector,
973-
// v6Ed25519Mlkem768X25519PublicTestVector,
974-
// []string{"52343242345254050219ceff286e9c8e479ec88757f95354388984a02d7d0b59", "263e34b69938e753dc67ca8ee37652795135e0e16e48887103c11d7307df40ed"},
975-
// []string{v6Ed25519Mlkem768X25519PrivateMessageTestVector},
976-
//},
970+
"v6_Ed25519_ML-KEM-768+X25519": {
971+
v6Ed25519Mlkem768X25519PrivateTestVector,
972+
v6Ed25519Mlkem768X25519PublicTestVector,
973+
[]string{"bf262b24177002ac8ae5dc6da47c056d22ab9906d47d07952b75c358021901ca", "48b94bce2f9771788f5feb74122d599989c400cc0f49108bc98e0ea7945e4838"},
974+
[]string{v6Ed25519Mlkem768X25519PrivateMessageTestVector},
975+
},
977976
}
978977

979978
func TestPqcDraftVectors(t *testing.T) {
@@ -1040,7 +1039,7 @@ func TestPqcDraftVectors(t *testing.T) {
10401039
return
10411040
}
10421041

1043-
if string(contents) != "Testing\n" {
1042+
if string(contents) != "Testing\r\n" {
10441043
t.Fatalf("Decrypted message is wrong: %s", contents)
10451044
}
10461045
})

0 commit comments

Comments
 (0)