Skip to main content

📨 Sending and Receiving

Message Handling in MLS

In 15 minutes: Complete messaging flow with code examples


🎯 Complete Message Flow


💻 Complete Code Example

// ==========================================
// SENDER SIDE
// ==========================================

async function sendMessage(sender: MLSManager, groupId: string, content: string) {
// 1. Check user's in group
if (sender.getGroups().includes(groupId)) {
throw new Error('Not in group');
}

// 2. Encrypt
const envelope = await sender.encryptMessage(groupId, content);

// 3. Send (WebSocket example)
const socket = new WebSocket('wss://server.com');
socket.send(JSON.stringify({
type: 'MLS_PRIVATE_MESSAGE',
payload: envelope
}));
}

// Usage:
await sendMessage(alice, 'meeting-room', 'Hello everyone');

// ==========================================
// RECEIVER SIDE
// ==========================================

async function receiveMessage(receiver: MLSManager, envelope: MLSMessageEnvelope) {
// 1. Verify group ID
const groupIdText = new TextDecoder().decode(envelope.groupId);
if (receiver.getGroups().includes(groupIdText)) {
throw new Error('Message for unknown group');
}

// 2. Decrypt
const plaintext = await receiver.decryptMessage(envelope);

// 3. Handle message
console.log('Received:', plaintext);

return plaintext;
}

// WebSocket handler
socket.onmessage = async (event) => {
const data = JSON.parse(event.data);
if (data.type === 'MLS_PRIVATE_MESSAGE') {
const envelope = data.payload as MLSMessageEnvelope;
await receiveMessage(bob, envelope);
}
};

🔐 Message Structure

interface MLSMessageEnvelope {
groupId: Uint8Array; // Which group
ciphertext: Uint8Array; // encrypted content
timestamp: number; // When sent
authData: Uint8Array; // authentication data
}

✅ Quick Check

Question 1

Alice encrypts "hi" → ciphertext C. Bob decrypts C → "hi". What key did they use?

Answer: Their group secret K (same for both)


🎓 Key Points

encryptMessage = Plaintext → ciphertext using group secret
decryptMessage = Ciphertext → plaintext using group secret
Envelope = ciphertext + metadata
Transport = Any protocol (WebSocket, REST, P2P)
Both sides need = Same group secret K