METADATA PRIVACY

Metadata Minimization & The AAD Shield

How Convro-6-Protocol achieves best-in-class metadata privacy through sealed sender, fixed-size padding, and cryptographic binding that crushes the competition.

63 Bytes
AAD Binding
64 KB
Fixed Padding
Hidden
Sender Always
5min
Time Rounding

The Sharp Line: Content vs Metadata

C6P draws a sharp distinction between message content (fully E2E encrypted) and metadata (minimized by design).

While message content is protected by end-to-end encryption, metadata can reveal who talks to whom, when, and how often. C6P minimizes metadata exposure through multiple layers of protection.

What the Server Never Sees

Message Plaintext

Content is encrypted end-to-end with C6P session keys

Sender Identity

Sealed sender hides who sent the message (server only knows recipient)

Message Size

Fixed 64KB padding hides actual content length

Exact Timestamp

Timestamps rounded to nearest 5 minutes with random 0-5s jitter

Design Philosophy

C6P is designed with privacy by default, not privacy as an opt-in feature. Sealed sender with 64KB padding is STANDARD, not optional. This means every user benefits from best-in-class metadata privacy automatically.

The 63-Byte AAD Shield

Additional Authenticated Data (AAD) cryptographically binds all context to prevent tampering, splicing, and downgrade attacks.

What is AAD?

AAD (Additional Authenticated Data) is metadata that's cryptographically authenticated but not encrypted. It ensures that envelope fields cannot be tampered with or reused in different contexts.

Canonical 63-Byte Layout

AAD Construction (Exact 63 Bytes)
1. "C6P_AAD_V1" (10 bytes) ← Label
2. C6P_VERSION (1 byte = 0x01) ← Protocol version
3. message_type (1 byte) ← 0x01 dm, 0x02 group, etc.
4. stream_id (1 byte) ← 0x01 i2r, 0x02 r2i
5. suite_id (1 byte) ← 0x01 ChaCha20, 0x02 XChaCha20
6. aad_flags (1 byte = 0x00) ← Reserved for future
7. session_id (8 bytes) ← Session identifier
8. session_binding (32 bytes) ← Device pair SHA-256
9. BE64(counter) (8 bytes) ← Message counter
Total: 10 + 5 + 8 + 32 + 8 = 63 bytes

Security Properties

Downgrade Prevention

Protocol version and suite bound in AAD — tampering fails AEAD verification

Splicing Resistance

Session binding prevents messages from being moved between sessions

Replay Detection

Counter in AAD ensures duplicate messages are rejected even if AEAD verifies

Type Confusion

Message type bound — DM cannot be relabeled as group message

Normative Requirement

AAD MUST be exactly 63 bytes in C6P v1. Any other length is an implementation bug and MUST cause fail-closed rejection. This is non-negotiable for security.

Session Binding: Device Pair Lockdown

Every message is cryptographically bound to the exact device pair that established the session.

Why Session Binding?

Without session binding, a malicious server could splice messages between different sessions or device pairs. Session binding prevents this by creating a unique fingerprint for each device pair.

Computation

Session Binding Derivation
session_binding = SHA-256(
    "C6P_BIND_V1" ||
    session_id(8 bytes) ||
    initiator_device_id(16 bytes) ||
    responder_device_id(16 bytes)
)

// Output: 32 bytes (256 bits)
// Included in every AAD construction

Attack Scenarios Prevented

Cross-Session Splicing

Attack: Malicious server copies message from Session A to Session B

Defense: Different session_id means different session_binding → AEAD verification fails

Device Confusion

Attack: Server delivers message intended for Device A to Device B

Defense: Wrong device_id means wrong session_binding → AEAD verification fails

Man-in-the-Middle

Attack: Attacker intercepts and modifies AAD fields (suite, type, etc.)

Defense: Any AAD modification breaks AEAD authentication → rejection

Cryptographic Guarantee

Session binding is computed from canonical, locally trusted session state, not from attacker-controlled fields. The server cannot "fix" AAD to match a spliced message because it doesn't know the session keys.

Sealed Sender: Server Blindness

The server routes messages without knowing who sent them, protecting your social graph.

How Sealed Sender Works

Messages use a two-layer envelope structure: an outer envelope for server routing (recipient only) and an encrypted inner envelope containing sender identity.

Two-Layer Envelope Structure
┌─ Outer Envelope (Server Sees) ─────────────┐
│ to_user_id: UUID (routing only)
│ message_type: "sealed_sender"
│ created_at: 2026-01-20T12:30:00Z (rounded)
│ encrypted_envelope: 64KB (PADDED)
└────────────────────────────────────────────┘
┌─ Inner Envelope (Recipient Decrypts) ──┐
│ from_user_id: UUID (HIDDEN)
│ from_convro_number: "+99 123 456"
│ session_id: BYTEA
│ actual_message_type: "encrypted_message"
│ actual_created_at: (precise timestamp)
│ encrypted_blob: C6P payload
└────────────────────────────────────────┘

Fixed 64KB Padding

All sealed messages are padded to exactly 64KB (65,536 bytes). This hides the actual message length from the server.

64 KB
Fixed Size

Every message exactly same size — no length analysis

5 min
Time Rounding

Timestamps rounded to nearest 5 minutes

0-5s
Random Jitter

Delivery delay prevents correlation

Mode Server Sees Sender Message Size Timestamp
Standard Visible Variable (~2-10 KB) Precise
Sealed Hidden Fixed 64 KB ALWAYS Rounded (±5 min)

How C6P Crushes the Competition

Side-by-side comparison shows C6P provides best-in-class metadata privacy by default.

Metadata Type WhatsApp Signal
(Standard)
Signal
(Sealed)
Convro
(STANDARD)
Sender identity Visible Visible Hidden Hidden (ALWAYS)
Recipient identity Visible Visible Visible Visible
Message content Encrypted Encrypted Encrypted Encrypted (C6P)
Message size Variable Variable Padded Fixed 64KB (ALWAYS)
Exact timestamp Precise Precise Precise 5min rounded (ALWAYS)
Social graph Full exposure Full exposure Recipient-only Recipient-only (ALWAYS)
Timing jitter None None None 0-5s random delay
🏆 Convro = Best-in-class privacy by default!
WhatsApp

Poor privacy (server sees everything)

Signal standard

Good E2E, but server sees social graph

Signal sealed

Optional privacy enhancement

Convro: Sealed sender is STANDARD (not optional) + 64KB padding + timing jitter

Key Takeaways

63-byte AAD cryptographically binds all context to prevent tampering and splicing

Session binding locks messages to exact device pair, preventing cross-session attacks

Sealed sender ALWAYS — server never knows who sent a message (privacy by default)

64KB fixed padding hides message length from traffic analysis attacks

Timestamp rounding + jitter prevents precise timing correlation (5min ± 0-5s)

Best-in-class privacy — C6P crushes WhatsApp and equals/exceeds Signal's sealed mode