Skip to content

feat(telegram): make MTProto usage indistinguishable from Telegram Desktop#1774

Merged
ernado merged 1 commit into
mainfrom
feat/mtproto-tdesktop-mimic
Jun 13, 2026
Merged

feat(telegram): make MTProto usage indistinguishable from Telegram Desktop#1774
ernado merged 1 commit into
mainfrom
feat/mtproto-tdesktop-mimic

Conversation

@ernado

@ernado ernado commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

Aligns gotd's MTProto usage with Telegram Desktop so a connection is indistinguishable from tdesktop on the server side. Three independent areas, derived from the bundled tdesktop reference (connection_tcp.cpp, session_private.cpp, mtproto_serialized_request.cpp).

1. Transport: obfuscated abridged (opt-in)

tdesktop always wraps direct connections in Obfuscated2 and uses the abridged codec (0xefefefef); gotd's default sent plain, unobfuscated intermediate (0xeeeeeeee) — different from the first byte on the wire.

  • dcs.PlainOptions.Obfuscated: when set, all connections (not just TCPObfuscatedOnly DCs) are wrapped in Obfuscated2 using the configured codec's tag (carried inside the obfuscation header).

2. Encrypted-message padding jitter (global)

tdesktop's CountPaddingPrimesCount aligns to 16 bytes, guarantees ≥12, then adds a random number of extra 16-byte blocks. gotd used a fixed 16 + (16 - len%16), giving a deterministic encrypted length — itself a fingerprint.

  • crypto.countPadding now matches tdesktop. Applied globally since it's MTProto-2.0-compliant (12..1024 bytes, 16-byte aligned) and a strict privacy improvement, not impersonation. The grammers golden vector still passes (with zero rand the jitter is 0 and padding coincides).

3. initConnection identity — Windows tdesktop (opt-in)

  • telegram.DeviceTDesktopWindows() — device model, system/app version, lang_pack="tdesktop", tz_offset params.
  • telegram.TimezoneParams() — ports tdesktop's 900s-rounded, clamped tz offset.
  • telegram.TDesktopResolver() — the matching obfuscated abridged resolver, so the two layers can't be misconfigured.

Usage

client := telegram.NewClient(appID, appHash, telegram.Options{
    Device:   telegram.DeviceTDesktopWindows(),
    Resolver: telegram.TDesktopResolver(),
})

Example

examples/tdesktop-mimic — a login-free connectivity check (help.getNearestDC) using both presets, modeled on mtproxy-connect.

Tests

  • crypto/cipher_padding_test.go — padding bounds (12..1024), 16-byte alignment, jitter, low-4-bits-only.
  • telegram/dcs/plain_obfuscated_test.go — end-to-end: a real listener decodes the Obfuscated2 header via obfuscated2.Accept and confirms the abridged tag + DC id.
  • telegram/device_test.go — tz_offset value/rounding, device fields, resolver wiring.

All affected packages pass with -race; build clean, go vet clean, gofmt clean, no generated/schema files touched.

🤖 Generated with Claude Code

…sktop

Align gotd's MTProto usage with Telegram Desktop so a connection looks the
same from the server's perspective, across three independent areas.

Transport (opt-in): add PlainOptions.Obfuscated, wrapping every direct
connection in Obfuscated2 with the configured codec's tag, mirroring
tdesktop which always obfuscates direct connections. Combined with
transport.Abridged this matches tdesktop on the wire from the first byte,
instead of gotd's plain unobfuscated intermediate.

Encrypted-message padding: port tdesktop's CountPaddingPrimesCount so
encrypted messages get a random number of extra 16-byte padding blocks in
addition to block alignment. Removes the deterministic encrypted-message
length that would otherwise fingerprint the client. MTProto 2.0 compliant
(12..1024 bytes, 16-byte aligned); applied globally as a strict improvement.

initConnection identity (opt-in): add telegram.DeviceTDesktopWindows (device
model, system/app version, lang_pack "tdesktop", tz_offset params),
telegram.TimezoneParams, and telegram.TDesktopResolver to wire the transport
and identity presets together.

Add the tdesktop-mimic example demonstrating a login-free connectivity check
using both presets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.79661% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.20%. Comparing base (15e3439) to head (a3a1b18).

Files with missing lines Patch % Lines
telegram/dcs/plain.go 50.00% 9 Missing and 1 partial ⚠️
telegram/device.go 75.86% 4 Missing and 3 partials ⚠️
crypto/cipher_encrypt.go 80.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1774      +/-   ##
==========================================
+ Coverage   71.06%   71.20%   +0.14%     
==========================================
  Files         501      502       +1     
  Lines       23502    23547      +45     
==========================================
+ Hits        16702    16767      +65     
+ Misses       5574     5552      -22     
- Partials     1226     1228       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ernado ernado merged commit 429a09d into main Jun 13, 2026
14 checks passed
@ernado ernado deleted the feat/mtproto-tdesktop-mimic branch June 13, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant