From fce6324ae50a8e28c63637de820ca373896ef35b Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Fri, 7 Nov 2025 22:20:27 +0000 Subject: [PATCH] Documentation updates, added BUILD.md --- BUILD.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 14 ++++--- 2 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 BUILD.md diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..8009f34 --- /dev/null +++ b/BUILD.md @@ -0,0 +1,114 @@ +# Building pyaegis + +This document contains instructions for developers who want to build pyaegis from source. + +## Prerequisites + +- **Python 3.12 or later** (CPython only) +- **Zig compiler** (required for building the libaegis static library) +- **C compiler** (gcc, clang, or MSVC) with development headers +- **uv** (recommended for dependency management) or **pip** + +### Installing Zig + +pyaegis uses Zig to build the underlying libaegis C library. Install Zig from [ziglang.org/download](https://ziglang.org/download/) or using your package manager: + +- **macOS**: `brew install zig` +- **Linux**: See [Zig installation guide](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager) +- **Windows**: `choco install zig` or `scoop install zig` + +## Getting the Source + +Clone the repository with submodules: + +```fish +git clone --recursive https://github.com/LeoVasanko/pyaegis.git +cd pyaegis +``` + +If you already cloned without `--recursive`, initialize submodules: + +```fish +git submodule update --init --recursive +``` + +## Development Setup + +### Installing in the development tree + +```fish +uv sync +uv run setup.py build_ext --inplace +``` + +The latter command is necessary for building the C code into the source tree, as normal `uv build` does not place it there (only in wheels). + +## Building libaegis Separately (Optional) + +The build process automatically builds libaegis, but you can build it manually: + +```fish +cd libaegis +zig build -Drelease +``` + +This creates the static library in `libaegis/zig-out/lib/`, and the Python CFFI build will find it from there. + +## Running Tests + +Run the test suite: + +```fish +uv run pytest +``` + +## Building Distributions + +Build source and wheel distributions: + +```fish +uv build +``` + +This creates files in the `dist/` directory. + +## Code Generation + +The Python modules are generated from templates. If you modify the core implementation in `pyaegis/aegis256x4.py`, regenerate the other variants: + +```fish +python tools/gen_modules.py +``` + +If you update libaegis headers, regenerate the CFFI definitions: + +```fish +python tools/gen_cdef.py +``` + +## Troubleshooting + +### Zig Not Found + +If you see an error about Zig not being found, ensure it's installed and in your PATH: + +```fish +zig version +``` + +If you cannot install Zig, you may manually compile in the libaegis folder (Zig, CMake) or simply place a libaegis.a in there if you can get it from elsewhere as a binary. + +### Build Failures + +- Ensure you have a C compiler installed +- On macOS, you may need Xcode command line tools: `xcode-select --install` +- On Linux, install development packages (e.g., `build-essential` on Ubuntu) + +## Project Structure + +- `pyaegis/` - Python package source +- `libaegis/` - C library source (submodule) +- `tests/` - Test suite +- `tools/` - Code generation scripts +- `examples/` - Usage examples +- `build_backend.py` - Custom setuptools build backend to do the Zig libaegis build diff --git a/README.md b/README.md index 41a8502..44dc47a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Fast, safe Python bindings for the AEGIS family of authenticated encryption algo - PyPI (recommended): -```bash +```fish pip install pyaegis ``` @@ -26,15 +26,17 @@ All submodules expose the same API; pick one for your key/nonce size and platfor ## Quick start +Normal authenticated encryption using the AEGIS-128X4 algorithm: + ```python from pyaegis import aegis128x4 as ciph -key = ciph.random_key() -nonce = ciph.random_nonce() +key = ciph.random_key() # Secret key (stored securely) +nonce = ciph.random_nonce() # Public nonce (recreated for each message) msg = b"hello" ct = ciph.encrypt(key, nonce, msg) -pt = ciph.decrypt(key, nonce, ct) +pt = ciph.decrypt(key, nonce, ct) # Raises ValueError if anything was tampered with assert pt == msg ``` @@ -239,7 +241,7 @@ uv run -m pyaegis.benchmark Benchmarks of the Python module and the C library run on Intel i7-14700, linux, single core (the software is not multithreaded). Note that the results are in megabits per second, not bytes. The CPU lacks AVX-512 that makes the X4 variants faster on AMD hardware. -```bash +```fish $ python -m pyaegis.benchmark AEGIS-256 107666.56 Mb/s AEGIS-256X2 191314.53 Mb/s @@ -256,7 +258,7 @@ AEGIS-256X4 MAC 347406.96 Mb/s ``` The Python library performance is similar to that of the C library: -```bash +```fish $ ./libaegis/zig-out/bin/benchmark AEGIS-256 107820.86 Mb/s AEGIS-256X2 205025.57 Mb/s