Cryptographic operations in Telegram Web K never block the main thread. All heavyweight computation — AES encryption, SHA hashing, RSA, modular exponentiation, and SRP — runs inside a dedicated Web Worker. The rest of the application communicates with that worker throughDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/TelegramOrg/Telegram-web-k/llms.txt
Use this file to discover all available pages before exploring further.
CryptoMessagePort, a typed message-passing bridge that makes cross-thread calls feel like ordinary async function calls. This page explains what each algorithm is used for and how to call into the worker from application code.
Crypto worker architecture
Crypto worker architecture
The worker is defined in If the code calling
src/lib/crypto/crypto.worker.ts. On startup it registers handlers for every method listed in CryptoMethods and waits for invoke messages from the main thread or from other workers (such as the MTProto shared worker).CryptoMessagePort (src/lib/crypto/cryptoMessagePort.ts) is the client side of that bridge. A single default instance is exported and imported wherever crypto is needed:invokeCrypto is a thin wrapper around invokeCryptoNew, which serializes {method, args} and posts it to the worker via SuperMessagePort. For aes-encrypt and aes-decrypt, the port cycles through available worker ports in round-robin order to keep multiple encryption streams from starving each other:invokeCrypto is itself running inside the worker (i.e., the MTProto worker), the call is dispatched synchronously to the registered listener without any postMessage round-trip, which avoids unnecessary latency on the hot encryption path.Available crypto methods
Available crypto methods
Every method listed in
src/lib/crypto/crypto_methods.ts is callable via CryptoWorker.invokeCrypto(methodName, ...args). TypeScript infers argument and return types from the CryptoMethods map.| Method | Algorithm | Primary use |
|---|---|---|
sha1 | SHA-1 | Auth key hashing, message key derivation |
sha256 | SHA-256 | SRP password hashing, DH fingerprints |
pbkdf2 | PBKDF2-HMAC-SHA512 (100 000 iterations) | SRP password stretching |
aes-encrypt | AES-256-IGE | MTProto message encryption |
aes-decrypt | AES-256-IGE | MTProto message decryption |
aes-local-encrypt | AES-CTR (local data) | Passcode-protected storage |
aes-local-decrypt | AES-CTR (local data) | Passcode-protected storage |
rsa-encrypt | RSA-OAEP | DH params encryption during auth |
factorize | Brent-Pollard | PQ factorization during auth |
mod-pow | Big-integer modular exponentiation | DH key computation |
computeSRP | SRP-2048 | Two-factor authentication |
generate-dh | DH key generation | Voice/video calls |
compute-dh-key | DH shared secret | Voice/video calls |
aes-ctr-prepare / aes-ctr-process / aes-ctr-destroy | AES-CTR streaming | File encryption for calls |
gzipUncompress | Deflate | Decompressing gzip_packed responses |
get-emojis-fingerprint | SHA-256 + emoji map | Call key verification display |
AES-IGE message encryption
AES-IGE message encryption
MTProto v2 encrypts every message with AES-256 in IGE (Infinite Garble Extension) mode. IGE is not part of standard library APIs, so it is implemented from scratch in AES-CTR for local storage — When the passcode lock is active,
src/lib/crypto/utils/aesIGE.ts using the @cryptography/aes package for the underlying block cipher.The key and IV for each message are derived from the msg_key (a 128-bit value) and the auth key:msg_key= middle 128 bits ofSHA-256(auth_key[88..120] + plaintext)(for outgoing; different slice for incoming).aesKeyandaesIvare derived frommsg_keyandauth_keyvia two more SHA-256 calls (seeMessageKeyUtilsinsrc/lib/mtproto/messageKeyUtils.ts).
aes-local-encrypt and aes-local-decrypt use AES-CTR via the aesCtrUtils.ts helpers. CTR mode is streaming-friendly and allows partial decryption, which matters for large IndexedDB blobs.RSA key management
RSA key management
src/lib/mtproto/rsaKeysManager.ts holds the built-in RSA public keys used for the initial DH parameter exchange. Telegram rotates these keys, so the manager maps 64-bit fingerprints (SHA-1 of the key, last 8 bytes) to {modulus, exponent} objects.During authorization, the server sends a list of acceptable fingerprints. rsaKeysManager.select(fingerprints) picks the first fingerprint that matches a known key:src/lib/crypto/utils/rsa.ts, which uses the Web Crypto API (SubtleCrypto.importKey + SubtleCrypto.encrypt) with RSAES-PKCS1-v1_5. The result is passed to the crypto worker via the rsa-encrypt method.Diffie-Hellman key exchange
Diffie-Hellman key exchange
Two DH workflows exist: one for MTProto authorization and one for voice/video calls.MTProto authorization DH — Handled entirely inside
Authorizer. The client’s private value b is 2048 random bits. g_b = g^b mod p and the shared secret g_a^b mod p are both computed via CryptoWorker.invokeCrypto('mod-pow', ...).Call DH — src/lib/crypto/generateDh.ts generates the client’s a and g_a for an E2E-encrypted call:src/lib/crypto/computeDhKey.ts then computes the shared key from the remote party’s g_b. The 256-byte SHA-256 fingerprint of the key is shown to both callers as the call encryption indicator (emoji fingerprint).The DH prime used during MTProto authorization is validated in
authorizer.ts against the exact 2048-bit prime from the MTProto security guidelines. No other prime is accepted.SRP authentication for two-factor auth
SRP authentication for two-factor auth
src/lib/crypto/srp.ts implements SRP-2048 as required by auth.checkPassword for accounts with a cloud password.Password hashing chain (makePasswordHash):PBKDF2 key stretching
Run
PBKDF2-HMAC-SHA512 for 100 000 iterations with client_salt as the salt. This is the computationally expensive step; it runs inside the crypto worker.computeSRP performs the full SRP-2048 protocol: it computes the verifier v = g^x mod p, derives the session key K, and produces M1 — the proof of knowledge that the server checks. The output InputCheckPasswordSRP is passed directly to auth.checkPassword.big-integer npm package, since browsers do not expose modular exponentiation for arbitrary-precision integers through the Web Crypto API.Web Crypto API integration
Web Crypto API integration
src/lib/crypto/subtle.ts exports a reference to crypto.subtle that works in both window and worker contexts:- SHA-1 and SHA-256 —
subtle.digest('SHA-1', data)andsubtle.digest('SHA-256', data)underpin thesha1andsha256crypto methods. - PBKDF2 —
subtle.deriveBits({name: 'PBKDF2', ...}, key, 512)handles the SRP password stretching. - RSA-OAEP —
subtle.encrypt({name: 'RSA-OAEP'}, publicKey, data)encrypts DH parameters.
@cryptography/aes, @cryptography/sha1, and @cryptography/sha256 packages.