Gentle Introduction to Homomorphic Encryption and CKKS
Series Overview
In this multipart series, we'll dive deep into CKKS. In this first part, we'll go through a short primer on Homomorphic Encryption and the CKKS Encryption Scheme. We'll defer the maths (as much as possible) to the later parts in this series, and instead try to build an intuition for things in this first part.
Introduction to Homomorphic Encryption
Homomorphic Encryption (HE) schemes allow computations to be performed directly on encrypted data, without ever needing to decrypt it. This is a departure from traditional cryptography schemes, where data must be decrypted before it can be processed. This allows for a moment of vulnerability that attackers can target.
Privacy-Preserving Applications
Homomorphic Encryption schemes have great implications for privacy and security of data. For example consider
- Medical Records: Sending sensitive medical records to a cloud server for machine learning inference
- Financial Analysis: Outsourcing financial data
analysis to an untrusted third party
- Data Processing: Performing computations on sensitive datasets
With standard encryption, your data must be exposed to compute on it. With HE, the server can run its computations blindly, never seeing your actual data.
What Makes CKKS Special?
CKKS is one example of a Homomorphic Encryption scheme.
It stands out in particular because it enables approximate arithmetic on real and complex numbers. While other HE schemes (like BFV or BGV) work over exact integers, CKKS allows us to perform operations on vectors of complex values.
Homomorphic Encryption Fundamentals
Core Components
At its core, an encryption scheme consists of three fundamental algorithms:
1. Key Generation
\[ (\mathsf{pk}, \mathsf{sk}) \;\leftarrow\; \mathsf{KeyGen}(1^\lambda) \]
Generates a public key \(\mathsf{pk}\) and a secret key \(\mathsf{sk}\) based on a security parameter \(\lambda\).
2. Encryption
\[ c \;\leftarrow\; \mathsf{Enc}(\mathsf{pk}, m) \]
Encrypts a message \(m\) into a ciphertext \(c\) using the public key.
3. Decryption
\[ m \;\leftarrow\; \mathsf{Dec}(\mathsf{sk}, c) \]
Recovers the original message \(m\) from the ciphertext using the secret key.
The Homomorphic Property
A scheme is said to be homomorphic if it supports an additional evaluation algorithm:
\[ \mathsf{Eval}(\mathsf{pk}, f, c_1, \dots, c_t) \]
such that, for some function \(f\) and messages \(m_1, \dots, m_t\):
\[ \mathsf{Dec}\Big(\mathsf{sk}, \mathsf{Eval}\big(\mathsf{pk}, f, \mathsf{Enc}(\mathsf{pk}, m_1), \dots, \mathsf{Enc}(\mathsf{pk}, m_t)\big)\Big) \;\approx\; f(m_1, \dots, m_t) \]
Note: There are a couple of problems with this definition. For a more exact definition, see Craig Thesis.
The important insight is that
You can perform computations directly on encrypted data, and when you decrypt the result, you get (approximately) the same output as if you had computed on the plaintexts.
An interesting point to note is that everytime we perform a computation on the encrypted data, we increase the noise level of the encrypted data. If we perform too many operations, the noise level increases to the point that we can no longer decrypt the data to get our message back. This forms the basis for classification of Homomorphic Encryption Schemes.
Classification of Homomorphic Encryption Schemes
Homomorphic encryption schemes can be classified based on what operations you can perform on the encrypted data (which are valid under the homomorphic property) and the number of times you can perform this operation before the noise renders decryption meaningless.
Partially Homomorphic Encryption (PHE)
These schemes support only one type of operation (either addition or multiplication) with no practical limit on the number of operations.
- RSA: Supports unlimited multiplications
- ElGamal: Supports unlimited multiplications
- Paillier: Supports unlimited additions
Somewhat Homomorphic Encryption (SHE)
These schemes support both addition and multiplication operations, but only for a limited number of operations before noise accumulation makes decryption impossible.
- BGV: Supports both addition and multiplication, but limited depth
Fully Homomorphic Encryption (FHE)
FHE schemes support both addition and multiplication and can perform an unlimited number of computations by using a technique called bootstrapping to refresh ciphertexts and reduce noise accumulation.
- Bootstrapped CKKS: Unlimited operations through bootstrapping
- TFHE: Fast bootstrapping for boolean circuits
Key Distinctions
Scheme Type | Operations | Depth Limit | Plaintext Type |
---|---|---|---|
BGV/BFV | +, × | Limited (SHE) | Integers |
CKKS | +, × | Unlimited (FHE) | Real/Complex |
Paillier | + only | Unlimited | Integers |
RSA | × only | Unlimited | Integers |
CKKS Introduction
CKKS is a fully homomorphic encryption scheme designed for approximate arithmetic on complex numbers. It allows operations on a vector of floating point numbers which makes it ideal for applications in machine learning etc
Polynomial Rings
A polynomial ring is a set of polynomials with coefficients from a given ring (like integers, \(\mathbb{Z}\)) where we can perform addition and multiplication.
Formally, the ring of polynomials with integer coefficients is written as:
\[ \mathbb{Z}[x] = \{ a_0 + a_1 x + a_2 x^2 + \dots + a_n x^n \mid a_i \in \mathbb{Z}, \; n \ge 0 \} \]
- Addition: Coefficients of like powers of \(x\) are added.
- Multiplication: Polynomials are multiplied using distributive law.
Quotient Polynomial Ring
A quotient polynomial ring modulo a polynomial \(f(x)\) is written as:
\[ R = \mathbb{Z}[x] / (f(x)) \]
Here, two polynomials are considered equivalent if their difference is a multiple of \(f(x)\):
\[ p(x) \equiv q(x) \pmod{f(x)} \iff p(x) - q(x) \text{ is divisible by } f(x) \]
Think of this like the modular arithmetic equivalent for polynomials.
Just as \(17 \equiv 2 \pmod{5}\), in \(R\) we might have: \[ x^N \equiv -1 \pmod{x^N+1}. \]
Example: In CKKS, we use
\[ R_q = \mathbb{Z}_q[x]/(x^N + 1) \]
where coefficients are integers modulo \(q\) (set of integers modulo q is the ring), and \(x^N + 1\) defines the equivalence relation.
Message/Plaintext Space
Suppose we have a vector of \(n\) messages. CKKS does not directly operate on this vector of complex numbers. Instead, it maps a vector
\[ \mathbf{m} = (m_1, m_2, \dots, m_{n}) \in \mathbb{C}^{n} \]
into a polynomial in the plaintext space (quotient polynomial ring) via the encoding algorithm:
\[ \text{Encode}_\Delta: \mathbb{C}^n \;\longrightarrow\; R_q = \mathbb{Z}_q[x]/(x^N + 1) \]
\((R_q)\) is known as the \(2(N)\)-th cyclotomic ring modulo \((q)\).
If the polynomial modulus degree is \(N\), the scheme actually supports encoding vectors of size:
\[ \mathbf{m} = (m_1, m_2, \dots, m_{N/2}) \in \mathbb{C}^{N/2}. \]
This is because the canonical embedding (more on this in the next part) of the ring \(R = \mathbb{Z}[x]/(x^N+1)\) into \(\mathbb{C}^N\) has conjugate symmetry, leaving only \(N/2\) independent slots.
So the idea is that we take a vector of complex/real numbers that each
represent a message, and then encode them into ONE
polynomial. This means whenever we operate on this polynomial, we are
effectively operating on all the original complex/real numbers that were
part of the vector.
This gives rise to the SIMD like property of CKKS.
Encryption / Decryption
The encryption algorithm maps the encoded polynomial into a ciphertext (pair of polynomials):
\[ \text{Enc}: R_\Delta \;\longrightarrow\; \text{Ciphertext } (c_0(x), c_1(x)) \in R_q \times R_q \]
The decryption algorithm maps a ciphertext back into the encoded polynomial:
\[ \text{Dec}: (c_0(x), c_1(x)) \;\longrightarrow\; m(x) \in R_\Delta \]
Finally, the decoding algorithm maps the polynomial back to an approximate vector of complex numbers:
\[ \text{Decode}_\Delta: R_\Delta \;\longrightarrow\; \mathbf{\tilde{m}} \in \mathbb{C}^n, \quad \mathbf{\tilde{m}} \approx \mathbf{m} \]
So encryption of one polynomial generates a pair of polynomials which
together form the ciphertext. This is the encrypted form of our original
message vector. We can now perform operations on two ciphertexts (such
as addition of two ciphertexts, multiplication of two ciphertexts), and
then decrypt the resulting ciphertext to get a plaintext polynomial
back. Note that we are yet to obtain our vector of complex/real numbers
back, this is done by Decoding the plaintext polynomial
which will convert it to a vector of complex numbers.
Summary of Algorithm Mappings
Algorithm | Input Space | Output Space |
---|---|---|
Encode | \(\mathbb{C}^n\) | \(R_\Delta \subset R_q\) |
Encrypt | \(R_\Delta\) | \(R_q \times R_q\) (ciphertext) |
Decrypt | \(R_q \times R_q\) | \(R_\Delta\) |
Decode | \(R_\Delta\) | \(\mathbb{C}^n\) (approximate) |
Special SIMD Property of CKKS
One of the powerful features of CKKS is that it can pack a whole vector of complex numbers into a single polynomial.
- Suppose we have a vector of messages:
\[ \mathbf{m} = (m_1, m_2, \dots, m_n) \in \mathbb{C}^n \]
- After encoding, all these values are embedded into one polynomial:
\[ m(x) \in R_\Delta \subset R_q \]
- The magic is that any homomorphic operation on (m(x)) , like addition or multiplication, is applied simultaneously to all the packed values.
This is similar to SIMD (Single Instruction, Multiple Data) in classical computing: a single operation is performed on multiple pieces of data at once.
In other words: CKKS allows us to treat the polynomial as a container of multiple messages and perform computations on the whole vector in parallel, all in the encrypted domain.
Why Isn’t Homomorphic Encryption Everywhere?
It does sound amazing to be able to compute directly on encrypted
data without ever decrypting it.
So why isn’t Homomorphic Encryption (HE) used everywhere yet?
There are a few important reasons:
1. Computational Overhead
- HE schemes are still orders of magnitude slower than
plaintext computation.
- For example, a simple multiplication between two ciphertexts can be up
to 100× slower than multiplying two integers.
- Ciphertexts are also much larger than plaintexts, and intermediate
results (especially after multiplications) can balloon in size,
consuming significant memory.
2. Limited Support for Non-Polynomial
Functions
- HE schemes natively operate over polynomial
rings.
- This makes it challenging to evaluate non-polynomial functions such as
sigmoid or ReLU (common in machine
learning).
- We can try to approximate such functions using polynomials but these
can reduce accuracy.
3. Noise Growth
- Each homomorphic operation increases the noise in a
ciphertext.
- Once the noise exceeds a threshold, decryption fails. This effectively
means we can only perform a fixed number of operations. If we exceed
this number, we lose the original message permanently. - Bootstrapping
can refresh ciphertexts (resetting the noise), but this step is
extremely costly in practice.
4. Deployment Challenges
- HE requires specialized cryptographic libraries and expertise.
- Integrating it into existing pipelines (databases, ML frameworks,
etc.) is still non-trivial compared to standard encryption.
Wrapping up
We will conclude part one of this series here. I hope this introduction to Homomorphic Encryption and CKKS was enough to pique your curiosity. In the next part of the series, we will dive deeper into the maths - starting with the canonical embedding and how they are used to perform the encoding/decoding step.
PS – I am still a novice in this almost mystical world of Homomorphic Encryption. If you spot any mistakes or if you'd like to discuss anything further, I’d greatly appreciate it if you reach out to me via X
References
Craig Thesis on Homomorphic Encryption
The original CKKS Paper - Homomorphic Encryption for Arithmetic of Approximate Numbers