Layered Trust and Message Verification Model
Traditional secure messaging has binary trust: either you can decrypt messages or you can’t. Cryptid introduces layered trust that separates group participation from identity verification.
Layer 1: MLS Group Trust
Section titled “Layer 1: MLS Group Trust”- Provides message authenticity within the group.
- Enables immediate communication for new group members.
- Guarantees that messages are from legitimate group participants.
Layer 2: Direct Contact Trust
Section titled “Layer 2: Direct Contact Trust”- Provides enhanced identity verification.
- Enables high security communications when needed.
- Guarantees that messages are from the specific persion you verified out-of-band.
Trust Level Classification
Section titled “Trust Level Classification”enum MessageTrustLevel { /// Highest trust: Sender is a verified direct contact DirectContact, /// Medium trust: Sender is an authenticated MLS group member GroupMember, /// Error condition: Should not occur in normal operation Unknown,}
struct GroupMember { device_id: [u8; 32], /// From MLS group context public_key: Ed25519PublicKey, delivery_address: Vec<String>, /// Which member added them added_by: [u8; 32], added_at: u64, participation_status: ParticipationStatus,}
enum ParticipationStatus { /// Currently participating in the group Active, /// Added but hasn't joined the group yet PendingWelcome, /// No longer in the group Left,}
Message Verification Process
Section titled “Message Verification Process”All group members can communicate immediately. Verification affects trust indicators, not communication ability.
This is the algorithm that determines trust levels:
fn verify_and_decrypt_group_message( message: &SecureMessage, group: &MLSGroup, contacts: &ContactStore,) -> Result<(String, MessageTrustLevel)> { // 1. MLS decryption always works for group members let plaintext = group.decrypt(&message.mls_ciphertext)?;
// 2. Determine trust level (doesn't block decryption) let trust_level = if let Some(contact) = contacts.get(&message.sender_address) { // Known direct contact - verify with stored key if contact .expected_public_key .verify(&message.sender_signature, &message.mls_ciphertext) { MessageTrustLevel::DirectContact } else { return Err("Signature verification failed for contact."); } } else if let Some(member) = group.get_member_by_address(&message.sender_address) { // Verify member with MLS-provided public key if member .public_key .verify(&message.sender_signature, &message.mls_ciphertext) { MessageTrustLevel::GroupMember } else { return Err("Invalid signature from group member."); } } else { MessageTrustLevel::Unknown };
Ok((plaintext, trust_level))}
Key Points
Section titled “Key Points”- Assume there’s a group consisting of Alice, Bob, and Steve.
- Bob adds Carol to the group.
- Carol’s messages appear immediately to all group members.
- Trust indicators show verification status without blocking communication.
- Users can upgrade trust by scanning QR codes for direct contact verification.
- Group participation doesn’t require prior contact relationships.