CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-tgcrypto

Fast and portable cryptography extension library for Pyrogram implementing AES-256-IGE, AES-256-CTR, and AES-256-CBC encryption modes for Telegram's MTProto protocol

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

tgcrypto

A high-performance cryptography library written in C as a Python extension, specifically designed for Telegram's MTProto protocol. tgcrypto implements three essential AES-256 encryption algorithms required by Telegram: IGE mode for MTProto v2.0, CTR mode for CDN encrypted files, and CBC mode for encrypted passport credentials.

Package Information

  • Package Name: tgcrypto
  • Language: C/Python
  • Installation: pip install tgcrypto
  • Platform: Cross-platform (Windows, macOS, Linux)
  • Python Compatibility: 3.7+ (CPython, PyPy)

Core Imports

import tgcrypto

Basic Usage

import os
import tgcrypto

# Generate random key and data
key = os.urandom(32)  # 32-byte key for AES-256
data = os.urandom(64)  # Example data (must be multiple of 16 for IGE/CBC)

# IGE Mode - for MTProto v2.0
iv_ige = os.urandom(32)  # 32-byte IV for IGE
encrypted_ige = tgcrypto.ige256_encrypt(data, key, iv_ige)
decrypted_ige = tgcrypto.ige256_decrypt(encrypted_ige, key, iv_ige)

# CTR Mode - for CDN encrypted files  
iv_ctr = os.urandom(16)  # 16-byte IV for CTR
state = bytes([0])  # Counter state (0-15)
encrypted_ctr = tgcrypto.ctr256_encrypt(data, key, iv_ctr, state)
decrypted_ctr = tgcrypto.ctr256_decrypt(encrypted_ctr, key, iv_ctr, bytes([0]))

# CBC Mode - for encrypted passport credentials
iv_cbc = os.urandom(16)  # 16-byte IV for CBC
encrypted_cbc = tgcrypto.cbc256_encrypt(data, key, iv_cbc)
decrypted_cbc = tgcrypto.cbc256_decrypt(encrypted_cbc, key, iv_cbc)

print(data == decrypted_ige)  # True
print(data == decrypted_ctr)  # True  
print(data == decrypted_cbc)  # True

Architecture

tgcrypto is designed for maximum performance and portability:

  • C Implementation: Core algorithms implemented in optimized C code
  • Python Extension: Seamless integration with Python through the C API
  • Zero Dependencies: No external dependencies beyond Python standard library
  • Thread Safety: Releases GIL during encryption/decryption for concurrent operations
  • Memory Efficient: Direct buffer operations without unnecessary copying

Capabilities

IGE Mode (AES-256-IGE)

AES-256 in Infinite Garble Extension mode, used specifically for Telegram's MTProto v2.0 protocol. IGE provides enhanced security properties compared to standard CBC mode.

def ige256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
    """
    Encrypt data using AES-256-IGE mode.
    
    Parameters:
    - data: Input data to encrypt (must be multiple of 16 bytes)
    - key: 32-byte encryption key  
    - iv: 32-byte initialization vector
    
    Returns:
    bytes: Encrypted data
    
    Raises:
    ValueError: If data is empty, not multiple of 16 bytes, key not 32 bytes, or IV not 32 bytes
    TypeError: If arguments are not bytes-like objects
    """

def ige256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
    """
    Decrypt data using AES-256-IGE mode.
    
    Parameters:
    - data: Input data to decrypt (must be multiple of 16 bytes)
    - key: 32-byte decryption key
    - iv: 32-byte initialization vector
    
    Returns:
    bytes: Decrypted data
    
    Raises:
    ValueError: If data is empty, not multiple of 16 bytes, key not 32 bytes, or IV not 32 bytes
    TypeError: If arguments are not bytes-like objects
    """

Usage Example:

import os
import tgcrypto

# IGE requires data to be multiple of 16 bytes
data = os.urandom(1024)  # Already multiple of 16
key = os.urandom(32)
iv = os.urandom(32)

# For data that's not a multiple of 16, add padding
data_with_padding = data + bytes(-len(data) % 16)

encrypted = tgcrypto.ige256_encrypt(data_with_padding, key, iv)
decrypted = tgcrypto.ige256_decrypt(encrypted, key, iv)

print(data_with_padding == decrypted)  # True

CTR Mode (AES-256-CTR)

AES-256 in Counter mode, used for CDN encrypted file downloads in Telegram. CTR mode provides streaming encryption capabilities and doesn't require padding.

def ctr256_encrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes:
    """
    Encrypt data using AES-256-CTR mode.
    
    Parameters:
    - data: Input data to encrypt (any length)
    - key: 32-byte encryption key
    - iv: 16-byte initialization vector (modified during operation)
    - state: 1-byte counter state (value 0-15)
    
    Returns:
    bytes: Encrypted data
    
    Raises:
    ValueError: If data is empty, key not 32 bytes, IV not 16 bytes, state not 1 byte, or state value > 15
    TypeError: If arguments are not bytes-like objects
    """

def ctr256_decrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes:
    """
    Decrypt data using AES-256-CTR mode.
    
    Parameters:
    - data: Input data to decrypt (any length)
    - key: 32-byte decryption key
    - iv: 16-byte initialization vector (modified during operation)
    - state: 1-byte counter state (value 0-15)
    
    Returns:
    bytes: Decrypted data
    
    Raises:
    ValueError: If data is empty, key not 32 bytes, IV not 16 bytes, state not 1 byte, or state value > 15
    TypeError: If arguments are not bytes-like objects
    """

Single Chunk Usage:

import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024)  # 10 MB of data
key = os.urandom(32)

# Use bytearray for IV since it gets modified
enc_iv = bytearray(os.urandom(16))
dec_iv = enc_iv.copy()

encrypted = tgcrypto.ctr256_encrypt(data, key, enc_iv, bytes([0]))
decrypted = tgcrypto.ctr256_decrypt(encrypted, key, dec_iv, bytes([0]))

print(data == decrypted)  # True

Streaming Usage:

import os
from io import BytesIO
import tgcrypto

# Setup
data = BytesIO(os.urandom(10 * 1024 * 1024))
key = os.urandom(32)
enc_iv = bytearray(os.urandom(16))
dec_iv = enc_iv.copy()
enc_state = bytes([0])
dec_state = bytes([0])

encrypted_buffer = BytesIO()
decrypted_buffer = BytesIO()

# Encrypt in chunks
while True:
    chunk = data.read(1024)
    if not chunk:
        break
    encrypted_buffer.write(tgcrypto.ctr256_encrypt(chunk, key, enc_iv, enc_state))

# Decrypt in chunks
encrypted_buffer.seek(0)
while True:
    chunk = encrypted_buffer.read(1024)
    if not chunk:
        break
    decrypted_buffer.write(tgcrypto.ctr256_decrypt(chunk, key, dec_iv, dec_state))

print(data.getvalue() == decrypted_buffer.getvalue())  # True

CBC Mode (AES-256-CBC)

AES-256 in Cipher Block Chaining mode, used for encrypting passport credentials in Telegram. CBC provides strong security with proper IV handling.

def cbc256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
    """
    Encrypt data using AES-256-CBC mode.
    
    Parameters:
    - data: Input data to encrypt (must be multiple of 16 bytes)
    - key: 32-byte encryption key
    - iv: 16-byte initialization vector
    
    Returns:
    bytes: Encrypted data
    
    Raises:
    ValueError: If data is empty, not multiple of 16 bytes, key not 32 bytes, or IV not 16 bytes
    TypeError: If arguments are not bytes-like objects
    """

def cbc256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes:
    """
    Decrypt data using AES-256-CBC mode.
    
    Parameters:
    - data: Input data to decrypt (must be multiple of 16 bytes)
    - key: 32-byte decryption key
    - iv: 16-byte initialization vector
    
    Returns:
    bytes: Decrypted data
    
    Raises:
    ValueError: If data is empty, not multiple of 16 bytes, key not 32 bytes, or IV not 16 bytes  
    TypeError: If arguments are not bytes-like objects
    """

Usage Example:

import os
import tgcrypto

# CBC requires data to be multiple of 16 bytes
data = os.urandom(1024 + 7)  # Add 7 bytes to demonstrate padding
key = os.urandom(32)

# Separate IVs for encryption and decryption
enc_iv = bytearray(os.urandom(16))
dec_iv = enc_iv.copy()

# Pad data to multiple of 16 bytes
padded_data = data + bytes(-len(data) % 16)

encrypted = tgcrypto.cbc256_encrypt(padded_data, key, enc_iv)
decrypted = tgcrypto.cbc256_decrypt(encrypted, key, dec_iv)

print(padded_data == decrypted)  # True

Error Handling

All functions perform comprehensive input validation and raise specific exceptions:

Common Errors:

  • ValueError: Input validation failures (empty data, wrong sizes, invalid state values)
  • TypeError: Non-bytes arguments passed to functions

Validation Rules:

  • Data: Must not be empty; IGE/CBC require multiples of 16 bytes
  • Key: Must be exactly 32 bytes for all modes
  • IV: Must be 32 bytes for IGE, 16 bytes for CTR/CBC
  • State (CTR only): Must be 1 byte with value 0-15

Error Handling Example:

import tgcrypto

try:
    # This will raise ValueError: Data size must match a multiple of 16 bytes
    tgcrypto.ige256_encrypt(b"hello", b"x" * 32, b"y" * 32)
except ValueError as e:
    print(f"Validation error: {e}")

try:
    # This will raise ValueError: Key size must be exactly 32 bytes
    tgcrypto.ctr256_encrypt(b"hello", b"short", b"x" * 16, bytes([0]))
except ValueError as e:
    print(f"Key size error: {e}")

Performance Considerations

  • Thread Safety: All functions release the Python GIL during computation
  • Memory Efficiency: Direct buffer operations minimize memory allocation
  • Optimized C Code: Hand-optimized AES implementation for maximum performance
  • No Dependencies: Zero external dependencies reduce attack surface and improve portability

Telegram Integration

tgcrypto is specifically designed for Telegram's cryptographic requirements:

  • MTProto v2.0: Uses IGE mode for message encryption
  • CDN Files: Uses CTR mode for streaming file downloads
  • Passport: Uses CBC mode for credential encryption

The library ensures compatibility with Telegram's exact specifications while providing optimal performance for bot development and MTProto implementations.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/tgcrypto@1.2.x
Publish Source
CLI
Badge
tessl/pypi-tgcrypto badge