Python wrapper for the FAEST (Fast AES-based Signature with Tight security) post-quantum digital signature scheme.
FAEST is a post-quantum signature scheme submitted to the NIST PQC standardization process. This Python package provides high-level bindings to the C reference implementation:
- 🔐 Quantum-resistant signatures based on symmetric cryptography
- 🚀 High performance - Direct binding to optimized C code via CFFI
- 🛡️ Memory-safe - Automatic private key clearing
- 🎯 Pythonic API - Clean, intuitive interface
- 📦 12 parameter sets - All FAEST variants supported
pip install pyfaestPre-built wheels available for:
- Linux x86_64 (manylinux)
- macOS arm64 (Apple Silicon)
- Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
No compilation required! For other platforms, see installation guide.
git clone https://github.com/Shreyas582/pyfaest.git
cd pyfaest
pip install -e .from faest import Keypair, sign, verify
# Generate a keypair
keypair = Keypair.generate('128f')
# Sign a message
message = b"Hello, quantum-resistant world!"
signature = sign(message, keypair.private_key)
# Verify the signature
is_valid = verify(message, signature, keypair.public_key)
print(f"Valid: {is_valid}") # TruePyFAEST supports all 12 FAEST parameter sets:
| Parameter Set | Security Level | Public Key | Private Key | Signature |
|---|---|---|---|---|
128f |
NIST Level 1 | 32 bytes | 32 bytes | 5,924 B |
128s |
NIST Level 1 | 32 bytes | 32 bytes | 4,506 B |
192f |
NIST Level 3 | 48 bytes | 40 bytes | 14,948 B |
192s |
NIST Level 3 | 48 bytes | 40 bytes | 11,260 B |
256f |
NIST Level 5 | 48 bytes | 48 bytes | 26,548 B |
256s |
NIST Level 5 | 48 bytes | 48 bytes | 20,696 B |
em_128f |
NIST Level 1 | 32 bytes | 32 bytes | 5,060 B |
em_128s |
NIST Level 1 | 32 bytes | 32 bytes | 3,906 B |
em_192f |
NIST Level 3 | 48 bytes | 48 bytes | 12,380 B |
em_192s |
NIST Level 3 | 48 bytes | 48 bytes | 9,340 B |
em_256f |
NIST Level 5 | 64 bytes | 64 bytes | 23,476 B |
em_256s |
NIST Level 5 | 64 bytes | 64 bytes | 17,984 B |
Suffix meanings:
f= Fast (optimized for speed)s= Small (optimized for signature size)em_*= Extended mode variants
Note: 192-bit variants have asymmetric key sizes (private=40, public=48) by design.
from faest import Keypair
# Generate a new keypair
keypair = Keypair.generate('128f')
# Access individual keys
public_key = keypair.public_key
private_key = keypair.private_key
param_set = keypair.param_set
# Validate keypair
is_valid = keypair.validate()from faest import sign, verify
# Sign a message
signature = sign(message, private_key)
# Verify a signature
is_valid = verify(message, signature, public_key)# Export keys as bytes
pk_bytes = public_key.to_bytes()
sk_bytes = private_key.to_bytes()
# Import from bytes
keypair = Keypair.from_bytes(pk_bytes, sk_bytes, '128f')
# Or create keys individually
from faest import PublicKey, PrivateKey
public_key = PublicKey(pk_bytes, '128f')
private_key = PrivateKey(sk_bytes, '128f')from faest import (
FaestError, # Base exception
KeyGenerationError, # Key generation failed
SignatureError, # Signing failed
VerificationError, # Verification failed
InvalidKeyPairError, # Keypair validation failed
)
try:
keypair = Keypair.generate('128f')
signature = sign(message, keypair.private_key)
except KeyGenerationError as e:
print(f"Key generation failed: {e}")
except SignatureError as e:
print(f"Signing failed: {e}")Complete examples in the examples/ directory:
basic_usage.py- Simple signing and verificationall_parameter_sets.py- Testing all 12 parameter setskey_serialization.py- Key import/export patterns
- Installation Guide - Detailed installation instructions
- Getting Started - Quick start tutorial
- Developer Guide - Architecture and internals
- Maintainer Guide - Release and publishing
- Python 3.8 or higher
- Linux x86_64, macOS arm64, or Windows (via WSL)
- CFFI >= 1.15.0 (automatically installed)
Note: Pre-built wheels eliminate the need for compilers or build tools.
- Reference implementation - Not yet optimized for production
- NIST evaluation - FAEST is a candidate, not yet standardized
- Memory safety - Private keys automatically cleared from memory
- Side channels - No protection against timing/power analysis attacks
- Secure storage - Store private keys encrypted at rest
Typical performance on modern hardware (single core):
| Operation | 128f | 128s | 256f | 256s |
|---|---|---|---|---|
| Key generation | ~1 ms | ~1 ms | ~2 ms | ~2 ms |
| Signing | ~5 ms | ~8 ms | ~15ms | ~25ms |
| Verification | ~5 ms | ~8 ms | ~15ms | ~25ms |
f variants are faster, s variants produce smaller signatures.
| Platform | Status | Notes |
|---|---|---|
| Linux x86_64 | ✅ Supported | Pre-built wheels |
| macOS arm64 | ✅ Supported | Pre-built wheels (Apple Silicon) |
| Windows (WSL) | ✅ Supported | Use Linux wheels in WSL |
| macOS x86_64 | Build from source (Intel Macs) | |
| Linux aarch64 | Build from source (ARM64 Linux) | |
| Windows native | ❌ Not supported | Use WSL instead |
pip install pytest
pytest tests/ -vSee INSTALLATION.md for detailed instructions.
Quick version:
# Build FAEST C library first
git clone https://github.com/faest-sign/faest-ref.git
cd faest-ref
meson setup build
meson compile -C build
# Install PyFAEST
cd /path/to/pyfaest
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Copy library files
FAEST_REF=/path/to/faest-ref bash scripts/update_libraries.sh
# Install in development mode
pip install -e .
# Verify
python verify_install.pypyfaest/
├── faest/ # Python package
│ ├── __init__.py # Public API exports
│ └── core.py # Main implementation (550+ lines)
├── lib/ # Bundled FAEST libraries
├── include/ # C header files
├── examples/ # Usage examples
├── tests/ # Test suite (37 tests)
├── docs/ # Documentation
├── scripts/ # Build/release scripts
├── faest_build.py # CFFI build script
└── setup.py # Package configuration
MIT License - See LICENSE file for details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
See DEVELOPER_GUIDE.md for more details.
If you use PyFAEST in research, please cite:
@software{pyfaest,
title = {PyFAEST: Python Bindings for FAEST},
author = {PyFAEST Contributors},
year = {2025},
url = {https://github.com/Shreyas582/pyfaest}
}See CHANGELOG.md for version history.
- Issues: GitHub Issues
- Documentation: docs/
- Examples: examples/
PyFAEST is built on top of the FAEST reference implementation by the FAEST team. Special thanks to all contributors to the FAEST project.
I have created this for a Post-Quantum Cryptography class project at NYU.