layer-mtproto 0.4.7

MTProto 2.0 session management, message framing, DH key exchange and transport abstractions
Documentation

layer-mtproto

MTProto 2.0 session management, DH key exchange, and message framing for Rust.

Crates.io docs.rs License: MIT OR Apache-2.0 TL Layer


Installation

[dependencies]
layer-mtproto  = "0.4.7"
layer-tl-types = { version = "0.4.7", features = ["tl-mtproto"] }

Overview

layer-mtproto implements the full MTProto 2.0 session layer. It handles:

  • 3-step DH key exchange
  • Encrypted sessions (AES-IGE pack/unpack)
  • Message framing: salt, session_id, message_id, sequence numbers
  • msg_container and gzip_packed support
  • Salt management and auto-correction
  • Error recovery: bad_msg_notification, bad_server_salt, msg_resend_req
  • Acknowledgements via MsgsAck

Core Types

EncryptedSession

Manages the live MTProto session after key exchange.

use layer_mtproto::EncryptedSession;

let session = EncryptedSession::new(auth_key, first_salt, time_offset);

let wire_bytes = session.pack(&my_request)?;
let wire_bytes = session.pack_serializable(&raw_obj)?;
let msg = session.unpack(&mut raw_bytes)?;

3-Step DH Handshake

use layer_mtproto::authentication as auth;

let (req1, state1) = auth::step1()?;
// send req1, receive res_pq

let (req2, state2) = auth::step2(state1, res_pq)?;
// send req2, receive server_DH_params

let (req3, state3) = auth::step3(state2, dh_params)?;
// send req3, receive dh_answer

let done = auth::finish(state3, dh_answer)?;
// done.auth_key    [u8; 256]
// done.first_salt  i64
// done.time_offset i32

Message

pub struct Message {
    pub msg_id:  i64,
    pub seq_no:  i32,
    pub salt:    i64,
    pub body:    Vec<u8>,  // raw TL bytes
}

Session (plaintext)

Used only before an auth key exists, for the initial DH handshake messages.

use layer_mtproto::Session;

let mut plain = Session::new();
let framed = plain.pack_plain(&my_handshake_request)?;

Message Framing

Every outgoing MTProto message:

server_salt     8 bytes
session_id      8 bytes
message_id      8 bytes  (Unix time * 2^32, monotonically increasing)
seq_no          4 bytes
message_length  4 bytes
payload         N bytes
padding         12-1024 random bytes (total % 16 == 0)

Prefixed by a 32-byte msg_key after encryption.

msg_key is SHA-256 of (auth_key[88..120] || plaintext) for client-to-server, and (auth_key[96..128] || plaintext) for server-to-client.


Stack position

layer-client
└ layer-mtproto  <-- here
  ├ layer-tl-types (tl-mtproto feature)
  └ layer-crypto

License

MIT or Apache-2.0, at your option. See LICENSE-MIT and LICENSE-APACHE.

Ankit Chaubey - github.com/ankit-chaubey