Zone Coordination Protocol (ZCP) — A residency-aware, post-quantum hybrid cryptography wire protocol for distributed IoT and edge computing.
Wire protocol types and codec for the Zone Coordination Protocol (ZCP).
clonic defines the binary envelope format that every ZCP message uses on the wire. It is deliberately minimal: types, constants, encode, decode. No crypto, no transport, no business logic.
Think of it like the http crate: it defines Request and Response but doesn't open sockets. Networking stacks build on top.
clonic is a modular Rust workspace with focused, single-responsibility crates:
| Crate | Purpose | Status |
|---|---|---|
| clonic-core | Wire protocol types and codec (42-byte envelope, zero-copy parsing) | ✅ Stable |
| clonic-crypto | Post-quantum hybrid (ML-KEM-768 + X25519) and classical (X25519) key encapsulation | 🔄 In progress |
| clonic-identity | Device identity, provisioning, and certificate chains | 🔄 In progress |
| clonic-transport | Transport abstraction layer (trait-based) | 🔄 In progress |
| clonic-transport-tcp | TCP/IP implementation with async/await | 🔄 In progress |
Every major communication protocol in use today — MQTT, CoAP, gRPC, AMQP, HTTP — is residency-blind. None carry any concept of where data is allowed to exist.
ZCP fixes this. Every envelope carries a 2-byte residency zone tag, cryptographically authenticated by the sender. The routing layer refuses to forward messages outside the declared zone. Data residency enforcement is architectural, not configuration.
Read the full Protocol Manifesto.
In neurology, a tonic-clonic seizure has two phases: sustained contraction (tonic) followed by rapid rhythmic pulses propagating across the nervous system (clonic).
tonic is the Rust ecosystem's gRPC framework — persistent channels, sustained connections, request-response between known endpoints. It holds the line open.
clonic is the other half: short, rhythmic coordination pulses rippling across a mesh of devices that may appear, disappear, and reconnect at any time. No persistent channel required. The fleet is the nervous system.
Offset Size Field Description
───────────────────────────────────────────────────────
0 1 version Protocol version (0x01)
1 1 msg_type Message type discriminant
2 1 crypto_suite Crypto profile (0x01=PQ, 0x02=classical)
3 1 flags Bit flags (compressed, fragmented)
4 32 sender_device_id Ed25519 public key
36 2 residency_tag ISO 3166-1 numeric, big-endian
38 4 payload_length Payload byte count, big-endian
──────────────────────────────────────────────────────── 42 bytes
42 var payload Encrypted (opaque to this crate)
42+N 16 mac AES-256-GCM authentication tag
All multi-byte integers are big-endian (network byte order). Total fixed overhead: 58 bytes.
use clonic::{EnvelopeRef, MsgType};
fn handle_frame(buf: &[u8]) {
let env = EnvelopeRef::parse(buf).expect("valid envelope");
match env.msg_type() {
Some(MsgType::SyncCrdt) => {
let payload = env.payload();
let residency = env.residency_tag();
// hand off to sync engine...
}
_ => { /* forward or drop */ }
}
}use clonic::{Envelope, MsgType, CryptoSuite, ResidencyTag};
let envelope = Envelope::new(
MsgType::TaskRoute,
CryptoSuite::PqHybrid,
device_public_key, // [u8; 32]
ResidencyTag::INDONESIA,
encrypted_payload, // Vec<u8>
gcm_tag, // [u8; 16]
);
let wire_bytes = envelope.to_bytes();use clonic::decode::peek_frame_length;
use clonic::envelope::HEADER_SIZE;
// Step 1: read exactly 42 bytes from the wire
let header_buf = read_exact(stream, HEADER_SIZE);
// Step 2: learn total frame size
let (_, total) = peek_frame_length(&header_buf).unwrap();
// Step 3: read remaining bytes
let mut frame = vec![0u8; total];
frame[..HEADER_SIZE].copy_from_slice(&header_buf);
read_exact(stream, &mut frame[HEADER_SIZE..]);
// Step 4: parse
let env = clonic::EnvelopeRef::parse(&frame).unwrap();| Feature | Default | Effect |
|---|---|---|
alloc |
off | Vec-backed Envelope, encode_to_vec |
std |
off | std::error::Error impl (implies alloc) |
serde |
off | Serialize/Deserialize on all public types (implies alloc) |
- No crypto — consumers bring their own (PQ hybrid or classical). The crate defines where crypto fields sit in the envelope but performs no encryption.
- No transport — no TCP, BLE, LoRa, libp2p. Transport-agnostic by design.
- No CRDT payloads — the
payloadfield is opaque bytes. - No business logic — no task scheduling, no routing decisions.
- Residency-aware: Every envelope carries a 2-byte ISO 3166-1 residency zone tag, cryptographically authenticated.
- Post-quantum ready: Suite 0x01 uses ML-KEM-768 + X25519 hybrid KEM; Suite 0x02 uses classical X25519.
- no_std first: Core protocol works on bare-metal; optional
allocandstdfeatures for richer environments. - Zero-copy parsing:
EnvelopeRefborrows from the wire buffer; no allocations required. - Modular: Each crate has a single responsibility; compose as needed.
-
Suite 0x01 — PQ Hybrid (ML-KEM-768 + X25519, ML-DSA-65 + Ed25519)
- Use when you need post-quantum resistance today or must hedge against future adversaries.
- Preferred for servers, gateways, and modern hardware that can afford larger keys/ciphertexts.
- Slightly larger envelope footprint due to hybrid KEM and dual signature.
-
Suite 0x02 — Classical (X25519, Ed25519)
- Use on constrained devices where size and CPU are tighter and PQ risk tolerance is acceptable for the deployment horizon.
- Smaller keys/ciphertexts and faster operations; minimal envelope overhead.
-
General guidance
- Keep suite consistent per deployment domain to simplify validation and tooling.
- Bind a clear domain separation context for HKDF (already enforced in KEM/sign code).
- Budget for payload + MAC size when setting transport frame limits (PQ suite is larger).
- MANIFESTO.md — Complete ZCP protocol specification
- ROADMAP.md — Development phases and milestones
- clonic-core README — Wire protocol details and API reference
MIT — maximum adoption, zero friction.
An open protocol by PT Teknorakit Inovasi Indonesia.