These examples are designed to be read alongside MAIN.md.
Alice obtains an introduction token for Bob. Conceptually, it contains:
- Bob’s identity public keys (Ed25519 + Dilithium)
- Bob’s operational signing key (MTSK)
- Bob’s prekey encryption public keys (X25519 + Kyber768)
- A temporary DHT address and expiration
- Bob’s signature over the token contents
Illustrative structure:
ClientHello
protocol_version = 1
alice_ltik_pub = (ed25519_pub, dilithium_pub)
alice_mtsk_pub = ed25519_pub
alice_ephemeral_x25519 = x25519_pub
alice_kem_kyber_pub = kyber768_pub
kyber_ciphertext_to_bob = Kyber768.Encapsulate(bob_kyber768_pub).ciphertext
supported_ciphers = [ChaCha20-Poly1305, AES-256-GCM]
timestamp = unix_time_ns
signatures = Sign_ed25519(...) + Sign_dilithium(...)
Alice then encrypts and routes this first contact through the mesh.
Illustrative structure:
ServerHello
bob_ephemeral_x25519 = x25519_pub
kyber_ciphertext_to_alice = Kyber768.Encapsulate(alice_kem_kyber_pub).ciphertext
selected_cipher = ChaCha20-Poly1305
timestamp = unix_time_ns
signatures = Sign_ed25519(...) + Sign_dilithium(...)
Conceptually:
SS = HKDF( X25519_shared || Kyber_shared_ab || Kyber_shared_ba, context="LMP-v1-session-init" )
RK_0 = HKDF( SS, context="LMP-ratchet-root" )
Header
conversation_id
sender_device_id
message_number
prev_chain_length
timestamp
(optional) new ratchet public keys
nonce_prefix = HKDF(conversation_id || sender_device_id, "LMP-nonce-prefix")[0..4]
nonce = nonce_prefix || little_endian_u64(message_number)
ciphertext, tag = AEAD_Encrypt(
key = MK_send,
nonce = nonce,
plaintext = message,
associated_data = header
)
- The examples here are meant to reduce ambiguity while reading the main spec.
- If any example conflicts with
MAIN.md, treatMAIN.mdas authoritative.