$ pip install fhe-oracle
Adversarial precision testing for Fully Homomorphic Encryption. Finds CKKS, BGV, BFV, and TFHE bugs that random testing misses. Open source, free forever, CMA-ES search with noise-aware fitness. Drop into CI and fail the build when your encrypted circuit diverges from its plaintext twin.
FHE precision bugs are input-localised. A CKKS circuit that passes 99,999 random inputs can still return garbage on the 100,000th.
Homomorphic schemes (CKKS, BGV, BFV) accumulate noise input by input. The inputs that trigger failure sit in narrow regions of the input space — regions that scale with multiplicative depth and the magnitude of intermediate ciphertexts. Those regions are vanishingly unlikely to be hit by uniform random sampling.
Result: your test suite passes, your production circuit silently returns catastrophically wrong answers on specific feature vectors. No existing FHE toolchain has a CI/CD gate for this.
Random testing wastes evaluations in safe parts of the input space. An adversarial optimiser — CMA-ES with auto-scaled step size — spends its budget climbing toward the failure region and finds bugs orders of magnitude larger than operational-box random sampling at the same wall-clock budget.
On the CKKS Taylor-3 sigmoid defect benchmark (d=5, narrow-corridor failure at |z| > 3), AutoOracle reliably finds 490 of 500 diverging inputs across 5 seeds. In-distribution random on a narrow operational box finds 0. Full benchmark table below.
One line. Python 3.9+. AGPL-3.0. No API key, no account, no telemetry.
pip install fhe-oracle
Pure-divergence mode — no native FHE library required. Works in any CI environment that can install numpy and cma.
pip install 'fhe-oracle[tenseal]' # or bring your own adapter for # OpenFHE · Concrete ML · SEAL
The [tenseal] extra turns on noise-guided search for CKKS. OpenFHE, Concrete ML, and SEAL adapters are shipped pluggable — wire up your compiled circuit.
Two Python functions — your plaintext model and its FHE-compiled version. The Oracle finds where they disagree.
import numpy as np
from fhe_oracle import AutoOracle # auto-classifies circuit + dispatches
def plaintext_fn(x):
return float(np.sum(np.asarray(x) ** 2))
def fhe_fn(x):
# Stand-in for your FHE-compiled predict function.
# Here: noise scales with input norm^2 (CKKS depth-noise pattern),
# with a hot zone that inflates error 100x when |x|^2 > 8.
v = float(np.sum(np.asarray(x) ** 2))
base = 1e-5 * v
amp = 100.0 if v > 8.0 else 1.0
return plaintext_fn(x) + base * amp
auto = AutoOracle(
plaintext_fn=plaintext_fn,
fhe_fn=fhe_fn,
bounds=[(-3.0, 3.0)] * 4,
)
result = auto.run(n_trials=500, threshold=1e-3, seed=0)
print(result.verdict) # "FAIL"
print(result.max_error) # e.g. 3.6e-2
print(result.regime) # "distant_defect" | "standard" | ...
print(result.strategy_used) # "robust_cma_es" | "cma_es" | ...
Adversarial CMA-ES over the input domain, guided by a noise-aware fitness that combines divergence with ciphertext-level signals.
AutoOracle runs a 50-eval landscape probe, classifies the divergence landscape into one of five regimes, and dispatches to the matching search strategy:
Wx+b.Every run returns a structured OracleResult:
Live runs from the repo at a 500-evaluation budget, deterministic seed 42. Each benchmark takes under one second on a 2020-era laptop.
| Circuit | Dim | Random (op-box) | AutoOracle | Note | |---------------------------------|------|-----------------|------------|-----------------------------| | CKKS Taylor-3 defect | 5 | 0 | 453 | Distant-defect regime | | LR-mock noise amplifier | 32 | 84 | 172 | Standard CMA-ES | | LR-mock noise amplifier | 128 | 78 | 160 | Standard CMA-ES | | Poly depth-4 noise | 32 | 404 | 439 | Saturated (box hit already) | | WDBC Taylor-3 (d=30, tau=100) | 30 | 4 | 382 | Standard CMA-ES |
Open-core release. AutoOracle is the recommended entry point; advanced knobs remain on FHEOracle.
Passing sigma0=None auto-derives the initial step size from your input bounds (mean(range)/4, the canonical CMA-ES guideline). Fixes the flat-fitness-basin trap that stranded CMA-ES on narrow-corridor CKKS defects.
FHEOracle(..., sigma0=None)
New landscape classifier detects when divergence is concentrated far from the box centre (flat fitness at the origin, cliff at the edges). Dispatches to auto-sigma so CMA-ES escapes the basin reliably.
AutoOracle(...).run(n_trials=500) # regime="distant_defect" when detected
Custom seed generators and fitness functions can be registered via Python entry points and auto-discovered by AutoOracle — no user code changes required. Used internally to keep patented Claim 5 components out of the AGPL distribution.
diversity_injection=True, inject_every=5 prevents covariance collapse on plateaus.adaptive=True early-stops on FAIL, auto-extends, and switches to random when CMA-ES stalls.multi_output=True targets argmax flips and near-margin inputs.random_floor=0.3 reserves budget for uniform sampling, then warm-starts CMA-ES.restarts=N, bipop=True for multi-basin landscapes.separable=True for axis-aligned high-dimensional search.PreactivationOracle(W, b, ...) collapses affine front-ends to a rank-k subproblem.EmpiricalSearch draws from your training distribution + jitter; union-verdict with CMA-ES via run_hybrid.per_op_trace(x, plain, fhe) localises where error accumulates in a CKKS circuit.Drop two files into your repo and fail the build when your FHE circuit diverges from its plaintext twin.
oracle_check.pyimport os
from fhe_oracle import AutoOracle
from my_model import plaintext_fn, fhe_fn
auto = AutoOracle(
plaintext_fn=plaintext_fn,
fhe_fn=fhe_fn,
bounds=[(-3.0, 3.0)] * 10,
)
result = auto.run(
n_trials=int(os.environ.get("ORACLE_N_TRIALS", "500")),
threshold=float(os.environ.get("ORACLE_THRESHOLD", "0.01")),
)
print(f"regime={result.regime} strategy={result.strategy_used} "
f"max_error={result.max_error:.3e}")
raise SystemExit(0 if result.verdict == "PASS" else 1)
.github/workflows/fhe-precision.ymlname: FHE Precision Test
on: [push, pull_request]
jobs:
fhe-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install fhe-oracle
- run: python oracle_check.py
env:
ORACLE_THRESHOLD: "0.01"
ORACLE_N_TRIALS: "500"
Pluggable noise models. Works with every major open FHE stack.
CKKS, BGV, BFV. Wire your compiled circuit's Eval call into fhe_fn and the noise-guided fitness activates.
Swap predict_proba(x, fhe="execute") in for the FHE function. Works with TFHE circuits out of the box.
CKKS and BFV. Bring your encoder / evaluator; the oracle handles the search layer.
pip install 'fhe-oracle[tenseal]' — first-class CKKS with noise-budget-aware search.
Shipped on PyPI. Reverse chronological.
sigma0=None auto-scale, DISTANT_DEFECT regime, entry-point plugin registry.AGPL-3.0. Free for open-source, research, and internal use.
The fhe-oracle package on PyPI and the fhe-oracle-oss repository are licensed under the GNU Affero General Public License v3.0. Use freely in open-source projects, academic research, and internal CI pipelines. If you run it as a network service, AGPL §13 copyleft applies to your deployment.
If AGPL's copyleft is incompatible with your deployment, get in touch — commercial / OEM licensing is handled case-by-case.
FHE Oracle ships as an AGPL-3.0 open-source package on PyPI — fully functional for CI testing, research, and internal deployments.
Self-host. Run in your own CI. Patch and fork, subject to AGPL-3.0. Community support via GitHub issues.
AutoOracle with full regime classifierCipherExplain is VaultBytes' encrypted SHAP suite — homomorphic SHAP explanations, EU AI Act audit reports, hosted API. Sister product to FHE Oracle; different problem space.
Bug reports and feature requests on GitHub. Research collaboration and licensing enquiries by email.
FHE Oracle is maintained by VaultBytes — b@vaultbytes.com.