Go to file
2019-06-14 19:56:39 +02:00
tests Fix TypeError tests for Python 3.4 2019-06-14 19:36:06 +02:00
tgcrypto Released the GIL 2019-06-13 19:53:56 +03:00
.appveyor.yml Add Appveyor CI: run tests and build wheels for Windows 2019-06-14 19:38:14 +02:00
.gitignore Initial commit 2018-01-27 17:15:32 +01:00
.travis.yml Add Travis CI: run tests and build wheels for Linux and macOS 2019-06-14 19:37:52 +02:00
COPYING Initial commit 2018-01-27 17:15:32 +01:00
COPYING.lesser Initial commit 2018-01-27 17:15:32 +01:00
MANIFEST.in Initial commit 2018-01-27 17:15:32 +01:00
NOTICE Update NOTICE 2019-06-12 09:31:04 +02:00
README.md Fix list count 2019-06-13 16:57:15 +02:00
setup.py Update beta version 2019-06-14 19:56:39 +02:00

TgCrypto

Fast Telegram Crypto Library for Python

TgCrypto is a high-performance, easy-to-install Telegram Crypto Library written in C as a Python extension. TgCrypto is intended for Pyrogram and implements the crypto algorithms Telegram requires, namely:

Installation

$ pip3 install -U tgcrypto

More info: https://docs.pyrogram.org/topics/tgcrypto

API

TgCrypto API consists of these six methods:

def 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:

Usage

IGE Mode

Note: Data must be padded to match a multiple of the block size (16 bytes).

import os

import tgcrypto

data = os.urandom(10 * 1024 * 1024 + 7)  # 10 MB of random data + 7 bytes to show padding
key = os.urandom(32)  # Random Key
iv = os.urandom(32)  # Random IV

# Pad with zeroes: -7 % 16 = 9
data += bytes(-len(data) % 16)

ige_encrypted = tgcrypto.ige256_encrypt(data, key, iv)
ige_decrypted = tgcrypto.ige256_decrypt(ige_encrypted, key, iv)

print(data == ige_decrypted)  # True

CTR Mode (single chunk)

import os

import tgcrypto

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

key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

ctr_encrypted = tgcrypto.ctr256_encrypt(data, key, enc_iv, bytes(1))
ctr_decrypted = tgcrypto.ctr256_decrypt(ctr_encrypted, key, dec_iv, bytes(1))

print(data == ctr_decrypted)  # True

CTR Mode (stream)

import os
from io import BytesIO

import tgcrypto

data = BytesIO(os.urandom(10 * 1024 * 1024))  # 10 MB of random data

key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

enc_state = bytes(1)  # Encryption state, starts from 0
dec_state = bytes(1)  # Decryption state, starts from 0

encrypted_data = BytesIO()  # Encrypted data buffer
decrypted_data = BytesIO()  # Decrypted data buffer

while True:
    chunk = data.read(1024)

    if not chunk:
        break

    # Write 1K encrypted bytes into the encrypted data buffer
    encrypted_data.write(tgcrypto.ctr256_encrypt(chunk, key, enc_iv, enc_state))

# Reset position. We need to read it now
encrypted_data.seek(0)

while True:
    chunk = encrypted_data.read(1024)

    if not chunk:
        break

    # Write 1K decrypted bytes into the decrypted data buffer
    decrypted_data.write(tgcrypto.ctr256_decrypt(chunk, key, dec_iv, dec_state))

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

CBC Mode

Note: Data must be padded to match a multiple of the block size (16 bytes).

import os

import tgcrypto

data = os.urandom(10 * 1024 * 1024 + 7)  # 10 MB of random data + 7 bytes to show padding
key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

# Pad with zeroes: -7 % 16 = 9
data += bytes(-len(data) % 16)

cbc_encrypted = tgcrypto.cbc256_encrypt(data, key, enc_iv)
cbc_decrypted = tgcrypto.cbc256_decrypt(cbc_encrypted, key, dec_iv)

print(data == cbc_decrypted)  # True

Testing

  1. Clone this repository: git clone https://github.com/pyrogram/tgcrypto.
  2. Enter the directory: cd tgcrypto.
  3. Run tests: python3 setup.py test.

License

LGPLv3+ © 2017-2019 Dan