๐ก layer-mtproto
MTProto 2.0 session management, DH key exchange, and message framing for Rust.
A complete, from-scratch implementation of Telegram's MTProto 2.0 session layer.
๐ฆ Installation
[]
= "0.1.2"
= { = "0.1.1", = ["tl-mtproto"] }
โจ What It Does
layer-mtproto implements the full MTProto 2.0 session layer โ the encrypted tunnel through which all Telegram API calls travel. This is the core protocol machinery that sits between your application code and the TCP socket.
It handles:
- ๐ค 3-step DH key exchange โ deriving a shared auth key from scratch
- ๐ Encrypted sessions โ packing/unpacking MTProto 2.0 messages with AES-IGE
- ๐ฆ Message framing โ salt, session_id, message_id, sequence numbers
- ๐๏ธ Containers & compression โ
msg_container, gzip-packed responses - ๐ง Salt management โ server salt tracking and auto-correction
- ๐ Session state โ time offset, sequence number, salt rotation
๐๏ธ Architecture
Application (layer-client)
โ
โผ
EncryptedSession โ encrypt/decrypt, pack/unpack
โ
โผ
Authentication โ 3-step DH handshake (step1 โ step2 โ step3 โ finish)
โ
โผ
layer-crypto โ AES-IGE, RSA, SHA, Diffie-Hellman
โ
โผ
TCP Socket
๐ Core Types
EncryptedSession
Manages the live MTProto session after a key has been established.
use EncryptedSession;
// Create from a completed DH handshake
let session = new;
// Pack a RemoteCall into encrypted wire bytes
let wire_bytes = session.pack;
// Or pack any Serializable (bypasses RemoteCall bound)
let wire_bytes = session.pack_serializable;
// Unpack an encrypted response
let msg = session.unpack?;
println!;
authentication โ DH Key Exchange
The full 3-step DH handshake as specified by MTProto:
use authentication as auth;
// Step 1 โ send req_pq_multi
let = step1?;
// ... send req1, receive res_pq ...
// Step 2 โ send req_DH_params
let = step2?;
// ... send req2, receive server_DH_params ...
// Step 3 โ send set_client_DH_params
let = step3?;
// ... send req3, receive dh_answer ...
// Finish โ extract auth key
let done = finish?;
// done.auth_key โ [u8; 256]
// done.first_salt โ i64
// done.time_offset โ i32
Message
A decoded MTProto message from the server.
Session
Plain (unencrypted) session for sending the initial DH handshake messages.
let mut plain = new;
let framed = plain.pack.to_plaintext_bytes;
๐ What's Inside
Encryption
- AES-IGE encryption/decryption using
layer-crypto msg_keyderivation from auth key and plaintext body- Server-side key derivation reversal for decryption
Framing
Every outgoing MTProto message includes:
server_salt (8 bytes) โ current server salt
session_id (8 bytes) โ random, stable per session
message_id (8 bytes) โ time-based, monotonically increasing
seq_no (4 bytes) โ content-related counter
message_length (4 bytes) โ payload length
payload (N bytes) โ serialized TL object
Plus 32 bytes of AES-IGE overhead.
Containers
msg_container (multiple messages in one frame) is supported both for packing and unpacking.
Salt Management
When the server responds with bad_server_salt, the session automatically records the corrected salt for future messages.
๐ Part of the layer stack
layer-client
โโโ layer-mtproto โ you are here
โโโ layer-tl-types
โโโ layer-crypto
๐ License
Licensed under either of, at your option:
- MIT License โ see LICENSE-MIT
- Apache License, Version 2.0 โ see LICENSE-APACHE
๐ค Author
Ankit Chaubey github.com/ankit-chaubey ยท ankitchaubey.in ยท ankitchaubey.dev@gmail.com