double ratchet first implementation
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
ycc
2026-03-04 22:30:22 +01:00
parent c0dcfe997c
commit f4fb42d72e
11 changed files with 375 additions and 14 deletions

View File

@@ -1,11 +1,14 @@
package client
import (
"crypto/rand"
"encoding/base64"
"os"
"strconv"
"testing"
"forge.redroom.link/yves/meowlib"
doubleratchet "github.com/status-im/doubleratchet"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/proto"
@@ -421,7 +424,7 @@ func TestProcessOutboundInbound_RoundTrip(t *testing.T) {
assert.NotEmpty(t, packed.Signature)
assert.Equal(t, bob.MyLookupKp.Public, packed.Destination)
received, err := bob.ProcessInboundUserMessage(packed.Payload, packed.Signature)
received, err := bob.ProcessInboundUserMessage(packed)
assert.NoError(t, err)
assert.Equal(t, []byte("end to end test"), received.Data)
assert.Equal(t, alice.MyIdentity.Public, received.From)
@@ -436,7 +439,7 @@ func TestProcessOutboundInbound_EmptyMessage(t *testing.T) {
packed, err := alice.ProcessOutboundUserMessage(userMsg)
assert.NoError(t, err)
received, err := bob.ProcessInboundUserMessage(packed.Payload, packed.Signature)
received, err := bob.ProcessInboundUserMessage(packed)
assert.NoError(t, err)
assert.Empty(t, received.Data)
}
@@ -452,6 +455,74 @@ func TestProcessOutboundUserMessage_InvalidKey(t *testing.T) {
assert.Error(t, err)
}
// ---------------------------------------------------------------------------
// DR-encrypted round-trip
// ---------------------------------------------------------------------------
func makeDRPeerPair(t *testing.T) (alice *Peer, bob *Peer) {
t.Helper()
alice, bob = makePeerPair(t)
// Generate DR keypair for alice (initiator)
drKp, err := doubleratchet.DefaultCrypto{}.GenerateDH()
if err != nil {
t.Fatal(err)
}
drRootKeyBytes := make([]byte, 32)
if _, err = rand.Read(drRootKeyBytes); err != nil {
t.Fatal(err)
}
drRootKey := base64.StdEncoding.EncodeToString(drRootKeyBytes)
alice.DrKpPrivate = base64.StdEncoding.EncodeToString(drKp.PrivateKey())
alice.DrKpPublic = base64.StdEncoding.EncodeToString(drKp.PublicKey())
alice.DrRootKey = drRootKey
alice.DrInitiator = true
bob.DrRootKey = drRootKey
bob.ContactDrPublicKey = alice.DrKpPublic
bob.DrInitiator = false
return alice, bob
}
func TestProcessOutboundInbound_DR_RoundTrip(t *testing.T) {
alice, bob := makeDRPeerPair(t)
userMsg, err := alice.BuildSimpleUserMessage([]byte("dr round trip test"))
assert.NoError(t, err)
packed, err := alice.ProcessOutboundUserMessage(userMsg)
assert.NoError(t, err)
assert.NotEmpty(t, packed.DrHeader, "DR header should be set")
received, err := bob.ProcessInboundUserMessage(packed)
assert.NoError(t, err)
assert.Equal(t, []byte("dr round trip test"), received.Data)
// Verify DR state was updated
assert.NotEmpty(t, alice.DrStateJson, "alice DR state should be persisted")
assert.NotEmpty(t, bob.DrStateJson, "bob DR state should be persisted")
}
func TestProcessOutboundInbound_DR_MultipleMessages(t *testing.T) {
alice, bob := makeDRPeerPair(t)
for i := 0; i < 5; i++ {
msg := []byte("message " + strconv.Itoa(i))
userMsg, err := alice.BuildSimpleUserMessage(msg)
assert.NoError(t, err)
packed, err := alice.ProcessOutboundUserMessage(userMsg)
assert.NoError(t, err)
assert.NotEmpty(t, packed.DrHeader)
received, err := bob.ProcessInboundUserMessage(packed)
assert.NoError(t, err)
assert.Equal(t, msg, received.Data)
}
}
// ---------------------------------------------------------------------------
// GetConversationRequest
// ---------------------------------------------------------------------------