Skip to content

Repository files navigation

Penumbra-FHE

Run encrypted inference on machine-learning models — without writing crypto code.

License: Apache 2.0 Status: pre-alpha


Export any supported model to ONNX, load it into Penumbra-FHE, and run inference directly on encrypted data using Fully Homomorphic Encryption (FHE). The server computes on ciphertext and never sees your input or output.

import penumbra as fhe

model = fhe.load_onnx("model.onnx")           # ONNX front door: parse + validate + lower to a Model
model.quantize(calibration_data, n_bits=6)   # float graph → int graph + lookup tables
pred = model.predict_encrypted(x)             # client encrypts → server evaluates → client decrypts

The ONNX front door, quantization service, and the encrypted round trip work today (Phases 5–6, plus the first Phase-9 slice). load_onnx parses an ONNX model, validates every op at load time (failing loudly with all problems at once if a model uses an unsupported op — validation is the compile step), and lowers it to an fhe.Model. predict_encrypted then runs the real encrypted forward pass (keygen → encrypt → evaluate → decrypt) via the Rust runtime and returns the client-side prediction — it needs a Rust toolchain (cargo) and takes seconds-to- minutes per sample. The current bridge shells out to the runtime; in-process PyO3 bindings and wheels are the remaining Phase-9 work. You can also assemble a model by hand from the op vocabulary — the same Model load_onnx produces:

import penumbra as fhe

model = fhe.Model([
    fhe.Conv2d(weight=w1, in_h=8, in_w=8, in_channels=1, stride=2),
    fhe.Activation(lambda v: max(v, 0.0)),   # ReLU, fused into the conv's requantization
    fhe.Linear(weight=w2, bias=b2),
])
model.quantize(calibration_data, n_bits=4)   # PTQ (or QAT) → int weights, scales, lookup tables
model.export("model.fhe")                     # serialize for the Rust runtime

Built directly on tfhe-rs (the TFHE scheme), it implements a small, fixed set of ML operations against TFHE primitives — no general-purpose FHE compiler involved.

How it works

Penumbra-FHE has a three-layer "narrow waist" architecture: a small, fixed set of ~8 operations that every model compiles down to, so the cryptography layer never changes as use cases multiply.

  • Python front end — load ONNX, quantize, lower to a serializable Intermediate Representation (IR).
  • Rust runtime (tfhe-rs) — read the IR and evaluate the op graph under encryption.

The golden invariant: TFHE is exact, so FHE output equals the quantized-cleartext output bit-for-bit. Any discrepancy is a bug, never crypto noise.

Project status

Pre-alpha — under active construction. This is research/prototype-grade software, not audited production cryptography. It targets small models (image classifiers, tabular models, small CNNs, tree ensembles); inference takes seconds, not milliseconds. "Any ONNX model" means: composed of supported ops, quantizes acceptably, and small enough to be practical.

Documentation

Quick start (development)

# Rust runtime (build in --release; debug FHE is very slow)
cd runtime && cargo test --release

# Python front end (managed with uv)
cd python && uv sync --all-extras && uv run pytest

See docs/DEVELOPMENT.md for full setup.

License

Apache 2.0.

About

Encrypted ML inference on ONNX models via TFHE - run quantized neural networks under fully homomorphic encryption, bit-exact to the cleartext result.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages