Content

Enum Content 

Source
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., MessageV0MessageV1), 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.

Fields

§discriminant: u32
§data: Vec<u8>

Implementations§

Source§

impl Content

Source

pub fn raw(data: Vec<u8>) -> Self

Create raw content from bytes

Source

pub fn raw_typed<T: Serialize>(data: &T) -> Result<Self, Error>

Create raw content from serializable object

Source

pub fn encrypted(content: ChaCha20Poly1305Content) -> Self

Create encrypted content

Source

pub fn ed25519_self_encrypted(content: Ed25519SelfEncryptedContent) -> Self

Create ed25519 self-encrypted content

Source

pub fn ml_dsa_self_encrypted(content: MlDsaSelfEncryptedContent) -> Self

Create ML-DSA self-encrypted content

Source

pub fn ephemeral_ecdh(content: EphemeralEcdhContent) -> Self

Create ephemeral ECDH encrypted content

Source

pub fn pqxdh_encrypted(content: PqxdhEncryptedContent) -> Self

Create PQXDH encrypted content

Source

pub fn pqxdh_initial(message: PqxdhInitialMessage) -> Self

Create PQXDH initial message content

Source

pub fn pqxdh_session(message: PqxdhSessionMessage) -> Self

Create PQXDH session message content

Source

pub fn as_raw(&self) -> Option<&Vec<u8>>

Get the raw bytes if this is raw content

Source

pub fn as_encrypted(&self) -> Option<&ChaCha20Poly1305Content>

Get the encrypted content if this is encrypted

Source

pub fn as_ed25519_self_encrypted(&self) -> Option<&Ed25519SelfEncryptedContent>

Get the ed25519 self-encrypted content if this is ed25519 self-encrypted

Source

pub fn as_ml_dsa_self_encrypted(&self) -> Option<&MlDsaSelfEncryptedContent>

Get the ML-DSA self-encrypted content if this is ML-DSA self-encrypted

Source

pub fn as_ephemeral_ecdh(&self) -> Option<&EphemeralEcdhContent>

Get the ephemeral ECDH encrypted content if this is ephemeral ECDH encrypted

Source

pub fn as_pqxdh_encrypted(&self) -> Option<&PqxdhEncryptedContent>

Get the PQXDH encrypted content if this is PQXDH encrypted

Source

pub fn is_encrypted(&self) -> bool

Check if this content is encrypted

Source

pub fn is_raw(&self) -> bool

Check if this content is raw

Trait Implementations§

Source§

impl Clone for Content

Source§

fn clone(&self) -> Content

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Content

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Content

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Content

Source§

fn eq(&self, other: &Content) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Content

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Content

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Classify for T

§

type Classified = T

§

fn classify(self) -> T

§

impl<T> Classify for T

§

type Classified = T

§

fn classify(self) -> T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Declassify for T

§

type Declassified = T

§

fn declassify(self) -> T

§

impl<T> Declassify for T

§

type Declassified = T

§

fn declassify(self) -> T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> DartSafe for T

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> TaskRetFutTrait for T
where T: Send,