This repository implements a privacy-preserving client-server architecture for handwritten digit classification using the CKKS Fully Homomorphic Encryption (FHE) scheme. By ensuring end-to-end encryption, sensitive data (e.g., MNIST digits) remains fully encrypted during inference—even on untrusted servers—preventing exposure of raw inputs or results.
- Encryption:
- Encrypts input (e.g., digit image "5") using CKKS.
- Send to Server:
- Transmits encrypted data for inference.
- Decryption:
- Decrypts encrypted class probabilities returned by the server.
- FHE-Compatible Inference:
- Processes encrypted data through a convolutional neural network (CNN).
- Return Encrypted Results:
- Sends encrypted class probabilities back to the client.
- Client: Holds private key; raw data never exposed.
- Server: Operates only on ciphertexts; cannot infer inputs/outputs.
- This enables secure AI in sensitive domains (e.g., healthcare, finance) by ensuring data privacy during inference.
- Speed: FHE computations are slower than plaintext.
- Precision: Approximate arithmetic may reduce model accuracy.
- Activation Limitations: Polynomials approximate non-linear functions imperfectly.
CKKS (Cheon-Kim-Kim-Song) is a homomorphic encryption scheme that enables approximate arithmetic (addition/multiplication) on encrypted data. It’s ideal for privacy-preserving machine learning and secure data analysis.
-
Input: Vector of real numbers
$[z_1, z_2, ..., z_n]$ . -
Scaling: Multiply by
$\Delta$ (e.g.,$\Delta = 2^{40}$ ) to preserve precision:
-
Canonical Embedding: Map the scaled vector to a polynomial in the ring
$R = \mathbb{Z}[x]/(x^N + 1)$ :
where
-
Public Key:
$pk = (b, a)$ , where$b = -a \cdot sk + e \ (\text{mod}\ q)$ . -
Encrypt
$m(x)$ into ciphertext$ct = (c_0, c_1)$ :
where
- Compute tensor product:
-
Relinearize using
$rlk$ to compress back to 2 components.
- Use Galois keys to rotate encoded slots (e.g., shift
$[z_1, z_2, z_3]$ →$[z_3, z_1, z_2]$ ).
-
Secret Key:
$sk$ (small random polynomial). - Recover the (noisy) polynomial:
- Apply canonical embedding:
- Descale:
import tenseal as ts
context = ts.context(
ts.SCHEME_TYPE.CKKS,
poly_modulus_degree=8192, # Polynomial modulus degree (N)
coeff_mod_bit_sizes=[60, 40, 40, 60] # Coefficient modulus bit sizes
)It defines the degree of the polynomial ring
-
Slot Capacity: Encodes
$N/2$ numbers in parallel (e.g.,$N=8192$ → 4096 slots). -
Typical Values:
-
$N=4096$ : ~128-bit security (lightweight). -
$N=8192$ : ~192-bit security (recommended for most use cases). -
$N=16384$ : Higher security (slow, for critical applications).
-
It specifies the bit sizes of primes in the coefficient modulus chain
-
First Prime (
$q_1$ ): Sets the scaling factor$\Delta \approx 2^{q_1}$ (e.g.,$60$ →$\Delta \approx 2^{60}$ ). -
Middle Primes (
$q_2, q_3, ...$ ): Manage noise growth during multiplications. -
Last Prime (
$q_L$ ): Final modulus to control residual noise. -
Multiplicative Depth:
- Chain length
$L$ determines how many multiplications are allowed. - Example:
[60, 40, 40, 60]→$L=4$ primes → supports 3 multiplications (before noise overwhelms the message).
- Chain length
-
Note: Total bit size of
$Q$ (sum ofcoeff_mod_bit_sizes) must align withpoly_modulus_degreefor security.
| Key | Purpose | Mathematical Role ` |
|---|---|---|
|
Secret Key ( |
Decrypt ciphertexts | Small polynomial in |
|
Public Key ( |
Encrypt data | Pair |
|
Relinearization Key ( |
Compress ciphertexts after multiplication | Encodes |
|
Galois Key ( |
Rotate slots or permute data | Encodes automorphisms of |
