Skip to content

Commit

Permalink
mkem: add corrections from review meeting
Browse files Browse the repository at this point in the history
  • Loading branch information
david415 committed Sep 30, 2024
1 parent 8bd78f0 commit b16316b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 13 deletions.
10 changes: 5 additions & 5 deletions kem/mkem/ciphertext.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ var (
type Ciphertext struct {
EphemeralPublicKey *PublicKey
DEKCiphertexts [][]byte
SecretCiphertext []byte
Envelope []byte
}

type IntermediaryCiphertext struct {
EphemeralPublicKey []byte
DEKCiphertexts [][]byte
SecretCiphertext []byte
Envelope []byte
}

func (i *IntermediaryCiphertext) Bytes() []byte {
Expand Down Expand Up @@ -53,8 +53,8 @@ func CiphertextFromBytes(scheme *Scheme, b []byte) (*Ciphertext, error) {
EphemeralPublicKey: &PublicKey{
publicKey: pubkey,
},
DEKCiphertexts: ic.DEKCiphertexts,
SecretCiphertext: ic.SecretCiphertext,
DEKCiphertexts: ic.DEKCiphertexts,
Envelope: ic.Envelope,
}
return c, nil
}
Expand All @@ -63,7 +63,7 @@ func (m *Ciphertext) Marshal() []byte {
ic := &IntermediaryCiphertext{
EphemeralPublicKey: m.EphemeralPublicKey.publicKey.Bytes(),
DEKCiphertexts: m.DEKCiphertexts,
SecretCiphertext: m.SecretCiphertext,
Envelope: m.Envelope,
}
return ic.Bytes()
}
Expand Down
41 changes: 35 additions & 6 deletions kem/mkem/mkem.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,34 @@ func (s *Scheme) decrypt(key []byte, ciphertext []byte) ([]byte, error) {
return aead.Open(nil, nonce, ciphertext, nil)
}

func (s *Scheme) Encapsulate(keys []*PublicKey, sharedSecret []byte) []byte {
func (s *Scheme) EnvelopeReply(privkey *PrivateKey, pubkey *PublicKey, plaintext []byte) []byte {
secret := hash.Sum256(s.nike.DeriveSecret(privkey.privateKey, pubkey.publicKey))
ciphertext := s.encrypt(secret[:], plaintext)
c := &Ciphertext{
EphemeralPublicKey: &PublicKey{
publicKey: pubkey.publicKey,
},
DEKCiphertexts: nil,
Envelope: ciphertext,
}
return c.Marshal()
}

func (s *Scheme) DecryptEnvelope(privkey *PrivateKey, pubkey *PublicKey, ciphertext []byte) ([]byte, error) {
c, err := CiphertextFromBytes(s, ciphertext)
if err != nil {
return nil, err
}

secret := hash.Sum256(s.nike.DeriveSecret(privkey.privateKey, pubkey.publicKey))
plaintext, err := s.decrypt(secret[:], c.Envelope)
if err != nil {
return nil, err
}
return plaintext, nil
}

func (s *Scheme) Encapsulate(keys []*PublicKey, payload []byte) (*PrivateKey, []byte) {
ephPub, ephPriv, err := s.nike.GenerateKeyPair()
if err != nil {
panic(err)
Expand All @@ -83,7 +110,7 @@ func (s *Scheme) Encapsulate(keys []*PublicKey, sharedSecret []byte) []byte {
if err != nil {
panic(err)
}
secretCiphertext := s.encrypt(msgKey, sharedSecret)
ciphertext := s.encrypt(msgKey, payload)

outCiphertexts := make([][]byte, len(secrets))
for i := 0; i < len(secrets); i++ {
Expand All @@ -94,10 +121,12 @@ func (s *Scheme) Encapsulate(keys []*PublicKey, sharedSecret []byte) []byte {
EphemeralPublicKey: &PublicKey{
publicKey: ephPub,
},
DEKCiphertexts: outCiphertexts,
SecretCiphertext: secretCiphertext,
DEKCiphertexts: outCiphertexts,
Envelope: ciphertext,
}
return c.Marshal()
return &PrivateKey{
privateKey: ephPriv,
}, c.Marshal()
}

func (s *Scheme) Decapsulate(privkey *PrivateKey, ciphertext []byte) ([]byte, error) {
Expand All @@ -112,7 +141,7 @@ func (s *Scheme) Decapsulate(privkey *PrivateKey, ciphertext []byte) ([]byte, er
if err != nil {
continue
}
return s.decrypt(msgKey, c.SecretCiphertext)
return s.decrypt(msgKey, c.Envelope)
}
return nil, errors.New("failed to trial decrypt")
}
Expand Down
37 changes: 35 additions & 2 deletions kem/mkem/mkem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestCiphertextMarshaling(t *testing.T) {
ic := &IntermediaryCiphertext{
EphemeralPublicKey: []byte("hello1"),
DEKCiphertexts: [][]byte{[]byte("yo123")},
SecretCiphertext: []byte("hello i am ciphertext"),
Envelope: []byte("hello i am ciphertext"),
}
blob1 := ic.Bytes()

Expand Down Expand Up @@ -48,7 +48,7 @@ func TestMKEMCorrectness(t *testing.T) {
_, err = rand.Reader.Read(secret)
require.NoError(t, err)

ciphertext := s.Encapsulate([]*PublicKey{replica1pub, replica2pub}, secret)
_, ciphertext := s.Encapsulate([]*PublicKey{replica1pub, replica2pub}, secret)

ciphertext2, err := CiphertextFromBytes(s, ciphertext)
require.NoError(t, err)
Expand All @@ -65,3 +65,36 @@ func TestMKEMCorrectness(t *testing.T) {

require.Equal(t, secret, secret2)
}

func TestMKEMProtocol(t *testing.T) {
nikeName := "x25519"
nike := schemes.ByName(nikeName)
s := FromNIKE(nike)

// replicas create their keys and publish them
replica1pub, replica1priv, err := s.GenerateKeyPair()
require.NoError(t, err)
replica2pub, _, err := s.GenerateKeyPair()
require.NoError(t, err)

// client to replica
request := make([]byte, 32)
_, err = rand.Reader.Read(request)
require.NoError(t, err)
privKey1, envelopeRaw := s.Encapsulate([]*PublicKey{replica1pub, replica2pub}, request)
envelope1, err := CiphertextFromBytes(s, envelopeRaw)
require.NoError(t, err)

// replica decrypts message from client
request1, err := s.Decapsulate(replica1priv, envelopeRaw)
require.NoError(t, err)
require.Equal(t, request1, request)
replyPayload := []byte("hello")
reply1 := s.EnvelopeReply(replica1priv, envelope1.EphemeralPublicKey, replyPayload)

// client decrypts reply from replica
plaintext, err := s.DecryptEnvelope(privKey1, replica1pub, reply1)
require.NoError(t, err)

require.Equal(t, replyPayload, plaintext)
}

0 comments on commit b16316b

Please sign in to comment.