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

From PyPI (recommended)

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

Encrypt and Decrypt (Recommended API)

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

AegisCipher (recommended for most users)

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.4.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.4.0
File Size Uploaded
aegisq_pqc-1.4.0.tar.gz 72.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for aegisq-pqc 1.4.0
File
aegisq_pqc-1.4.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
aegisq_pqc-1.4.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.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.11 abi3 Linux glibc 2.17+ ARM64 Details
aegisq_pqc-1.4.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
aegisq_pqc-1.4.0-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.3 MB

Release files / aegisq_pqc-1.4.0.tar.gz

Download URL aegisq_pqc-1.4.0.tar.gz
Size 72.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0e638e022a3c666d9a05f4e216dcd0c6ce07a5c686063f743d0eb46df1a244bc
BLAKE2b-256 checksum
How to use checksums
bb2c8ef0febbce2c24231377597e09b55540a161e100fe54a0d216256ae55d6f
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 20, 2026.

Transparency log

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

Download URL aegisq_pqc-1.4.0-cp311-abi3-win_amd64.whl
Size 214.6 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
2c4cc8ca9d91332219104698cb9563509be5537dcde135de5809764ccd28485b
BLAKE2b-256 checksum
How to use checksums
15083c3df190a44532ef786cce8bdc8a8b7bb763b9e186b3bd7a5c64e1d71073
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 20, 2026.

Transparency log

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

Download URL aegisq_pqc-1.4.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 700.8 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
e3c6651cb81cb80d9200e5e28b8a06aa1bca95cfe5ad2dfaf394a35990e6e7b7
BLAKE2b-256 checksum
How to use checksums
080ae037cf3f826a41ff416d8d1f9f92ecf5cca2a9c34246e425c56f36a5a2d3
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 20, 2026.

Transparency log

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

Download URL aegisq_pqc-1.4.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 662.6 kB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
10d76f85aa78ea4abf3c8891954870d6b30ef7aed7560d5b8d96533e6d38508c
BLAKE2b-256 checksum
How to use checksums
a75bb2b981d0a3bd84bb5507bb6cd11e6d4c124d9b20f0d409f61f70dea90223
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 20, 2026.

Transparency log

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

Download URL aegisq_pqc-1.4.0-cp311-abi3-macosx_11_0_arm64.whl
Size 323.1 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e04d91fcf3b36fd2d455ff7c8eb974db849425732e723f593a331c2bc6efbe37
BLAKE2b-256 checksum
How to use checksums
a1ed3357c69f73589c05aa077cdffe3f979488febfe62938bf097c7128e24e0e
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 20, 2026.

Transparency log

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

Download URL aegisq_pqc-1.4.0-cp311-abi3-macosx_10_12_x86_64.whl
Size 324.9 kB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
2d1c5d09324ca46ecae5578294cd8de3dd94a7d1995df8cb7aed955d64033caa
BLAKE2b-256 checksum
How to use checksums
00e4db53d2502d26010dde8ec12cd4f9929db50091d878489a9b43737e7a6243
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 20, 2026.

Transparency log

Release history Release notifications | RSS feed

1.5.0

6 release files

This release

1.4.0 This release

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