Rust-powered, AES-NI accelerated cryptography for Telegram clients.
TgCryptoRust is a drop-in replacement for TgCrypto, implemented in Rust and packaged for Python through PyO3 and maturin. It provides the Telegram-focused AES-256 modes used by MTProto clients:
- AES-256-IGE for MTProto message encryption
- AES-256-CTR for CDN file encryption
- AES-256-CBC for Telegram Passport credentials
Important
This project is provided for educational and experimental purposes. The implementation follows public AES specifications and is tested against known vectors, but it has not received a formal third-party security audit. Do not treat it as a certified cryptographic module.
- Python 3.9 through 3.14
- Rust 1.83 or newer when building from source
Prebuilt wheels are intended for common desktop and server platforms. Rust is only required when a wheel is not available for your platform or when you are developing the project locally.
uv add TgCryptoRust
uv pip install TgCryptoRust
pip install TgCryptoRustExisting TgCrypto users can keep importing tgcrypto:
import tgcryptoNew code can import the branded module directly:
import tgcryptorsBoth modules expose the same API.
import os
import tgcrypto
data = os.urandom(1024)
key = os.urandom(32)
iv = os.urandom(32)
encrypted = tgcrypto.ige256_encrypt(data, key, iv)
decrypted = tgcrypto.ige256_decrypt(encrypted, key, iv)
assert decrypted == dataCTR accepts arbitrary-length data. The state argument is a one-byte offset
inside the current keystream block and is kept for TgCrypto compatibility.
import os
import tgcryptors
data = os.urandom(1000)
key = os.urandom(32)
iv = os.urandom(16)
state = b"\x00"
encrypted = tgcryptors.ctr256_encrypt(data, key, iv, state)
decrypted = tgcryptors.ctr256_decrypt(encrypted, key, iv, state)
assert decrypted == dataCBC input must be aligned to 16-byte AES blocks.
import os
import tgcrypto
data = os.urandom(1024)
key = os.urandom(32)
iv = os.urandom(16)
encrypted = tgcrypto.cbc256_encrypt(data, key, iv)
decrypted = tgcrypto.cbc256_decrypt(encrypted, key, iv)
assert decrypted == dataUse the streaming classes when processing one logical stream in chunks. The key schedule is expanded once and reused.
import os
import tgcryptors
key = os.urandom(32)
iv = os.urandom(16)
data = os.urandom(1024)
stream = tgcryptors.Ctr256(key, iv)
encrypted = stream.update(data[:300]) + stream.update(data[300:])IGE streaming is also available for block-aligned chunks:
import os
import tgcrypto
key = os.urandom(32)
iv = os.urandom(32)
data = os.urandom(1024)
stream = tgcrypto.Ige256(key, iv)
encrypted = stream.encrypt(data[:512]) + stream.encrypt(data[512:])TgCryptoRust keeps the TgCrypto-compatible function names, argument order, return types, and validation behavior for:
ige256_encrypt(data, key, iv)ige256_decrypt(data, key, iv)ctr256_encrypt(data, key, iv, state)ctr256_decrypt(data, key, iv, state)cbc256_encrypt(data, key, iv)cbc256_decrypt(data, key, iv)
The PyPI package name is TgCryptoRust. The native module is tgcryptors, and
the compatibility module is tgcrypto.
import tgcryptors
print(tgcryptors.__version__)
print(tgcryptors.runtime_info())uv sync --python 3.14
uv run maturin develop --release
.venv/bin/python -m unittest discover -s tests -vRun the Rust checks:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --releaseBuild a wheel:
uv build --wheeltgcryptors-corecontains the Rust AES primitive and Telegram block modes.tgcryptors-pythonexposes the PyO3 extension module.python/tgcrypto.pyre-exportstgcryptorsfor TgCrypto compatibility.tests/covers the public Python API and import compatibility.
On x86 and x86_64, AES-NI is detected at runtime when the crate is built with
the default aesni feature. Other targets use the software fallback. The
software fallback uses table lookups and is not guaranteed to be constant-time
on every CPU.
TgrCrypto is deprecated in favor of TgCryptoRust.
pip uninstall TgrCrypto
pip install TgCryptoRustExisting code that imports tgcrypto can remain unchanged.
LGPL-3.0-or-later. See COPYING and COPYING.lesser.