Skip to main content

AegisQ

Post-Quantum Cryptography Engine for Python · v1.2.0

AegisQ is a hybrid cryptographic library that combines ML-KEM (FIPS 203) for quantum-resistant key encapsulation with AES-256-GCM for authenticated symmetric encryption. The cryptographic core is written in Rust for performance and security guarantees, exposed to Python via PyO3.

from aegisq import AegisCipher, SecurityLevel

cipher = AegisCipher(level=SecurityLevel.ML_KEM_768)
keypair = cipher.generate_keypair()

# Encrypt
package = cipher.encrypt(b"Secret data", keypair.public_key)

# Decrypt
plaintext = cipher.decrypt(package, keypair.secret_key)

Features

  • Quantum-safe key exchange — ML-KEM (Module Lattice-based KEM), standardized as NIST FIPS 203
  • Authenticated encryption — AES-256-GCM provides confidentiality and integrity in a single operation
  • Three security levels — ML-KEM-512 (NIST Level 1), ML-KEM-768 (Level 3, default), ML-KEM-1024 (Level 5)
  • Rust core, Python API — Cryptographic operations run in optimized Rust; Python developers get an ergonomic 3-line API
  • Constant-time operations — Timing-attack resistant via subtle::ConstantTimeEq and Barrett reduction
  • Memory zeroization — All secret keys and shared secrets are securely erased after use via zeroize
  • Zero-copy FFI — Data passes between Python and Rust without unnecessary copies
  • GIL release — Rust crypto operations release the Python GIL via py.detach(), enabling true parallelism
  • Type-safe — Full PEP 561 type stubs with IDE autocompletion support
  • Python 3.11+ — Built with PyO3 abi3 stable ABI for broad compatibility (3.11 through 3.13+)
  • Ephemeral sessions with forward secrecy — EphemeralSession class auto-generates keypairs and destroys secrets on close
  • Async support — encrypt_async() / decrypt_async() methods for non-blocking cryptographic operations

Installation

pip install aegisq-pqc

Python 3.11+ required. The package supports Python 3.11 through 3.13+ via PyO3's stable ABI.

From source (requires Rust toolchain)

# Prerequisites: Rust (via rustup), Python >= 3.11, maturin
pip install maturin

# Clone and build
git clone https://github.com/AC-Santiago/AegisQ.git
cd AegisQ
maturin develop --release

Quick Start

The AegisCipher class handles the entire hybrid KEM-DEM flow — ML-KEM key encapsulation followed by AES-256-GCM encryption — in a single .encrypt() call.

from aegisq import AegisCipher, SecurityLevel

# 1. Receiver generates a keypair
cipher_bob = AegisCipher(level=SecurityLevel.ML_KEM_768)
keypair = cipher_bob.generate_keypair()
# keypair.public_key  → 1184 bytes (share openly)
# keypair.secret_key  → 2400 bytes (keep private)

# 2. Sender encrypts with the receiver's public key
cipher_alice = AegisCipher(level=SecurityLevel.ML_KEM_768)
encrypted_package = cipher_alice.encrypt(
    plaintext=b"Top secret medical records",
    recipient_public_key=keypair.public_key,
)
# encrypted_package is a single bytes object:
# [ ML-KEM Capsule (1088 B) | Nonce (12 B) | Auth Tag (16 B) | Ciphertext ]

# 3. Receiver decrypts
decrypted = cipher_bob.decrypt(
    encrypted_package=encrypted_package,
    secret_key=keypair.secret_key,
)
assert decrypted == b"Top secret medical records"

Raw KEM Operations (Advanced)

The MlKem class exposes low-level ML-KEM operations for users building custom protocols:

from aegisq import MlKem, SecurityLevel

kem = MlKem(level=SecurityLevel.ML_KEM_768)
keypair = kem.generate_keypair()

# Encapsulate: produces a capsule + 32-byte shared secret
capsule, shared_secret = kem.encapsulate(keypair.public_key)

# Decapsulate: recovers the same 32-byte shared secret
recovered = kem.decapsulate(capsule, keypair.secret_key)
assert shared_secret == recovered

Async Operations

import asyncio
from aegisq import AegisCipher, SecurityLevel

async def main():
    cipher = AegisCipher(level=SecurityLevel.ML_KEM_768)
    keypair = cipher.generate_keypair()

    # Non-blocking encryption
    package = await cipher.encrypt_async(
        b"Secret data",
        keypair.public_key,
    )

    # Non-blocking decryption
    plaintext = await cipher.decrypt_async(
        package,
        keypair.secret_key,
    )
    print(plaintext)  # b'Secret data'

asyncio.run(main())

Ephemeral Sessions (Forward Secrecy)

The EphemeralSession class generates a keypair internally and destroys the secret key when the session closes, providing forward secrecy:

from aegisq import EphemeralSession

# Receiver creates an ephemeral session (secret key never leaves this context)
with EphemeralSession() as receiver:
    public_key = receiver.public_key  # Share this with the sender

    # Sender encrypts using the receiver's public key
    sender_cipher = EphemeralSession()
    package = sender_cipher.encrypt(
        b"Secret data",
        recipient_public_key=public_key,
    )
    sender_cipher.close()

    # Receiver decrypts
    plaintext = receiver.decrypt(package)

# Session closes, secret key is destroyed

Security Levels

Level Enum Value NIST Level Public Key Secret Key Capsule Package Overhead
ML-KEM-512 SecurityLevel.ML_KEM_512 1 800 B 1632 B 768 B 796 B
ML-KEM-768 SecurityLevel.ML_KEM_768 3 (default) 1184 B 2400 B 1088 B 1116 B
ML-KEM-1024 SecurityLevel.ML_KEM_1024 5 1568 B 3168 B 1568 B 1596 B

Package overhead = capsule + AES nonce (12 B) + AES auth tag (16 B). The total encrypted package size is overhead + plaintext length.


API Reference

class AegisCipher:
    def __init__(self, level: SecurityLevel = SecurityLevel.ML_KEM_768) -> None
    def generate_keypair(self) -> KeyPair
    def encrypt(self, plaintext: bytes, recipient_public_key: bytes) -> bytes
    def decrypt(self, encrypted_package: bytes, secret_key: bytes) -> bytes
    async def encrypt_async(self, plaintext: bytes, recipient_public_key: bytes) -> bytes
    async def decrypt_async(self, encrypted_package: bytes, secret_key: bytes) -> bytes

EphemeralSession (forward secrecy)

class EphemeralSession:
    def __init__(self, level: SecurityLevel = SecurityLevel.ML_KEM_768) -> None
    def public_key(self) -> bytes  # Read-only, secret key never exposed
    def encrypt(self, plaintext: bytes, recipient_public_key: bytes) -> bytes
    def decrypt(self, encrypted_package: bytes) -> bytes
    def close(self) -> None
    # Also supports context manager: `with EphemeralSession() as s: ...`

MlKem (advanced, raw KEM operations)

class MlKem:
    def __init__(self, level: SecurityLevel = SecurityLevel.ML_KEM_768) -> None
    def generate_keypair(self) -> KeyPair
    def encapsulate(self, public_key: bytes) -> tuple[bytes, bytes]
    def decapsulate(self, capsule: bytes, secret_key: bytes) -> bytes
    def load_public_key_b64(self, b64: str, level: SecurityLevel = None) -> bytes

Base64 Serialization

# Serialize public key to Base64 URL-safe (no padding)
b64 = keypair.public_key_b64()

# Load public key from Base64 URL-safe string
kem = MlKem(level=SecurityLevel.ML_KEM_768)
public_key_bytes = kem.load_public_key_b64(b64)

KeyPair

class KeyPair:
    public_key: bytes   # Encryption key (share openly)
    secret_key: bytes   # Decapsulation key (keep private)
    level: SecurityLevel

Exceptions

AegisQError(Exception)                          Base exception
├── DecapsulationError(AegisQError)             ML-KEM structural error (wrong buffer size)
├── DecryptionError(AegisQError)               AES-GCM auth tag failed (tampered or wrong key)
├── InvalidParameterError(AegisQError, ValueError)  Incorrect parameter sizes
├── RngError(AegisQError)                      OS CSPRNG unavailable
└── SessionExpiredError(AegisQError)           Attempted operation on closed EphemeralSession

All exceptions can be imported from the top-level package:

from aegisq import AegisQError, DecryptionError

Architecture

AegisQ is structured in three hermetic layers. Each layer only depends on the one below it:

┌─────────────────────────────────────────────────────────────┐
│  Layer 3: Python API  (aegisq/)                             │
│  AegisCipher, MlKem, SecurityLevel, exception hierarchy     │
│  Type hints, docstrings, developer-facing abstractions       │
├─────────────────────────────────────────────────────────────┤
│  Layer 2: FFI Bridge  (crates/aegisq-pyo3/)                 │
│  PyO3 bindings, GIL release, zero-copy data passing          │
│  No cryptographic logic — pure translation layer             │
├─────────────────────────────────────────────────────────────┤
│  Layer 1: Rust Core   (crates/aegisq-core/)                 │
│  ML-KEM (FIPS 203), AES-256-GCM, Transit Package assembly   │
│  #![no_std] compatible, constant-time, zeroize               │
└─────────────────────────────────────────────────────────────┘
  • Layer 1 implements all cryptographic math in pure Rust with no_std compatibility. It has no knowledge of Python.
  • Layer 2 translates Rust types to Python types via PyO3 and releases the GIL during expensive operations.
  • Layer 3 provides the ergonomic Python classes that end users interact with.

Development

Build

maturin develop                    # Debug build (fast compilation)
maturin develop --release          # Release build (optimized)

Test

# Rust tests (unit + integration, all crates)
cargo test --workspace

# Python tests
pytest tests/python/ -v

# Specific test suites
cargo test -p aegisq-core                     # Core crypto only
pytest tests/python/test_cipher_api.py        # AegisCipher end-to-end
pytest tests/python/test_hybrid_bindings.py   # Hybrid bridge
pytest tests/python/test_kem_bindings.py      # KEM bridge
pytest tests/python/test_kem_api.py           # MlKem API

Code Quality

cargo clippy --workspace -- -D warnings   # Rust linter (warnings are errors)
cargo fmt --all                           # Rust formatting
ruff check aegisq/                        # Python type checking

Security

Guarantees

Property Mechanism
IND-CCA2 security Implicit rejection in ML-KEM Decaps (FIPS 203 §7.3)
Quantum resistance M-LWE hardness assumption (ML-KEM)
Data confidentiality + integrity AES-256-GCM authenticated encryption
Timing attack immunity subtle::ConstantTimeEq, Barrett reduction
Memory scrubbing zeroize::Zeroize on all secrets
Nonce uniqueness Fresh 96-bit random nonce via OsRng per encrypt call
Integer overflow protection overflow-checks = true in release profile

Important Notes

  • No forward secrecy by default. If a secret key is compromised, all payloads encrypted to that key are compromised. Mitigation: Use ephemeral keypairs — generate a new keypair per session and discard the secret key after decryption.
  • ML-KEM Decaps never raises an error for invalid capsules (implicit rejection). Instead, it returns a pseudorandom key, which causes AES-GCM to fail with DecryptionError. This prevents chosen-ciphertext oracle attacks.
  • AES-GCM tag failure always raises DecryptionError. Unlike ML-KEM's silent rejection, a failed auth tag means the payload was tampered with or the wrong key was used.

Standards Compliance

Standard Description
FIPS 203 ML-KEM — Module-Lattice-Based Key-Encapsulation Mechanism (NIST, 2024)
NIST SP 800-38D AES-GCM — Galois/Counter Mode specification

Dependencies

Crate Version Purpose
aes-gcm 0.10 AES-256-GCM authenticated encryption (no_std, hardware AES-NI)
sha3 0.11 SHAKE-128/256 and SHA3-256/512 for ML-KEM (no_std)
zeroize 1.8 Secure memory erasure of secrets
subtle 2.6 Constant-time comparisons
getrandom 0.4 Cross-platform CSPRNG (no_std)
pyo3 0.28 Rust-Python FFI bindings (abi3-py311)

For complete technical documentation including the mathematical foundation, algorithm specifications, and security model details, see DOCUMENTATION.md.

Metadata

Release files for aegisq-pqc 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aegisq-pqc 1.5.0
File Size Uploaded
aegisq_pqc-1.5.0.tar.gz 84.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for aegisq-pqc 1.5.0
File
aegisq_pqc-1.5.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 abi3 Linux glibc 2.17+ x86-64 Details
aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.11 abi3 Linux glibc 2.17+ ARM64 Details
aegisq_pqc-1.5.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
aegisq_pqc-1.5.0-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.4 MB

Release files / aegisq_pqc-1.5.0.tar.gz

Download URL aegisq_pqc-1.5.0.tar.gz
Size 84.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1025b36840ca5db097d8c6a59aaefedaf19210a486bbe93a2e87b2f1ca775149
BLAKE2b-256 checksum
How to use checksums
f14699109588e1625e87afdc1cfe697d7325ba64e977fdabe8216fe7621cbebd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / aegisq_pqc-1.5.0-cp311-abi3-win_amd64.whl

Download URL aegisq_pqc-1.5.0-cp311-abi3-win_amd64.whl
Size 229.2 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
58f5e3bc301319ebb99b0a19f7772eac2620677a329a14b972b73f06a6674757
BLAKE2b-256 checksum
How to use checksums
2574fcbe4e5ad11694aef97c11ddd7606b174913db2ab125c95477f614595d36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 721.9 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
8fa6e072d4d48f19b60be31e97b43ad6b85c59ddac684569d0dadf8bd42fd49a
BLAKE2b-256 checksum
How to use checksums
04495e482e23002a224a6c4aa0eae15c735418be321885b32a66502a0014512e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL aegisq_pqc-1.5.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 683.7 kB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
45c7b5cd7ae5ca84496edc781d860698bbdee638ad96c00c0c60fe68ce1e1788
BLAKE2b-256 checksum
How to use checksums
1d4f82d8dbd51716ac767dec42efa59408e3862e96081dee918327651df0aacb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / aegisq_pqc-1.5.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL aegisq_pqc-1.5.0-cp311-abi3-macosx_11_0_arm64.whl
Size 338.3 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9a4db4363822098c9a1b100ed3ac360ecd152adfdd698ed1dd949d290f9418b4
BLAKE2b-256 checksum
How to use checksums
207452d815f7698e2ad3562768cf9ad9e406c117cc40783656aeadb03ecb40c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / aegisq_pqc-1.5.0-cp311-abi3-macosx_10_12_x86_64.whl

Download URL aegisq_pqc-1.5.0-cp311-abi3-macosx_10_12_x86_64.whl
Size 337.8 kB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
0ef43390ea769e8622bd312afa020e536c3c528946b202b258d7324d0b42029b
BLAKE2b-256 checksum
How to use checksums
86fa609106c4fb34574129c5afe58409bb8b2204371b383c6223ca25f4737e94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.5.0 This release

6 release files

1.4.0

6 release files

1.3.1

6 release files

1.3.0

6 release files

1.2.0

6 release files

1.1.0

6 release files

1.0.0

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page