#packet #validation #enigma #format #canonical #attachment #serialization #sha-256 #secure-messaging #chunked-transfer

enigma-packet

Canonical message packet format + serialization for Enigma secure messaging

1 unstable release

new 0.1.0 Dec 15, 2025

#1898 in Encoding

MIT license

29KB
717 lines

enigma-packet

enigma-packet defines canonical, versioned packet formats for Enigma messages. It focuses on deterministic binary framing, strict validation, and clean error handling so higher layers can plug in crypto, transport, or storage policies without duplicating serialization logic. Attachments of any size are streamed through chunked transfers, so application layers can enforce their own policies without hitting artificial limits.

Quickstart

use enigma_packet::{
    encode_message,
    decode_message,
    validate_message,
    AttachmentChunkMeta,
    AttachmentKind,
    AttachmentMeta,
    Message,
    MessageMeta,
    MessageType,
};
use uuid::Uuid;

let text = Message {
    id: Uuid::new_v4(),
    sender: "alice".into(),
    receiver: "bob".into(),
    timestamp_ms: 1,
    msg_type: MessageType::Text,
    payload: b"hello".to_vec(),
    meta: MessageMeta::Basic {
        content_type: Some("text/plain".into()),
    },
};

validate_message(&text)?;
let packet = encode_message(&text)?;
let decoded = decode_message(&packet)?;
assert_eq!(decoded, text);

Attachments are advertised once, streamed through chunk packets, and finalized explicitly. The crate encodes the transfer metadata inside the packets while leaving network/storage policy to the caller.

let attachment_id = Uuid::new_v4();
let init = Message {
    msg_type: MessageType::AttachmentInit,
    payload: Vec::new(),
    meta: MessageMeta::AttachmentInit(AttachmentMeta {
        attachment_id,
        kind: AttachmentKind::File,
        filename: Some("video.mp4".into()),
        content_type: Some("video/mp4".into()),
        total_size: 12_345_678_901,
        chunk_size: 1024 * 512,
        chunk_count: 24_102,
        sha256: None,
        created_at_ms: Some(1),
    }),
    ..text.clone()
};

let chunk = Message {
    msg_type: MessageType::AttachmentChunk,
    payload: vec![0_u8; 1024 * 512],
    meta: MessageMeta::AttachmentChunk(AttachmentChunkMeta {
        attachment_id,
        index: 0,
        offset: 0,
        chunk_size: 1024 * 512,
        total_size: Some(12_345_678_901),
    }),
    ..text.clone()
};

Packet Format Overview

Each packet carries one Message encoded with fixed bincode settings and wrapped in a deterministic frame:

Field Size Notes
MAGIC 4 bytes ENP1 identifier
VERSION 1 byte currently 1
FLAGS 1 byte reserved for future extensions
RESERVED 2 bytes big-endian zero for now
BODY_LEN 4 bytes big-endian length of the encoded body
BODY variable bincode Message payload

Packets must be at least 12 bytes (header only) and at most 16 MiB. The body length is also capped at 16 MiB minus header to keep allocations safe.

Validation Summary

Messages are validated before encoding and after decoding:

  • sender and receiver must be non-empty UTF-8 strings up to 64 characters
  • timestamp must be greater than zero
  • text payloads must be valid UTF-8 but have no enforced length limit
  • attachment init packets require metadata describing total size, chunking plan, and filenames for file transfers
  • attachment chunk packets must reference the declared chunk sizing, include non-empty payloads, and obey deterministic offsets
  • attachment end/abort/ack packets must provide metadata and empty payloads

See docs/validation.md for the full rule set and docs/api.md for detailed function descriptions.

Dependencies

~0.8–1.5MB
~32K SLoC