Skip to main content

Adversarial precision testing for FHE programs

Project description

FHE Oracle

License: AGPL v3

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.

On the reference logistic-regression benchmark in this repo (a CKKS circuit with a polynomial sigmoid approximation defect), the oracle finds divergence 4,259× larger than random sampling at an equal 500-evaluation budget. Reproduce 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 a noise-aware fitness that combines plaintext/FHE divergence with ciphertext noise-budget consumption and multiplicative-depth utilisation.
  • Adapters for OpenFHE, Concrete ML, and TenSEAL turn on noise-guided search. A pure divergence fallback works without any native FHE library — useful for CI.
  • Output: PASS/FAIL verdict, worst input, sensitivity map, and a structured JSON/Markdown report for artefact upload.

Benchmarks

See benchmarks/ for reproducible circuits. Numbers below are from live runs on this repo (500-evaluation budget, deterministic seed 42):

Circuit Dim Random max error Oracle max error Ratio
Logistic regression (reference) 5 3.5e-4 1.50 4,259×
Logistic regression (input-amplified mock) 8 2.7e-1 6.8e-1 2.5×
Polynomial (depth 4) 6 1.7e-2 1.9e-2 1.1×
Dense + Chebyshev sigmoid 10 1.0e-1

Pure-Python divergence-only benchmarks run in under one second on a 2020-era laptop. Library-comparison benchmarks (TenSEAL / OpenFHE / Pyfhel) take 15–45 s/seed; reach the unified-circuit numbers via benchmarks/library_comparison.py.

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.5)

  • Cross-library benchmark harnessbenchmarks/library_comparison.py drives the same (w·x+b)² circuit through every installed adapter and emits a single CSV per family (CKKS / integer).
  • sigma0=None auto-scale + DISTANT_DEFECT regime in AutoOracle — handles landscapes where the failure region sits outside the initial search ball.

Features (v0.4)

  • Periodic diversity injectionFHEOracle(..., 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. See fhe_oracle.diversity.DiversityInjector.
  • Adaptive budget allocationFHEOracle(..., 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 via AdaptiveConfig.
  • Multi-output rank-aware fitnessFHEOracle(..., multi_output=True, multi_output_mode="combined") wraps the user's vector-valued plaintext/FHE pair in a MultiOutputFitness that targets decision-altering precision failures (argmax flips, near-margin inputs) on top of max-absolute error. Use MultiOutputFitness.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 inner FHEOracle).

Features (v0.3)

  • Auto-configuration probeAutoOracle(...) 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(...) projects d >> 100 inputs into k-dim random subspaces and searches with CMA-ES. Currently benefits only low-rank hidden-layer quantisation bugs; for dense directional / corner-region bugs prefer PreactivationOracle (when W, b are available) or uniform random sampling. See research/release/v030-benchmark-report.md for the evaluation.
  • Pure-divergence defaultsw_noise and w_depth now default to 0.0 (paper §6.15 empirical evidence); pass w_noise=0.5, w_depth=0.3 to restore v0.2 shaping behaviour.

Features (v0.2)

  • Pure-divergence mode — CI-friendly, no FHE library required.
  • Hybrid random + CMA-ES with warm-startrandom_floor=0.3 on FHEOracle reserves a fraction of the budget for uniform sampling, then warm-starts CMA-ES at the best random point.
  • IPOP / BIPOP restartsrestarts=N, bipop=True on FHEOracle for multi-basin landscapes.
  • Separable CMA-ESseparable=True for axis-aligned landscapes (high-dim settings).
  • Union verdict (oracle + empirical)run_hybrid(...) returns a HybridResult; PASS iff both the adversarial and training-distribution legs pass.
  • Coverage certificate — the random-floor phase produces a CoverageCertificate attached to OracleResult; pair with budget_for(eta, p) or pass_confidence(eta) for a probabilistic PASS statement.
  • Preactivation searchPreactivationOracle(W, b, ...) searches in preactivation z-space, collapsing d=784 affine front-ends to a rank-k subproblem.
  • Cascade (multi-fidelity) searchCascadeSearch(...) runs cheap-fidelity search then re-scores the top-K under an expensive fidelity.
  • Per-operation trace diagnosticper_op_trace(x, plain, fhe) and TracingTenSEALFn localise where error accumulates in a CKKS circuit.
  • TenSEAL adapterpip install fhe-oracle[tenseal] enables noise-guided search on CKKS.

Licensing

AGPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fhe_oracle-0.5.2.tar.gz (99.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fhe_oracle-0.5.2-py3-none-any.whl (80.6 kB view details)

Uploaded Python 3

File details

Details for the file fhe_oracle-0.5.2.tar.gz.

File metadata

  • Download URL: fhe_oracle-0.5.2.tar.gz
  • Upload date:
  • Size: 99.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fhe_oracle-0.5.2.tar.gz
Algorithm Hash digest
SHA256 7137333c8a6d24d3e52d48997cf8b2e99b116e4dc1fa722ae97a9387074ada28
MD5 076b0f93fc09a62c76cb6b098d58f8f2
BLAKE2b-256 38ce2da33bd2a12e980963216c5887dd457cd6570aa7f9710fec104e5c07c7d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for fhe_oracle-0.5.2.tar.gz:

Publisher: release.yml on BAder82t/fhe-oracle-oss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fhe_oracle-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: fhe_oracle-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 80.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fhe_oracle-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d566e965d2862c77a6f3cde8afdaf000ee007a46de9e1f21f0ca47aafef79971
MD5 833ef5ef718d2db70a724c4745967cb2
BLAKE2b-256 5026cab4509e0ebf6b710d79e40ab4015e8b64ab351d411524f0ad74800d2d2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for fhe_oracle-0.5.2-py3-none-any.whl:

Publisher: release.yml on BAder82t/fhe-oracle-oss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page