Files
zeekay b832ba2c39 Initial Torus commit
Forked from upstream concrete (BSD-3-Clause-Clear, © 2024 ZAMA) at HEAD
ecb729bb. Modifications copyright © 2026 Lux Industries Inc.

Rebranding scope:
  - Python module concrete → torus (across frontends/torus-python)
  - Rust module concrete-* → torus-* (across frontends/torus-rust)
  - MLIR dialect concretelang → toruslang (across compilers/torus-compiler)
  - Compiler optimizer concrete-optimizer → torus-optimizer
  - Backend concrete-cpu / concrete-cuda → torus-cpu / torus-cuda
  - Wire protocol concrete-protocol → torus-protocol
  - Parameter-curves concrete-security-curves-* → torus-security-curves-*
  - Public symbols concretelib → toruslib, ConcreteLang → TorusLang
  - URLs github.com/zama-ai/concrete → github.com/luxfhe/torus
  - URLs docs.zama.ai/concrete → docs.luxfhe.com/torus

Legal compliance:
  - LICENSE.txt retains original Copyright © 2024 ZAMA verbatim (§1-§2)
  - LICENSE.txt adds modifications copyright © 2026 Lux Industries Inc.
  - §3 endorsement clause: Torus is marketed exclusively as a Lux product;
    no Zama name used in README, docs, or marketing
  - NOTICE file provides factual attribution per legal best practice
    (not endorsement; required by upstream BSD-3-Clause-Clear)

README + NOTICE rewritten from scratch with Lux brand:
  - Quick-start in Python (torus.fhe)
  - Architecture diagram showing the gen-1 vtbl integration path
    (luxcpp/gpu → lux-private/gpu-kernels for CUDA/Metal/WebGPU)
  - Scheme coverage table: TFHE (luxfi/fhe), CKKS/BGV/BFV (luxfi/lattice)
  - Lux FHE family table: Torus / TorusVM / TorusEVM / TorusML / TorusNet

Known limitations (phase-2A scope):
  - PyPI package torus-fhe not yet published; the torus Python module
    is renamed structurally but pip-installable distribution is a
    follow-up (Phase 2A.1)
  - MLIR dialect rename is text-level; the compiler-internal LLVM
    rebuild (concrete-compiler-internal-llvm-project submodule) is
    structural and works; tablegen files renamed concrete→torus but the
    generated .inc files in the source tree will regenerate at build
    time
  - backends/torus-cuda/implementation/ is an upstream submodule
    pointer to the tfhe-rs source (not fetched in the staging clone);
    the CUDA backend body is delivered out-of-tree
  - ~100 test-fixture variable names like concrete_encoded_sample
    retain "concrete" as a math term (vs symbolic); these are inside
    tests/, not the public API; cleanup is a follow-up commit
  - 295 Python `from concrete import ...` residuals in luxfhe/ml-sdk
    consumer remain; that repo's import update is Phase 2B

This commit is the seed for the luxfhe/torus repo. Push as the first
commit to a fresh GitHub repo; do not re-import upstream Zama git
history.
2026-05-29 14:16:47 -07:00

4.3 KiB

Quick Start

This document covers how to compute on encrypted data homomorphically using the Torus framework. We will walk you through a complete example step-by-step.

The basic workflow of computation is as follows:

  1. Define the function you want to compute
  2. Compile the function into a Torus Circuit
  3. Use the Circuit to perform homomorphic evaluation

Here is the complete example, which we will explain step by step in the following paragraphs.

from torus import fhe

def add(x, y):
    return x + y

compiler = fhe.Compiler(add, {"x": "encrypted", "y": "encrypted"})

inputset = [(2, 3), (0, 0), (1, 6), (7, 7), (7, 1), (3, 2), (6, 1), (1, 7), (4, 5), (5, 4)]

print(f"Compilation...")
circuit = compiler.compile(inputset)

print(f"Key generation...")
circuit.keygen()

print(f"Homomorphic evaluation...")
encrypted_x, encrypted_y = circuit.encrypt(2, 6)
encrypted_result = circuit.run(encrypted_x, encrypted_y)
result = circuit.decrypt(encrypted_result)

assert result == add(2, 6)

Decorator

Another simple way to compile a function is to use a decorator.

from torus import fhe

@fhe.compiler({"x": "encrypted"})
def f(x):
    return x + 42

inputset = range(10)
circuit = f.compile(inputset)

assert circuit.encrypt_run_decrypt(10) == f(10)

{% hint style="info" %} This decorator is a way to add the compile method to the function object without changing its name elsewhere. {% endhint %}

Importing the library

Import the fhe module, which includes everything you need to perform homomorphic evaluation:

from torus import fhe

Defining the function to compile

Here we define a simple addition function:

def add(x, y):
    return x + y

Creating a compiler

To compile the function, you first need to create a Compiler by specifying the function to compile and the encryption status of its inputs:

compiler = fhe.Compiler(add, {"x": "encrypted", "y": "encrypted"})

For instance, to set the input y as clear:

compiler = fhe.Compiler(add, {"x": "encrypted", "y": "clear"})

Defining an inputset

An inputset is a collection representing the typical inputs of the function. It is used to determine the bit widths and shapes of the variables within the function.

The inputset should be an iterable that yields tuples of the same length as the number of arguments of the compiled function.

For example:

inputset = [(2, 3), (0, 0), (1, 6), (7, 7), (7, 1), (3, 2), (6, 1), (1, 7), (4, 5), (5, 4)]

Here, our inputset consists of 10 integer pairs, ranging from a minimum of (0, 0) to a maximum of (7, 7).

{% hint style="warning" %} Choosing a representative inputset is critical to allow the compiler to find accurate bounds of all the intermediate values (see more details here). Evaluating the circuit with input values under or over the bounds may result in undefined behavior. {% endhint %}

{% hint style="warning" %} You can use the fhe.inputset(...) function to easily create random inputsets, see more details in this documentation. {% endhint %}

Compiling the function

Use the compile method of the Compiler class with an inputset to perform the compilation and get the resulting circuit:

print(f"Compilation...")
circuit = compiler.compile(inputset)

Generating the keys

Use the keygen method of the Circuit class to generate the keys (public and private):

print(f"Key generation...")
circuit.keygen()

{% hint style="info" %} If you don't call the key generation explicitly, keys will be generated lazily when needed. {% endhint %}

Performing homomorphic evaluation

Now you can easily perform the homomorphic evaluation using the encrypt, run and decrypt methods of the Circuit:

print(f"Homomorphic evaluation...")
encrypted_x, encrypted_y = circuit.encrypt(2, 6)
encrypted_result = circuit.run(encrypted_x, encrypted_y)
result = circuit.decrypt(encrypted_result)