Metadata-Version: 2.4
Name: tgcrypto-zig
Version: 0.1.1
Summary: Fast and Portable Cryptography Extension Library for Pyrogram (Zig backend)
Author: rick
Author-email: rick <itsmerick184@gmail.com>
License-Expression: LGPL-3.0-or-later
Project-URL: Homepage, https://github.com/fjralf/tgcrypto-zig
Project-URL: Source, https://github.com/fjralf/tgcrypto-zig
Project-URL: Issues, https://github.com/fjralf/tgcrypto-zig/issues
Keywords: pyrogram,telegram,crypto,cryptography,encryption,mtproto,extension,library,aes,zig
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Security
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Internet
Classifier: Topic :: Communications
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <4.0,>=3.11
Description-Content-Type: text/markdown
License-File: COPYING
License-File: COPYING.lesser
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Dynamic: license-file

# tgcrypto2 (Zig backend)

Fast and Portable Cryptography Extension Library for Pyrogram — reimplemented
in Zig 0.16, drop-in compatible with the original C extension, plus a native
`xor(a, b)` helper.

## Build & publish to PyPI

```bash
python -m pip install --upgrade build twine
python -m build          # produces sdist + wheel in dist/
twine upload dist/*
```

`ziglang==0.16.0` is declared as a `[build-system] requires` dependency in
`pyproject.toml`, so `pip`/`build` fetches it automatically into an isolated
build environment — no system Zig install needed, and no `.so` is committed
to the repo. When someone runs `pip install tgcrypto2`, `setup.py`'s custom
`build_ext` step shells out to `python -m ziglang build so` to compile
`src/tgcrypto.zig` fresh for their platform/Python version, then places the
resulting `_tgcrypto` extension where Python expects it.

## Local development build

```bash
pip install -e .
python -m pytest
```

## What's inside

- `ige256_encrypt`, `ige256_decrypt`
- `ctr256_encrypt`, `ctr256_decrypt`

All functions match the reference C implementation's behavior
and signatures exactly (verified against the full upstream NIST/random test
suite).

## Free-threading (Python 3.13+ / PEP 703)

`_tgcrypto` opts into running under a free-threaded (`Py_GIL_DISABLED`,
`python3.1xt`) interpreter via the `Py_mod_gil` module slot. This matters
because a C extension that does *not* declare support gets silently
downgraded by CPython: the GIL is re-enabled for the *entire process* for
as long as that module stays imported, not just for that module — so an
unaware dependency can quietly take away the benefit of free-threading from
everything else running in the same interpreter.

This module is safe to opt in because every exported function is stateless
per call: each allocates and returns a fresh output buffer, and the AES
context (`std.crypto.core.aes`) lives on the stack for the duration of a
single call with no shared mutable state. The one thing to be aware of:
`ctr256_*`/`cbc256_*` mutate the caller-supplied `iv`/`state` buffer in
place (matching the reference C behavior and this project's own upstream
tests, which pass plain `bytes`). If the *same* `bytearray` is handed to
two threads concurrently, that's a data race in the caller's Python code —
no different from any two threads mutating a shared mutable object without
a lock, and not something the GIL was protecting either, since the GIL is
already released around the actual compute.

On Python < 3.13 (no `Py_mod_gil` slot exists) this is a no-op — the module
builds and behaves identically to a normal GIL-bound extension.
