Skip to content

Commit

Permalink
feat: Update to new kmac key combiner in kem
Browse files Browse the repository at this point in the history
  • Loading branch information
lubux committed Oct 11, 2024
1 parent 384a0e0 commit 86c81cb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
55 changes: 35 additions & 20 deletions openpgp/mlkem_ecdh/mlkem_ecdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
package mlkem_ecdh

import (
"bytes"
goerrors "errors"
"fmt"
"io"

"github.com/ProtonMail/go-crypto/internal/kmac"
"github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
"golang.org/x/crypto/sha3"

Expand All @@ -18,7 +20,7 @@ import (

const (
maxSessionKeyLength = 64
kdfContext = "OpenPGPCompositeKDFv1"
domainSeparator = "OpenPGPCompositeKDFv1"
)

type PublicKey struct {
Expand Down Expand Up @@ -122,7 +124,7 @@ func Decrypt(priv *PrivateKey, kEphemeral, ecEphemeral, ciphertext []byte) (msg
}

// buildKey implements the composite KDF as specified in
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-04.html#name-key-combiner
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-combiner
func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemKeyShare, mlkemEphemeral []byte, mlkemPublicKey kem.PublicKey) ([]byte, error) {
h := sha3.New256()

Expand All @@ -132,28 +134,41 @@ func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemK
_, _ = h.Write(eccPublicKey)
eccKeyShare := h.Sum(nil)

serializedMlkemKey, err := mlkemPublicKey.MarshalBinary()
serializedMlkemPublicKey, err := mlkemPublicKey.MarshalBinary()
if err != nil {
return nil, err
}

// eccData = eccKeyShare || eccCipherText
// mlkemData = mlkemKeyShare || mlkemCipherText
// encData = counter || eccData || mlkemData || fixedInfo
h.Reset()

// SHA3 never returns error
_, _ = h.Write([]byte{0x00, 0x00, 0x00, 0x01})
_, _ = h.Write(eccKeyShare)
_, _ = h.Write(eccEphemeral)
_, _ = h.Write(eccPublicKey)
_, _ = h.Write(mlkemKeyShare)
_, _ = h.Write(mlkemEphemeral)
_, _ = h.Write(serializedMlkemKey)
_, _ = h.Write([]byte{pub.AlgId})
_, _ = h.Write([]byte(kdfContext))

return h.Sum(nil), nil
// eccKeyShare - the ECDH key share encoded as an octet string
// eccEphemeral - the ECDH ciphertext encoded as an octet string
// eccPublicKey - The ECDH public key of the recipient as an octet string
// mlkemKeyShare - the ML-KEM key share encoded as an octet string
// mlkemEphemeral - the ML-KEM ciphertext encoded as an octet string
// mlkemPublicKey - The ML-KEM public key of the recipient as an octet string
// algId - the OpenPGP algorithm ID of the public-key encryption algorithm
// domainSeparator – the UTF-8 encoding of the string "OpenPGPCompositeKDFv1"

// KEK = KMAC256(
// eccKeyShare || mlkemKeyShare,
// eccEphemeral || mlkemEphemeral || ecdhPublicKey || mlkemPublicKey || algId,
// 256 (32 bytes),
// domainSeparator
// )

kMacKeyBuffer := bytes.NewBuffer(make([]byte, len(eccKeyShare)+len(mlkemKeyShare)))
_, _ = kMacKeyBuffer.Write(eccKeyShare)
_, _ = kMacKeyBuffer.Write(mlkemKeyShare)

k := kmac.NewKMAC256(kMacKeyBuffer.Bytes(), 32, []byte(domainSeparator))

// kmac hash never returns an error
_, _ = k.Write(eccEphemeral)
_, _ = k.Write(mlkemEphemeral)
_, _ = k.Write(eccPublicKey)
_, _ = k.Write(serializedMlkemPublicKey)
_, _ = k.Write([]byte{pub.AlgId})

return k.Sum(nil), nil
}

// Validate checks that the public key corresponds to the private key
Expand Down
5 changes: 3 additions & 2 deletions openpgp/v2/read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,8 @@ var pqcDraftVectors = map[string]struct {
armoredMessages []string
v6 bool
}{
"v4_Ed25519_ML-KEM-768+X25519": {
// TODO: Update with fresh test vectors
/*"v4_Ed25519_ML-KEM-768+X25519": {
v4Ed25519Mlkem768X25519PrivateTestVector,
v4Ed25519Mlkem768X25519PublicTestVector,
[]string{"b2e9b532d55bd6287ec79e17c62adc0ddd1edd73", "95bed3c63f295e7b980b6a2b93b3233faf28c9d2", "bd67d98388813e88bf3490f3e440cfbaffd6f357"},
Expand All @@ -1031,7 +1032,7 @@ var pqcDraftVectors = map[string]struct {
[]string{"52343242345254050219ceff286e9c8e479ec88757f95354388984a02d7d0b59", "263e34b69938e753dc67ca8ee37652795135e0e16e48887103c11d7307df40ed"},
[]string{v6Ed25519Mlkem768X25519PrivateMessageTestVector},
true,
},
},*/
}

func TestPqcDraftVectors(t *testing.T) {
Expand Down

0 comments on commit 86c81cb

Please sign in to comment.