Installation¶
PyFE4AI is installed from a clone of its repository. It needs Python 3.10
or later, gmpy2 and numpy; an optional Rust extension makes the
lattice schemes much faster and provides the BLS12-381 pairing group.
From source¶
git clone https://github.com/spire-studio/pyfe4ai.git
cd pyfe4ai
conda env create -f environment.yml # Python and gmpy2 from conda-forge
conda activate pyfe4ai
pip install -e ".[test]" # the package, with pytest
The dependencies are declared in pyproject.toml; environment.yml
only adds what conda provides better than pip (Python itself and gmpy2
built against conda-forge’s GMP and MPFR). Without conda, a virtual
environment with pip install -e ".[test]" works as well where gmpy2
wheels exist for the platform.
The Rust extension¶
With a Rust toolchain (cargo) on the PATH, pip install also
builds the native extension pyfe4ai._rust_native (sources in rust/).
It runs the Ring-LWE, dense-LWE and threshold hot paths natively, provides
ristretto255 and the BLS12-381 pairing group that the pairing-based schemes
use by default, and computes the same values as the Python code, which
remains the reference and the fallback.
The first build downloads the Rust crates of
rust/native/Cargo.tomlfrom crates.io; later builds use cargo’s cache.In a source checkout,
python tools/build_rust.pybuilds (or rebuilds) the extension in place,--offlinewith cached crates only.PYFE4AI_NO_NATIVE=1 pip install -e .skips it.A failed build does not fail the installation:
pipprints a warning and the package runs its Python implementation.
Check what you got:
import pyfe4ai
info = pyfe4ai.backend_info()
print(info["native_available"], info["native_version"], info["backend"])
backend_info() reports the library version, whether the extension is
available (or why it could not be imported), its version and build, the
backend the calling thread uses, the threads per native call, the Gaussian
sampler and the parameter cache directory. Without the extension, the first
operation that falls back to Python issues one
FEWarning per process saying so; the
Python implementation is about 5 to 35 times slower on the lattice schemes.
Environment variables and the parameter cache lists the environment variables that select the backend
and the threads.
Other pairing curves¶
The pairing-based schemes (function-hiding IPE, the FH-MCFE family and
quadratic FE) run on BLS12-381 from the Rust extension. Other curves
(pairing_group_param = "MNT224", "BN254", …) need
charm-crypto-framework, which is built
from source and needs GMP, OpenSSL and PBC 1.0.0 first:
pip install -e ".[test,pairing]"
The repository’s docker/Dockerfile.pairing builds an image with all of
them (docker build -f docker/Dockerfile.pairing -t pyfe4ai-pairing .).
Without the extension and without charm-crypto, the pairing-based schemes
are not available; every other scheme is.
Running the tests¶
python -m pytest -q # all tests
python -m pytest -m core -q # everything that needs no pairing backend
python -m pytest -m "not slow" -q
With the extension built, run the suite on both backends
(PYFE4AI_BACKEND=native and PYFE4AI_BACKEND=python): the native
code must match the Python reference bit for bit. CONTRIBUTING.md in the
repository describes the test groups and marks.
Building this documentation¶
pip install -e ".[doc]"
cd docs && make html # _build/html/index.html