pub enum Content {
Raw(Vec<u8>),
ChaCha20Poly1305(ChaCha20Poly1305Content),
Ed25519SelfEncrypted(Ed25519SelfEncryptedContent),
MlDsaSelfEncrypted(MlDsaSelfEncryptedContent),
PqxdhEncrypted(PqxdhEncryptedContent),
EphemeralEcdh(EphemeralEcdhContent),
Unknown {
discriminant: u32,
data: Vec<u8>,
},
}Expand description
Message content variants supporting both raw bytes and encrypted content.
§Content Type Design and Versioning Strategy
The Content enum represents the payload of a message and supports different encryption
schemes. Important: The choice of available content types and their cryptographic
implementations is hard-wired at the message version level (e.g., MessageV0).
This means that when a new message version is introduced (like MessageV1), it can
have different content variants or updated cryptographic schemes.
§Serialization with Postcard
This enum uses postcard for efficient binary serialization. Postcard distinguishes enum variants using a compact binary tag system:
Raw(Vec<u8>)→ serialized as[0, ...data bytes...]ChaCha20Poly1305(content)→ serialized as[1, ...encrypted content...]Ed25519Encrypted(content)→ serialized as[2, ...encrypted content...]
The first byte indicates which variant is being deserialized, making the format self-describing and forwards-compatible. For more details on postcard’s enum handling, see: https://docs.rs/postcard/latest/postcard/#enums
§Content Type Security Model
Each content type has different security properties and use cases:
§Raw - Unencrypted Content
- Used for public messages or when encryption is handled at a higher layer
- Suitable for metadata, public announcements, or already-encrypted data
- No confidentiality protection - readable by all message recipients
§ChaCha20Poly1305 - Context-Based Encryption
- Uses ChaCha20-Poly1305 AEAD (Authenticated Encryption with Associated Data)
- Encryption key derived from message context (channel tags, group keys, etc.)
- Provides both confidentiality and authenticity
- Minimal overhead, suitable for high-throughput scenarios
§Ed25519Encrypted - Identity-Based Encryption
- Uses Ed25519 keypairs (typically from mnemonic phrases) for key derivation
- Encrypts using ChaCha20-Poly1305 with keys derived from Ed25519 operations
- Suitable for direct peer-to-peer encrypted messaging
- Self-contained encryption that doesn’t require additional context
§Version Evolution
When message formats evolve (e.g., MessageV0 → MessageV1), the Content enum
can be updated with:
- New encryption schemes (e.g., post-quantum cryptography)
- Additional metadata or structure
- Different key derivation methods
- Backwards-incompatible changes to existing variants
The versioning at the Message level ensures that older clients can gracefully
handle unknown message versions while maintaining compatibility with supported versions.
§Example Usage
use zoe_wire_protocol::Content;
// Raw content for public data
let public_msg = Content::raw("Hello, world!".as_bytes().to_stdvec());
// Typed content (serialized with postcard)
#[derive(serde::Serialize)]
struct MyData { value: u32 }
let typed_content = Content::raw_typed(&MyData { value: 42 })?;Variants§
Raw(Vec<u8>)
Raw byte content without encryption.
Use this variant for:
- Public messages that don’t require encryption
- Content that is already encrypted at a higher layer
- Metadata or routing information
- Binary data that should be transmitted as-is
ChaCha20Poly1305(ChaCha20Poly1305Content)
ChaCha20-Poly1305 encrypted content with context-derived keys.
The encryption key is determined by message context such as:
- Channel tags and group membership
- Shared secrets established through key exchange
- Derived keys from parent encryption contexts
This variant provides minimal serialization overhead while maintaining strong AEAD security properties.
Ed25519SelfEncrypted(Ed25519SelfEncryptedContent)
Ed25519-derived ChaCha20-Poly1305 self-encrypted content.
Uses sender’s Ed25519 keypair to derive ChaCha20-Poly1305 encryption keys. Only the sender can decrypt this content (encrypt-to-self pattern). Suitable for:
- Personal data storage
- Self-encrypted notes and backups
- Content where only the author should have access
MlDsaSelfEncrypted(MlDsaSelfEncryptedContent)
ML-DSA-derived ChaCha20-Poly1305 self-encrypted content.
Uses sender’s ML-DSA keypair to derive ChaCha20-Poly1305 encryption keys. Only the sender can decrypt this content (encrypt-to-self pattern). Post-quantum secure version of Ed25519SelfEncrypted. Suitable for:
- Personal data storage (post-quantum secure)
- Self-encrypted notes and backups
- Content where only the author should have access
PqxdhEncrypted(PqxdhEncryptedContent)
PQXDH encrypted content.
Uses the PQXDH (Post-Quantum Extended Diffie-Hellman) protocol for asynchronous secure communication establishment. Combines X25519 ECDH with ML-KEM for hybrid classical/post-quantum security. Suitable for:
- Asynchronous RPC initiation (tarpc-over-message)
- Secure inbox messaging
- Initial key agreement for ongoing sessions
- Post-quantum secure communication setup
EphemeralEcdh(EphemeralEcdhContent)
Ephemeral ECDH encrypted content.
Uses ephemeral X25519 key pairs for each message to encrypt for the recipient. Only the recipient can decrypt (proper public key encryption). Provides perfect forward secrecy. Suitable for:
- RPC calls over message infrastructure
- One-off encrypted messages
- Public key encryption scenarios
Unknown
Unknown content type.
This variant is used when the content type is unknown or not supported. It contains the discriminant and the raw data.
Implementations§
Source§impl Content
impl Content
Sourcepub fn raw_typed<T: Serialize>(data: &T) -> Result<Self, Error>
pub fn raw_typed<T: Serialize>(data: &T) -> Result<Self, Error>
Create raw content from serializable object
Sourcepub fn encrypted(content: ChaCha20Poly1305Content) -> Self
pub fn encrypted(content: ChaCha20Poly1305Content) -> Self
Create encrypted content
Sourcepub fn ed25519_self_encrypted(content: Ed25519SelfEncryptedContent) -> Self
pub fn ed25519_self_encrypted(content: Ed25519SelfEncryptedContent) -> Self
Create ed25519 self-encrypted content
Sourcepub fn ml_dsa_self_encrypted(content: MlDsaSelfEncryptedContent) -> Self
pub fn ml_dsa_self_encrypted(content: MlDsaSelfEncryptedContent) -> Self
Create ML-DSA self-encrypted content
Sourcepub fn ephemeral_ecdh(content: EphemeralEcdhContent) -> Self
pub fn ephemeral_ecdh(content: EphemeralEcdhContent) -> Self
Create ephemeral ECDH encrypted content
Sourcepub fn pqxdh_encrypted(content: PqxdhEncryptedContent) -> Self
pub fn pqxdh_encrypted(content: PqxdhEncryptedContent) -> Self
Create PQXDH encrypted content
Sourcepub fn pqxdh_initial(message: PqxdhInitialMessage) -> Self
pub fn pqxdh_initial(message: PqxdhInitialMessage) -> Self
Create PQXDH initial message content
Sourcepub fn pqxdh_session(message: PqxdhSessionMessage) -> Self
pub fn pqxdh_session(message: PqxdhSessionMessage) -> Self
Create PQXDH session message content
Sourcepub fn as_encrypted(&self) -> Option<&ChaCha20Poly1305Content>
pub fn as_encrypted(&self) -> Option<&ChaCha20Poly1305Content>
Get the encrypted content if this is encrypted
Sourcepub fn as_ed25519_self_encrypted(&self) -> Option<&Ed25519SelfEncryptedContent>
pub fn as_ed25519_self_encrypted(&self) -> Option<&Ed25519SelfEncryptedContent>
Get the ed25519 self-encrypted content if this is ed25519 self-encrypted
Sourcepub fn as_ml_dsa_self_encrypted(&self) -> Option<&MlDsaSelfEncryptedContent>
pub fn as_ml_dsa_self_encrypted(&self) -> Option<&MlDsaSelfEncryptedContent>
Get the ML-DSA self-encrypted content if this is ML-DSA self-encrypted
Sourcepub fn as_ephemeral_ecdh(&self) -> Option<&EphemeralEcdhContent>
pub fn as_ephemeral_ecdh(&self) -> Option<&EphemeralEcdhContent>
Get the ephemeral ECDH encrypted content if this is ephemeral ECDH encrypted
Sourcepub fn as_pqxdh_encrypted(&self) -> Option<&PqxdhEncryptedContent>
pub fn as_pqxdh_encrypted(&self) -> Option<&PqxdhEncryptedContent>
Get the PQXDH encrypted content if this is PQXDH encrypted
Sourcepub fn is_encrypted(&self) -> bool
pub fn is_encrypted(&self) -> bool
Check if this content is encrypted