Skip to content

Commit

Permalink
Various improvements (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
delivrance authored Oct 11, 2021
1 parent a3164a0 commit 4102d3b
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 70 deletions.
26 changes: 9 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,15 @@

<img src="https://i.imgur.com/JyxrStE.png" width="160" align="right">

> Fast and Portable Telegram Crypto Library for Python
> Fast and Portable Cryptography Extension Library for Pyrogram
**TgCrypto** is a Telegram Crypto Library written in C89 as a Python extension. It is designed to be portable, fast, easy
to install and use. TgCrypto is intended for [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the crypto
algorithms Telegram requires, namely:
**TgCrypto** is a Cryptography Library written in C as a Python extension. It is designed to be portable, fast,
easy to install and use. TgCrypto is intended for [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the
cryptographic algorithms Telegram requires, namely:

- **`AES256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto).
- **`AES256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn).
- **`AES256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport).

Python [wheels are available](https://pypi.org/project/TgCrypto/#files) for hassle-free installations; they are
automatically built and tested using Travis CI for Linux (i686, x86_64, AArch64), Windows (32-bit, 64-bit) and macOS
(x86_64).

Even though TgCrypto is primarily intended for use with Pyrogram, you are free and welcome to use it for any other
Python project too, as it's shipped as standalone package.

More info: https://docs.pyrogram.org/topics/tgcrypto
- **`AES-256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto).
- **`AES-256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn).
- **`AES-256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport).

## Requirements

Expand Down Expand Up @@ -163,7 +154,8 @@ print(data == cbc_decrypted) # True

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

## License

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
9 changes: 4 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
setup(
name="TgCrypto",
version="1.2.2",
description="Fast Telegram Crypto Library for Python",
description="Fast and Portable Cryptography Extension Library for Pyrogram",
long_description=readme,
long_description_content_type="text/markdown",
url="https://github.com/pyrogram",
Expand All @@ -40,12 +40,11 @@
"Programming Language :: C",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
Expand All @@ -57,7 +56,7 @@
"Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules"
],
keywords="fast pyrogram telegram crypto mtproto api client library python",
keywords="pyrogram telegram crypto cryptography encryption mtproto extension library aes",
project_urls={
"Tracker": "https://github.com/pyrogram/tgcrypto/issues",
"Community": "https://t.me/pyrogram",
Expand Down
70 changes: 35 additions & 35 deletions tgcrypto/aes256.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,25 +306,6 @@ static const uint32_t Td3[256] = {
0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0
};

static const uint8_t Td4[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};

static const uint8_t SBOX[16][16] = {
{0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
{0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
Expand All @@ -344,6 +325,25 @@ static const uint8_t SBOX[16][16] = {
{0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}
};

static const uint8_t SBOX1[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};

static const uint32_t RCON[10] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
Expand Down Expand Up @@ -591,40 +591,40 @@ void aes256_decrypt(const uint8_t in[16], uint8_t out[16], const uint32_t key[60
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ key[55];

s0 = (
((uint32_t) Td4[(t0 >> 24)] << 24)
^ ((uint32_t) Td4[(t3 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t2 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t1) & 0xff])
((uint32_t) SBOX1[(t0 >> 24)] << 24)
^ ((uint32_t) SBOX1[(t3 >> 16) & 0xff] << 16)
^ ((uint32_t) SBOX1[(t2 >> 8) & 0xff] << 8)
^ ((uint32_t) SBOX1[(t1) & 0xff])
^ key[56]
);

PUT(out, s0);

s1 = (
((uint32_t) Td4[(t1 >> 24)] << 24)
^ ((uint32_t) Td4[(t0 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t3 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t2) & 0xff])
((uint32_t) SBOX1[(t1 >> 24)] << 24)
^ ((uint32_t) SBOX1[(t0 >> 16) & 0xff] << 16)
^ ((uint32_t) SBOX1[(t3 >> 8) & 0xff] << 8)
^ ((uint32_t) SBOX1[(t2) & 0xff])
^ key[57]
);

PUT(out + 4, s1);

s2 = (
((uint32_t) Td4[(t2 >> 24)] << 24)
^ ((uint32_t) Td4[(t1 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t0 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t3) & 0xff])
((uint32_t) SBOX1[(t2 >> 24)] << 24)
^ ((uint32_t) SBOX1[(t1 >> 16) & 0xff] << 16)
^ ((uint32_t) SBOX1[(t0 >> 8) & 0xff] << 8)
^ ((uint32_t) SBOX1[(t3) & 0xff])
^ key[58]
);

PUT(out + 8, s2);

s3 = (
((uint32_t) Td4[(t3 >> 24)] << 24)
^ ((uint32_t) Td4[(t2 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t1 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t0) & 0xff])
((uint32_t) SBOX1[(t3 >> 24)] << 24)
^ ((uint32_t) SBOX1[(t2 >> 16) & 0xff] << 16)
^ ((uint32_t) SBOX1[(t1 >> 8) & 0xff] << 8)
^ ((uint32_t) SBOX1[(t0) & 0xff])
^ key[59]
);

Expand Down
71 changes: 59 additions & 12 deletions tgcrypto/tgcrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@
*/

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include "aes256.h"
#include "ige256.h"
#include "ctr256.h"
#include "cbc256.h"

#define DESCRIPTION "Fast and Portable Cryptography Extension Library for Pyrogram\n" \
"TgCrypto is part of Pyrogram, a Telegram MTProto library for Python\n" \
"You can learn more about Pyrogram here: https://pyrogram.org\n"

static PyObject *ige(PyObject *args, uint8_t encrypt) {
Py_buffer data, key, iv;
uint8_t *buf;
Expand Down Expand Up @@ -55,7 +60,7 @@ static PyObject *ige(PyObject *args, uint8_t encrypt) {
}

Py_BEGIN_ALLOW_THREADS
buf = ige256(data.buf, data.len, key.buf, iv.buf, encrypt);
buf = ige256(data.buf, data.len, key.buf, iv.buf, encrypt);
Py_END_ALLOW_THREADS

PyBuffer_Release(&data);
Expand Down Expand Up @@ -110,7 +115,7 @@ static PyObject *ctr256_encrypt(PyObject *self, PyObject *args) {
}

Py_BEGIN_ALLOW_THREADS
buf = ctr256(data.buf, data.len, key.buf, iv.buf, state.buf);
buf = ctr256(data.buf, data.len, key.buf, iv.buf, state.buf);
Py_END_ALLOW_THREADS

PyBuffer_Release(&data);
Expand Down Expand Up @@ -152,7 +157,7 @@ static PyObject *cbc(PyObject *args, uint8_t encrypt) {
}

Py_BEGIN_ALLOW_THREADS
buf = cbc256(data.buf, data.len, key.buf, iv.buf, encrypt);
buf = cbc256(data.buf, data.len, key.buf, iv.buf, encrypt);
Py_END_ALLOW_THREADS

PyBuffer_Release(&data);
Expand All @@ -173,20 +178,62 @@ static PyObject *cbc256_decrypt(PyObject *self, PyObject *args) {
return cbc(args, 0);
}

PyDoc_STRVAR(
ige256_encrypt_docs,
"ige256_encrypt(data, key, iv)\n"
"--\n\n"
"AES-256-IGE Encryption"
);

PyDoc_STRVAR(
ige256_decrypt_docs,
"ige256_decrypt(data, key, iv)\n"
"--\n\n"
"AES-256-IGE Decryption"
);

PyDoc_STRVAR(
ctr256_encrypt_docs,
"ctr256_encrypt(data, key, iv, state)\n"
"--\n\n"
"AES-256-CTR Encryption"
);

PyDoc_STRVAR(
ctr256_decrypt_docs,
"ctr256_decrypt(data, key, iv, state)\n"
"--\n\n"
"AES-256-CTR Decryption"
);

PyDoc_STRVAR(
cbc256_encrypt_docs,
"cbc256_encrypt(data, key, iv)\n"
"--\n\n"
"AES-256-CBC Encryption"
);

PyDoc_STRVAR(
cbc256_decrypt_docs,
"cbc256_decrypt(data, key, iv)\n"
"--\n\n"
"AES-256-CBC Encryption"
);

static PyMethodDef methods[] = {
{"ige256_encrypt", (PyCFunction) ige256_encrypt, METH_VARARGS, "AES256-IGE Encryption"},
{"ige256_decrypt", (PyCFunction) ige256_decrypt, METH_VARARGS, "AES256-IGE Decryption"},
{"ctr256_encrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, "AES256-CTR Encryption"},
{"ctr256_decrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, "AES256-CTR Decryption"},
{"cbc256_encrypt", (PyCFunction) cbc256_encrypt, METH_VARARGS, "AES256-CBC Encryption"},
{"cbc256_decrypt", (PyCFunction) cbc256_decrypt, METH_VARARGS, "AES256-CBC Decryption"},
{NULL, NULL, 0, NULL}
{"ige256_encrypt", (PyCFunction) ige256_encrypt, METH_VARARGS, ige256_encrypt_docs},
{"ige256_decrypt", (PyCFunction) ige256_decrypt, METH_VARARGS, ige256_decrypt_docs},
{"ctr256_encrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, ctr256_encrypt_docs},
{"ctr256_decrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, ctr256_decrypt_docs},
{"cbc256_encrypt", (PyCFunction) cbc256_encrypt, METH_VARARGS, cbc256_encrypt_docs},
{"cbc256_decrypt", (PyCFunction) cbc256_decrypt, METH_VARARGS, cbc256_decrypt_docs},
{NULL}
};

static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"tgcrypto",
"Telegram Crypto for Pyrogram",
"TgCrypto",
DESCRIPTION,
-1,
methods
};
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[testenv]
deps = pytest
commands = pytest {posargs}
commands = pytest {posargs}

0 comments on commit 4102d3b

Please sign in to comment.