Note
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.
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 implements the cryptographic algorithms Telegram requires, namely:
AES-256-IGE— used in MTProto v2.0.AES-256-CTR— used for CDN encrypted files.AES-256-CBC— used for encrypted passport credentials.
- Python 3.9 through 3.14
- Rust 1.83+ (only when building from source)
Prebuilt wheels are available for common desktop and server platforms. Rust is only required when a wheel is not available for your platform.
pip install TgCryptoRustOr with uv:
uv add TgCryptoRust
uv syncdef ige256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
def ige256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
def ctr256_encrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...
def ctr256_decrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...
def cbc256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
def cbc256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...Note: Data must be padded to a multiple of the block size (16 bytes).
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, 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 == dataNote: Data must be padded to a multiple of the block size (16 bytes).
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:])import tgcryptors
print(tgcryptors.__version__)
print(tgcryptors.runtime_info())Existing TgCrypto users can keep importing tgcrypto:
import tgcryptoNew code can import the branded module directly:
import tgcryptorsBoth modules expose the same API.
TgCryptoRust is a full drop-in replacement. All function names, argument orders, return types, and validation behavior match the original TgCrypto:
| Function | Arguments |
|---|---|
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) |
tgcryptors-core— Rust AES primitive and Telegram block modes (IGE, CTR, CBC).tgcryptors-python— PyO3 extension module exposing the native API.python/tgcrypto— Compatibility shim re-exportingtgcryptorsfor existing imports.tests/— Python unit tests covering the public API.
On x86 and x86_64, AES-NI is detected at runtime when the crate is built with
the default aesni feature. Other targets use a software fallback (T-table based,
not guaranteed 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.
# Set up environment
uv sync --python 3.14
# Build and install the native module
uv run maturin develop --release
# Run Python tests
.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 --wheelLGPLv3+ — GNU Lesser General Public License v3 or later.
© 2025-Present Joy. See COPYING and COPYING.lesser.