Message

Enum Message 

Source
pub enum Message {
    MessageV0(MessageV0),
}
Expand description

Top-level message format with versioning support.

§Message Versioning Strategy

The Message enum provides the primary versioning mechanism for the wire protocol. Each variant (e.g., MessageV0) represents a specific version of the message format with hard-wired cryptographic choices and content types.

§Version-Specific Design Philosophy

Unlike other protocols where features are negotiated dynamically, this protocol hard-wires cryptographic algorithms and content types into each message version. This design provides several benefits:

  • Security: No downgrade attacks through feature negotiation
  • Simplicity: Clear, unambiguous message format per version
  • Performance: No runtime algorithm selection overhead
  • Evolution: Clean migration path to new cryptographic standards

§Content Type Binding

Each message version has a fixed set of supported Content variants:

  • MessageV0 supports: Raw, ChaCha20Poly1305, Ed25519Encrypted
  • Future versions (e.g., MessageV1) may support different encryption schemes

This binding ensures that cryptographic choices are made explicitly during protocol design rather than being negotiated at runtime.

§Serialization and Wire Compatibility

Messages are serialized using postcard, which handles enum versioning through compact binary tags:

  • MessageV0(data) → serialized as [0, ...message data...]
  • MessageV1(data) → would serialize as [1, ...message data...] (future)

This allows clients to:

  1. Quickly identify the message version from the first byte
  2. Skip unknown message versions gracefully
  3. Maintain backwards compatibility with supported versions

§Evolution Path

When cryptographic standards change or new features are needed, the protocol evolves by adding new message versions:

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum Message {
    MessageV0(MessageV0),        // Legacy: ChaCha20-Poly1305, Ed25519
    MessageV1(MessageV1),        // Future: Post-quantum crypto, new content types
}

This ensures that:

  • Older clients continue working with MessageV0
  • Newer clients can handle both versions
  • Migration happens gradually and safely

§Example: Version-Specific Handling

use zoe_wire_protocol::{Message, MessageV0, Content};

fn handle_message(msg: Message) {
    match msg {
        Message::MessageV0(v0_msg) => {
            // Handle v0-specific features
            match v0_msg.content {
                Content::Raw(data) => { /* process raw data */ },
                Content::ChaCha20Poly1305(_) => { /* decrypt with ChaCha20 */ },
                Content::Ed25519SelfEncrypted(_) => { /* decrypt with Ed25519 */ },
            }
        }
        // Future: MessageV1 would be handled here with its own content types
    }
}

Variants§

§

MessageV0(MessageV0)

Message format version 0.

Supports the following cryptographic primitives:

This version is designed for high-performance messaging with modern cryptographic standards as of 2025.

Implementations§

Source§

impl Message

Source

pub fn verify_sender_signature( &self, message_bytes: &[u8], signature: &Signature, ) -> Result<(), VerifyError>

Source

pub fn new_v0( content: Content, sender: VerifyingKey, when: u64, kind: Kind, tags: Vec<Tag>, ) -> Self

Source

pub fn new_v0_raw( content: Vec<u8>, sender: VerifyingKey, when: u64, kind: Kind, tags: Vec<Tag>, ) -> Self

Source

pub fn new_v0_encrypted( content: ChaCha20Poly1305Content, sender: VerifyingKey, when: u64, kind: Kind, tags: Vec<Tag>, ) -> Self

Trait Implementations§

Source§

impl Clone for Message

Source§

fn clone(&self) -> Message

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 Message

Source§

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

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

impl<'de> Deserialize<'de> for Message

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 Message

Source§

fn eq(&self, other: &Message) -> 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 Message

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 Message

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,