fairlearn-fhe
Drop-in encrypted Fairlearn metrics. Fairlearn-compatible API for the supported metric subset; ciphertext arithmetic over CKKS via TenSEAL.
fairlearn-fhe is an early-stage project maintained at
https://github.com/BAder82t/fairlearn-fhe.
# plaintext
from fairlearn.metrics import demographic_parity_difference
disp = demographic_parity_difference(y_true, y_pred, sensitive_features=A)
# encrypted (one import change)
from fairlearn_fhe.metrics import demographic_parity_difference
from fairlearn_fhe import build_context, encrypt
ctx = build_context()
y_p_enc = encrypt(ctx, y_pred)
disp = demographic_parity_difference(y_true, y_p_enc, sensitive_features=A)
disp is numerically equivalent to the plaintext result within CKKS noise tolerance (< 1e-4 abs error in default settings).
Trust models
Two modes are supported. The default ports the regaudit-fhe convention; the second goes further.
Mode A — encrypted predictions, plaintext sensitive features (default)
- Encrypted:
y_pred. - Plaintext:
y_true,sensitive_features, group counts. - Cost: one ct×pt multiply + slot-sum per group → depth 1.
Mode B — fully-encrypted predictions and sensitive features
from fairlearn_fhe import build_context, encrypt, encrypt_sensitive_features
from fairlearn_fhe.metrics import demographic_parity_difference
ctx = build_context()
y_pred_enc = encrypt(ctx, y_pred)
sf_enc = encrypt_sensitive_features(ctx, sensitive_features, y_true=y_true)
disp = demographic_parity_difference(y_true, y_pred_enc, sensitive_features=sf_enc)
- Encrypted:
y_pred, the per-row group-membership masks. - Plaintext (auditor metadata): group counts, per-group positive/negative counts (passed via
y_true=at encryption time). - Cost: ct×ct + ct×pt + slot-sum per group → depth 2.
y_true remains plaintext in both modes (it is the auditor's ground truth). The denominators of TPR/FPR-style metrics — per-group positive/negative counts — are always revealed: there is no fairness signal without them.
Per-group rates are decrypted at the audit boundary; final aggregation (max, min, ratio, difference) runs on those K plaintext scalars.
Supported metrics
| Plaintext name | Encrypted? | Mechanism |
|---|---|---|
selection_rate |
yes | sum(y_pred·mask)/n_g |
true_positive_rate |
yes | sum(y_pred·y_true·mask)/sum(y_true·mask) |
true_negative_rate |
yes | sum((1-y_pred)·(1-y_true)·mask)/sum((1-y_true)·mask) |
false_positive_rate |
yes | sum(y_pred·(1-y_true)·mask)/sum((1-y_true)·mask) |
false_negative_rate |
yes | sum((1-y_pred)·y_true·mask)/sum(y_true·mask) |
mean_prediction |
yes | sum(y_pred·mask)/n_g |
demographic_parity_difference |
yes | max-min selection_rate over groups |
demographic_parity_ratio |
yes | min/max selection_rate over groups |
equalized_odds_difference |
yes | max(tpr_diff, fpr_diff) |
equalized_odds_ratio |
yes | min(tpr_ratio, fpr_ratio) |
equal_opportunity_difference |
yes | tpr max-min |
equal_opportunity_ratio |
yes | tpr min/max |
Plus MetricFrame.fhe() returning an EncryptedMetricFrame.
Backends
Two CKKS backends share a single API:
from fairlearn_fhe import build_context
ctx_tenseal = build_context(backend="tenseal") # default; pip-installable
ctx_openfhe = build_context(backend="openfhe") # native OpenFHE backend, opt-in
Benchmarked on n=1024, 3 sensitive groups, depth-6 circuit:
| backend | ctx build | encrypt | dp_diff | dp abs err | eo_diff | eo abs err |
|---|---|---|---|---|---|---|
| tenseal | 888 ms | 7.5 ms | 284 ms | 1e-7 | 562 ms | 2e-7 |
| openfhe | 321 ms | 13.5 ms | 505 ms | 2e-10 | 1015 ms | 4e-11 |
On the included benchmark, OpenFHE gives lower numeric error; TenSEAL is faster per metric and ships via pip on every supported platform.
Install
pip install fairlearn-fhe # tenseal backend
pip install fairlearn-fhe[openfhe] # add openfhe backend (requires C++ build)
pip install fairlearn-fhe[signing] # add Ed25519 envelope signing helpers
Verify an audit envelope without importing an FHE backend:
fairlearn-fhe-verify envelope.json
License
Apache-2.0. Compatible with Fairlearn (MIT).
Metadata
Release files for fairlearn-fhe 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fairlearn_fhe-0.2.4.tar.gz | 98.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fairlearn_fhe-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.8 kB
Release files / fairlearn_fhe-0.2.4.tar.gz
| Download URL | fairlearn_fhe-0.2.4.tar.gz |
|---|---|
| Size | 98.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
164951bf89bbd24b0842ffbf415344b2e10af24114347d9d0874fbe536b79c77
|
|
BLAKE2b-256 checksum How to use checksums |
a6fe458e5f0caf52fc78f9b41c5ba7d2453b2b2215d35a47b317b1d481d49f8d
|
| 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 Oct 7, 2026.
Transparency logRelease files / fairlearn_fhe-0.2.4-py3-none-any.whl
| Download URL | fairlearn_fhe-0.2.4-py3-none-any.whl |
|---|---|
| Size | 57.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fd99709e70da6c6986bcf54f0953aba31cc2be4243b9f263d115c9ce79eb844d
|
|
BLAKE2b-256 checksum How to use checksums |
3cf88e117542e7a48319357da82cd639cce0328bd00a97e181e28ac4168b739e
|
| 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 Oct 7, 2026.
Transparency log