Various improvements (#24)

This commit is contained in:
Dan 2021-10-11 18:18:46 +02:00 committed by GitHub
parent a3164a03c8
commit 4102d3b116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 70 deletions

View File

@ -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
@ -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

3
pyproject.toml Normal file
View File

@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View File

@ -24,7 +24,7 @@ with open("README.md", encoding="utf-8") as f:
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",
@ -40,12 +40,11 @@ setup(
"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",
@ -57,7 +56,7 @@ setup(
"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",

View File

@ -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},
@ -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
@ -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]
);

View File

@ -19,6 +19,7 @@
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "aes256.h"
@ -26,6 +27,10 @@
#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;
@ -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);
@ -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);
@ -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);
@ -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
};