FHE Oracle
Adversarial precision testing for Fully Homomorphic Encryption. Finds CKKS bugs that random testing misses.
Install
pip install fhe-oracle
Optional adapters:
pip install "fhe-oracle[tenseal]" # CKKS via TenSEAL
pip install "fhe-oracle[openfhe]" # CKKS / BGV / BFV via OpenFHE (Linux)
pip install "fhe-oracle[concrete]" # TFHE via Concrete ML
30-second example
import numpy as np
from fhe_oracle import FHEOracle
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 (a CKKS depth-noise pattern),
# with a hot zone that inflates the 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
oracle = FHEOracle(
plaintext_fn=plaintext_fn,
fhe_fn=fhe_fn,
input_dim=4,
input_bounds=[(-3.0, 3.0)] * 4,
seed=0,
)
result = oracle.run(n_trials=300, threshold=1e-3)
print(result.verdict) # "FAIL"
print(result.max_error) # ~3.6e-2
print(result.worst_input) # ~[3.0, 3.0, 3.0, -3.0]
Output:
OracleResult(verdict='FAIL', max_error=3.593336e-02, trials=304, elapsed=0.05s)
Swap the fixture for a real fhe_fn (e.g. concrete-ml's
predict_proba(x, fhe="execute")) and the oracle will search
adversarially for inputs that break precision.
Why this exists
FHE precision bugs are input-localised. A CKKS circuit that passes on 99,999 random inputs in a row can return garbage on the 100,000th. 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 — and those regions are vanishingly unlikely to be hit by uniform random sampling.
Random testing wastes evaluations in safe parts of the input space. An adversarial optimiser (CMA-ES, guided by a noise-budget-aware fitness function) spends its budget climbing toward the failure region instead, and finds bugs orders of magnitude larger than random sampling in the same wall-clock budget.
The reference logistic-regression example illustrates a polynomial
approximation defect in a synthetic CKKS-like circuit. Random testing
uses the operational range [-0.3, 0.3]^5; the oracle searches
[-5, 5]^5. Its large error ratio reflects both the different domains
and the search methods, and is not a matched comparison or speedup.
Reproduce this illustration with:
pip install cma numpy
python benchmarks/sigmoid_defect_benchmark.py --seed 42
How it works
- CMA-ES search over the input domain, guided by plaintext/FHE output divergence by default, with optional custom fitness plugins.
- Adapters for OpenFHE, Concrete ML, and TenSEAL connect supported circuits to divergence search. Optional plugins can supply additional fitness functions. Synthetic checks can run without native FHE libraries.
- Output: PASS/FAIL verdict, worst input, sensitivity map, and a structured JSON/Markdown report for artefact upload.
Benchmarks
See benchmarks/ for reproducible circuits. Historical results below are recorded in the 20-seed summary. They are not a fresh validation of v0.6.0. Ratios measure the maximum error discovered, not runtime or number of bugs found.
| Real TenSEAL circuit / setting | Seeds | Median oracle/random max-error ratio | Oracle wins |
|---|---|---|---|
LR, matched (lr_matched, B=60) |
20 | 2.04× | 15/20 |
| Depth-4 polynomial, matched | 20 | 1.41× | 16/20 |
Chebyshev, matched (cheb_matched, B=60) |
20 | 0.38× | 3/20 |
Results depend on circuit, domain, parameters and strategy. The synthetic reference's historical 4,259× ratio compares different domains and is excluded from this matched-results table. Approximation error between an intended model and its polynomial surrogate must be distinguished from the error introduced by encrypted execution of that surrogate.
For a customer evaluation, pin backend versions, use the same input domain and tolerance for each method, count all model evaluations, and compare both equal evaluation budgets and equal wall-clock budgets across seeds.
Verdicts and evaluation errors
PASS means no threshold violation was observed during the specified
search; it is not proof of correctness, cryptographic security or
regulatory compliance. Coverage confidence is conditional on the
caller-supplied minimum failure-region measure.
Invalid evaluations abort the run instead of producing a PASS. The built-in
precision comparisons reject backend exceptions, non-finite values, empty
outputs and mismatched output shapes. Scalars and one-element vectors
are compatible; higher-dimensional shapes must match. EvaluationError
is exported for callers to catch. Custom fitness implementations must
propagate backend failures and return finite scores.
The CLI exits 0 for PASS, 1 for a measured precision FAIL and 2 for a model, configuration or evaluation error. In CI, treat every nonzero exit as a blocked check. Some backend/property callbacks may propagate their original exception; they never imply a successful check.
Supported integrations
Core includes pure divergence search. Noise-budget fitness and named heuristic implementations require separately installed plugins; supplying an adapter alone does not install them. Broken plugin entry points emit warnings and fall back to available Core functionality.
TenSEAL, OpenFHE and Concrete are optional integrations with backend-specific requirements. The Lattigo module is a restricted subprocess precision probe, not a general Core adapter, and its Go binary must be built separately. The package remains Alpha while backend/version validation expands.
CI/CD integration
Drop oracle_check.py at your repo root:
import os
from fhe_oracle import FHEOracle
from my_model import plaintext_fn, fhe_fn
oracle = FHEOracle(
plaintext_fn=plaintext_fn,
fhe_fn=fhe_fn,
input_dim=10,
input_bounds=[(-3.0, 3.0)] * 10,
)
result = oracle.run(
n_trials=int(os.environ.get("ORACLE_N_TRIALS", "500")),
threshold=float(os.environ.get("ORACLE_THRESHOLD", "0.01")),
)
print(result)
raise SystemExit(0 if result.verdict == "PASS" else 1)
Add .github/workflows/fhe-precision.yml:
name: 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.11" }
- run: pip install fhe-oracle
- run: python oracle_check.py
env:
ORACLE_THRESHOLD: "0.01"
ORACLE_N_TRIALS: "500"
Full template: examples/github_action.yml.
Features (v0.6)
- One-call check —
check(plaintext_fn, fhe_fn, input_bounds)runsAutoOracleand, on FAIL, automatically shrinks the witness and localizes the fault (if the circuit supports tracing), returning aCheckResultwith a ready-to-print report. Replaces the run → check-verdict → shrink → trace → render sequence with one call. - CLI —
fhe-oracle check model.pyruns the same flow against a Python file definingplaintext_fn/fhe_fn/input_boundsat module level (optionallyn_trials/threshold/seedtoo, overridable via--n-trials/--threshold/--seed/--format/--no-shrink). Exits 0 on PASS, 1 on FAIL, 2 on a model, configuration or evaluation error. - Witness shrinking —
FHEOracle.shrink(result)reduces a FAIL witness toward a reference point (default: box centre) via per-coordinate binary search, while divergence keeps meeting the original threshold. Returns aShrinkResultwith the minimised input and the shrink ratio achieved. - Fault localization —
localize_fault(trace)reads aper_op_trace()result and returns theOperationStepmost likely responsible for the divergence, using the already-decrypted per-step values (no perturbation/guessing required). - Circuit structure diagnostic —
characterize_structure(fn, dim, bounds)estimates whether a target function has exploitable low-rank structure before you reach forseparable=Trueor aSubspaceOraclesubspace_dim. Returns aStructureReportwith aneffective_rankestimate and a plain-English recommendation. - Structure-aware
AutoOraclerouting — a newLOW_RANK_STRUCTUREregime measures the divergence surface's actual rank viacharacterize_structureand dispatches toseparable=TrueCMA-ES only when real low-rank structure is found (dimension alone is not used, avoiding the earlierd>100heuristic's regression on isotropic circuits). - Multi-library differential testing —
differential_test(adapter_a, adapter_b, input_dim, ...)searches for inputs where two FHE adapters' decrypted outputs disagree, using onlyencrypt/decrypt(no noise-budget API, no reference plaintext function needed). - Property-based fitness functions —
AdditivityFitnessandScalarLinearityFitnesssearch for algebraic-property violations (f(a+b) != f(a)+f(b),f(c*x) != c*f(x)) as drop-inFHEOraclefitness objects. - CI diagnostics —
report.to_markdown/to_jsonaccept an optionaldiagnosticsdict, rendered under a## Diagnosticssection on FAIL.examples/oracle_check.pyis a real, runnable CI script demonstrating the full shrink-and-report flow. - Adapter-agnostic tracing —
TracingCircuitgeneralisesTracingTenSEALFn's per-operation tracing pattern to anyFHEAdapterfor a declared sequence of named steps.
Features (v0.5)
- Cross-library benchmark harness —
benchmarks/library_comparison.pydrives the same(w·x+b)²circuit through every installed adapter and emits a single CSV per family (CKKS / integer). sigma0=Noneauto-scale +DISTANT_DEFECTregime inAutoOracle— handles landscapes where the failure region sits outside the initial search ball.
Features (v0.4)
- Periodic diversity injection —
FHEOracle(..., diversity_injection=True, inject_every=5, inject_count=3)injects diverse candidates (corner / uniform / best-neighbour) into the CMA-ES population every N generations, preventing the covariance collapse that strands vanilla CMA-ES on plateau landscapes. Seefhe_oracle.diversity.DiversityInjector. - Adaptive budget allocation —
FHEOracle(..., adaptive=True)enables three behaviours simultaneously: early stop on a definitive FAIL, auto-extension when divergence is still climbing at budget exhaustion, and strategy-switch to uniform random when CMA-ES's step size collapses on a plateau. Configure viaAdaptiveConfig. - Multi-output rank-aware fitness —
FHEOracle(..., multi_output=True, multi_output_mode="combined")wraps the user's vector-valued plaintext/FHE pair in aMultiOutputFitnessthat targets decision-altering precision failures (argmax flips, near-margin inputs) on top of max-absolute error. UseMultiOutputFitness.detailed_report(x)to inspect a witness. - All three default OFF — backward-compatible with v0.3.x.
Opt in per-call or via
AutoOracle(..., adaptive=True, diversity_injection=True)(kwargs are forwarded to the innerFHEOracle).
Features (v0.3)
- Auto-configuration probe —
AutoOracle(...)runs a 50-eval probe to classify the divergence landscape (FULL_DOMAIN_SATURATION,PLATEAU_THEN_CLIFF,PREACTIVATION_DOMINATED,STANDARD) and dispatches to the best search strategy automatically. No prior paper reading required. - Random subspace embedding (experimental) —
SubspaceOracle(...)projectsd >> 100inputs intok-dim random subspaces and searches with CMA-ES. Currently benefits only low-rank hidden-layer quantisation bugs; for dense directional / corner-region bugs preferPreactivationOracle(whenW, bare available) or uniform random sampling. - Pure-divergence defaults —
w_noiseandw_depthnow defaulted to0.0in v0.3 (paper §6.15 empirical evidence). Those arguments were removed in v0.5.1; current Core uses divergence fitness and optional plugin providers.
Features (v0.2)
- Pure-divergence mode — CI-friendly, no FHE library required.
- Hybrid random + CMA-ES with warm-start —
random_floor=0.3onFHEOraclereserves a fraction of the budget for uniform sampling, then warm-starts CMA-ES at the best random point. - IPOP / BIPOP restarts —
restarts=N, bipop=TrueonFHEOraclefor multi-basin landscapes. - Separable CMA-ES —
separable=Truefor axis-aligned landscapes (high-dim settings). - Union verdict (oracle + empirical) —
run_hybrid(...)returns aHybridResult; PASS iff both the adversarial and training-distribution legs pass. - Coverage certificate — the random-floor phase produces a
CoverageCertificateattached toOracleResult; pair withbudget_for(eta, p)orpass_confidence(eta)for a probabilistic PASS statement. - Preactivation search —
PreactivationOracle(W, b, ...)searches in preactivation z-space, collapsing d=784 affine front-ends to a rank-k subproblem. - Cascade (multi-fidelity) search —
CascadeSearch(...)runs cheap-fidelity search then re-scores the top-K under an expensive fidelity. - Per-operation trace diagnostic —
per_op_trace(x, plain, fhe)andTracingTenSEALFnlocalise where error accumulates in a CKKS circuit. - TenSEAL adapter —
pip install fhe-oracle[tenseal]enables noise-guided search on CKKS.
Licensing
AGPL-3.0-or-later. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fhe_oracle-0.6.0.tar.gz.
File metadata
- Download URL: fhe_oracle-0.6.0.tar.gz
- Upload date:
- Size: 123.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87de2cfd63834eb56dfc48510cdaecf11582ac03dddedef5254b50a2a7f0409a
|
|
| MD5 |
2c3a30687cb86df2a7e6862605230205
|
|
| BLAKE2b-256 |
853f818610b4be13aece1460eaf3b02d28ff390f652bb6a3a4d5983c3316a5f6
|
Provenance
The following attestation bundles were made for fhe_oracle-0.6.0.tar.gz:
Publisher:
release.yml on BAder82t/fhe-oracle-oss
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fhe_oracle-0.6.0.tar.gz -
Subject digest:
87de2cfd63834eb56dfc48510cdaecf11582ac03dddedef5254b50a2a7f0409a - Sigstore transparency entry: 2835016145
- Sigstore integration time:
-
Permalink:
BAder82t/fhe-oracle-oss@e9b611723ace5f9c7ef2ef36ef7ae063bff37808 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/BAder82t
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e9b611723ace5f9c7ef2ef36ef7ae063bff37808 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fhe_oracle-0.6.0-py3-none-any.whl.
File metadata
- Download URL: fhe_oracle-0.6.0-py3-none-any.whl
- Upload date:
- Size: 95.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1e467a9a47fd98ac17731cdd72113b465f217a125629c4c6342b2c81c277d1d
|
|
| MD5 |
a3379d35a5080879b098b9615b065325
|
|
| BLAKE2b-256 |
ad8d956fd9370cb95b83b9ed72ec5f99e0f50272ddaff054da03d3e5c0cd216b
|
Provenance
The following attestation bundles were made for fhe_oracle-0.6.0-py3-none-any.whl:
Publisher:
release.yml on BAder82t/fhe-oracle-oss
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fhe_oracle-0.6.0-py3-none-any.whl -
Subject digest:
e1e467a9a47fd98ac17731cdd72113b465f217a125629c4c6342b2c81c277d1d - Sigstore transparency entry: 2835016178
- Sigstore integration time:
-
Permalink:
BAder82t/fhe-oracle-oss@e9b611723ace5f9c7ef2ef36ef7ae063bff37808 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/BAder82t
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e9b611723ace5f9c7ef2ef36ef7ae063bff37808 -
Trigger Event:
push
-
Statement type: