Skip to content

Latest commit

 

History

History
167 lines (119 loc) · 7.16 KB

File metadata and controls

167 lines (119 loc) · 7.16 KB

Fastcomcorp ZINA Protocol Guide

This document provides a rigorous technical definition of the Fastcomcorp ZINA protocols (spanning v1, v2, and v3), detailing the mathematical formulas, cipher specifications, and state machine logic. This guide is intended for cryptographic auditors and developers implementing compatible engines.


1. Cryptographic Primitives

Fastcomcorp ZINA utilizes a cipher suite designed for post-quantum resistance and high-assurance security, with capabilities varying by protocol version.

Primitive Algorithm Parameters / Specification
Asymmetric (Classical) X448 RFC 7748, 448-bit Curve, ~224-bit security
Asymmetric (PQ) ML-KEM-768 FIPS 203, Module-Lattice-Based KEM
Symmetric (AEAD) AES-256-GCM NIST SP 800-38D, 12-byte Nonce, 16-byte Tag
KDF HKDF-SHA-512 RFC 5869 with HMAC-SHA-512
Signatures (Classical) Ed448 (EdDSA) RFC 8032, Edwards-curve Digital Signature Algorithm
Signatures (PQ) Falcon-512 FIPS 204, Lattice-based, compact
Authentication Hash SHA-512 FIPS 180-4, used for manual/automated binding

2. Initial Key Agreement: Hybrid 5-DH + KEM

The session initiation protocol, known as Hybrid PQ-Handshake, combines five X448 Diffie-Hellman operations with an ML-KEM encapsulation to ensure both classical forward secrecy and quantum resistance.

2.1 Notation

  • $IK_A, EK_A$: Alice's Identity and Ephemeral key pairs.
  • $IK_B, SPK_B, OPK_B, KEM_PK_B$: Bob's public keys.
  • $X448(priv, pub)$: Curve448 scalar multiplication.
  • $HKDF(salt, ikm, info, L)$: HKDF-SHA-512 extraction and expansion.

2.2 The Handshake Formula

When Alice (initiator) contacts Bob (responder), she computes:

$$ \begin{align*} DH_1 &= X448(IK_A.priv, SPK_B.pub) \\ DH_2 &= X448(EK_A.priv, IK_B.pub) \\ DH_3 &= X448(EK_A.priv, SPK_B.pub) \\ DH_4 &= X448(EK_A.priv, OPK_B.pub) \quad (\text{if } OPK_B \text{ available}) \\ DH_5 &= X448(IK_A.priv, IK_B.pub) \quad (\text{Identity Binding}) \end{align*} $$

Alice then performs the PQ encapsulation: $$ (KEM_CT, KEM_SS) = ML\text{-}KEM.Encaps(KEM_PK_B) $$

The Master Secret ($SK$) is derived as: $$ SK = HKDF(None, DH_1 \parallel DH_2 \parallel DH_3 \parallel [DH_4] \parallel DH_5 \parallel KEM_SS, \text{"ZINA++X4DHKEM"}, 32) $$


3. The Hybrid Double Ratchet

The Double Ratchet advances the Root Key ($RK$) and Chain Keys ($CK$) using a hybrid of classical DH and periodic PQ updates.

3.1 Root Key Update (Asymmetric Step)

Every ratchet response ($i \to i+1$) updates the Root Key. In ZINA v2, this update is Hybrid:

$$ \begin{align*} ikm &= X448(Ratchet_{priv, local}, Ratchet_{pub, remote}) \parallel KEM_SS \\ info &= \text{"HybridRatchet"} \parallel session_context \\ RK_{i+1}, CK_{s,0} &= HKDF(RK_i, ikm, info, 64) \end{align*} $$

Note

The $KEM_SS$ is only included in steps where $i \equiv 0 \pmod{\text{KEM_RATCHET_INTERVAL}}$. On intermediate steps, $ikm$ consists only of the X448 output.

3.2 Chain Key Update (Symmetric Step)

For every message $j$ in a ratchet epoch, the chain key advances:

$$ \text{Advance: } CK_{s,j+1} = HKDF(CK_{s,j}, \text{salt=}1, \text{info=}\text{"NextChainKey"} \parallel j, 32) $$ $$ \text{Message Key: } MK, Nonce = HKDF(CK_{s,j}, \text{salt=}0, \text{info=}\text{"MessageKey"} \parallel j, 44) $$


4. Message Construction & AEAD

Messages are encrypted using AES-256-GCM with Associated Authenticated Data (AAD) that binds the ciphertext to the protocol state.

4.1 AAD Construction

$$ AAD = n \parallel PK_{ratchet448} \parallel session_context $$ Where:

  • $n$: Message sequence number (4-byte little-endian).
  • $PK_{ratchet448}$: The sender's current 56-byte X448 ratchet public key.
  • $session_context$: The 32-byte session-unique identifier (derived during handshake).

4.2 AEAD Logic

$$ Ciphertext = AES\text{-}256\text{-}GCM.Encrypt(MK, Nonce, Plaintext, AAD) $$


5. Ratchet Key Authentication (Ed448 & Falcon-512)

To prevent Active Middleperson attacks on the ratchet exchange, every new ratchet key is signed using the sender's identity key.

5.1 Classical Binding (Ed448)

In ZINA v3 "PQ-Hybrid", ratchet keys are signed via Ed448 EdDSA signatures: $$ Sig_{448} = EdDSA\text{-}448(IK_{priv}, PK_{ratchet448} \parallel n \parallel epoch) $$ This provides 114 bytes of non-malleable, high-security authentication for the asymmetric step.

5.2 Post-Quantum Binding (Falcon-512)

Future versions and high-security profiles utilize Falcon-512 for quantum-resistant signatures: $$ Sig_{PQ} = Falcon\text{-}512.Sign(IK_{PQ,priv}, PK_{ratchet448} \parallel n \parallel epoch) $$ The protocol supports both signatures simultaneously for maximum robustness.


6. Layer 2 Metadata Protection

Group metadata is protected by an inner encryption layer derived from the pairwise session.

6.1 Metadata Key Derivation

$$ K_{meta} = HKDF(None, session_context, \text{"MetadataProtection"}, 32) $$

6.2 ChangeSet Encryption

$$ grpChgSetEnc = AES\text{-}256\text{-}GCM.Encrypt(K_{meta}, Nonce, Protobuf(GroupChangeSet), \text{""}) $$

6.3 Transport-Layer Header Obfuscation (v3)

To hide the social graph from messaging relays, v3 "PQ-Hybrid" sessions encrypt the routing headers:

  1. Header Key Derivation: $K_{header} = HKDF(None, session_context, \text{"HeaderObfuscation"}, 32)$
  2. Obfuscation: $EncHeader = AES\text{-}256\text{-}GCM.Encrypt(K_{header}, Nonce, RoutingHeader, \text{"HeaderObfuscationV3"})$
  3. Redaction: Plaintext fields in the MessageEnvelope (sender name, device ID, message ID) are cleared after encryption.

7. Security Margin and Bounds

  • Forward Secrecy: Immediate upon deletion of $MK_j$; perfect at epoch boundary.
  • Quantum Resistance: $2^{128}$ symmetric equivalent for ML-KEM-768.
  • Metadata Silence: Transport relays see only encrypted blobs and random-looking hashes.
  • Memory Safety: Mandatory zeroization of keys and staged message keys (via Zeroize trait) prevents remanence.

8. File Encapsulation Protocol

ZINA secures bulk data (attachments) by decoupling the encryption of the file from the ratcheted message channel.

8.1 File Encryption

For a file $F$, a unique 256-bit key $K_{file}$ and 96-bit nonce $N_{file}$ are generated: $$ C_{file} = AES\text{-}256\text{-}GCM.Encrypt(K_{file}, N_{file}, F, \text{AAD=}\text{"ZinaAttachmentV1"}) $$

The resulting $C_{file}$ is uploaded to persistent storage.

8.2 Attachment Descriptor (The "Key Handover")

The metadata and keys are encapsulated in a JSON descriptor $D$:

{
  "url": "https://storage.zina.im/...",
  "key": "base64(K_file)",
  "nonce": "base64(N_file)",
  "hash": "sha256(C_file)",
  "name": "document.pdf",
  "size": 102400
}

This descriptor $D$ is then encrypted as a standard ZINA message using the current ratchet session: $$ Envelope(D) = ZINA.Encrypt(MK_j, Nonce_j, D, AAD_j) $$

8.3 Security Properties

  • Out-of-Band Integrity: The hash in the descriptor allows the receiver to verify $C_{file}$ before attempting decryption with $K_{file}$.
  • PQ-Resistant Handover: By sending $D$ through a v3 PQ-Hybrid session, the file keys inherit the same quantum resistance as the text conversation.