# XIV. Homomorphic Matrix-Vector Multiplication
[TOC]
## Introduction
This is the fourteenth chapter of [Understanding Homomorphic Encryption](https://hackmd.io/@spockwall/rJgV4qFgZe) series. Homomorphic Matrix-Vector Multiplication is an important building blocks for CKKS Bootstrapping. Applying homomorphic matrix-vector multiplication is equivalent to applying homomorphic linear transformation. See the next chapter how homomorphic linear transformation is used for Bootstrapping.
(*RNS representation is not used in this chapter for clarity.*)
## Homomorphic Matrix-Vector Multiplication under Plaintext Space
### Setup
Let's define a small problem with dimension $N/2 = 4$ (4 slots).
- **Input Vector $\vec z$:**
$$\vec z = [1, 2, 3, 4]$$
- **Matrix $A$:**
$$A = \begin{bmatrix}
1 & 2 & 3 & 4 \\
5 & 6 & 7 & 8 \\
9 & 10 & 11 & 12 \\
13 & 14 & 15 & 16
\end{bmatrix}$$
- **Goal:** Compute $A \cdot \vec z=[30, 70, 110, 150]$
---
### The Algorithm: Diagonal Method
In homomorphic encryption, we cannot access rows or columns arbitrarily. We can only perform **SIMD operations** (add/multiply whole vectors) and **Rotations**.
The formula used is:
$$A \cdot \vec z = \sum_{j=0}^{3} (u_j \odot \rho(\vec z, j))$$
Where:
* $u_j$ is the $j$-th **Extended Diagonal** of matrix $A$.
* $\rho(\vec z, j)$ is the vector $z$ **rotated left** by $j$.
* $\odot$ is component-wise multiplication.
---
### **Step 1: Precompute the Diagonals ($u_j$)**
We extract diagonals and wrap around when we hit the edge. The diagonal $j$:
$$u_j[i] = A_{i, (i+j) \pmod 4}$$
- Diagonal 0: $u_0=[A_{00}, A_{11}, A_{22}, A_{33}]=[1, 6, 11, 16]$
- Diagonal 1: $u_1=[A_{01}, A_{12}, A_{23}, A_{30}]=[2, 7, 12, 13]$
- Diagonal 2: $u_2=[A_{02}, A_{13}, A_{20}, A_{31}]=[3, 8, 9, 14]$
- Diagonal 3: $u_3=[A_{03}, A_{10}, A_{21}, A_{32}]=[4, 5, 10, 15]$
### **Step 2: Rotate the Vector ($z$)**
We generate 3 rotated versions of the ciphertext $z = [1, 2, 3, 4]$.
* $\rho(\vec z, 0) = [1, 2, 3, 4]$ (No rotation)
* $\rho(\vec z, 1) = [2, 3, 4, 1]$ (Rotate left by 1)
* $\rho(\vec z, 2) = [3, 4, 1, 2]$ (Rotate left by 2)
* $\rho(\vec z, 3) = [4, 1, 2, 3]$ (Rotate left by 3)
### **Step 3: Multiply and Accumulate**
Now we multiply each diagonal by the corresponding rotated vector and sum them up.
**1. Iteration $j=0$:**
$$
\begin{aligned}
\text{Term}_0 &= u_0 \odot \rho(\vec z, 0) \\
&= [1, 6, 11, 16] \times [1, 2, 3, 4] \\
&= [\mathbf{1}, \mathbf{12}, \mathbf{33}, \mathbf{64}]
\end{aligned}
$$
**2. Iteration $j=1$:**
$$
\begin{aligned}
\text{Term}_1 &= u_1 \odot \rho(z; 1) \\
&= [2, 7, 12, 13] \times [2, 3, 4, 1] \\
&= [\mathbf{4}, \mathbf{21}, \mathbf{48}, \mathbf{13}]
\end{aligned}
$$
**3. Iteration $j=2$:**
$$
\begin{aligned}
\text{Term}_2 &= u_2 \odot \rho(z; 2) \\
&= [3, 8, 9, 14] \times [3, 4, 1, 2] \\
&= [\mathbf{9}, \mathbf{32}, \mathbf{9}, \mathbf{28}]
\end{aligned}
$$
**4. Iteration $j=3$:**
$$
\begin{aligned}
\text{Term}_3 &= u_3 \odot \rho(z; 3) \\
&= [4, 5, 10, 15] \times [4, 1, 2, 3] \\
&= [\mathbf{16}, \mathbf{5}, \mathbf{20}, \mathbf{45}]
\end{aligned}
$$
### **Step 4: Final Summation**
Add the four resulting vectors together:
$$
\begin{bmatrix} 1 \\ 12 \\ 33 \\ 64 \end{bmatrix} +
\begin{bmatrix} 4 \\ 21 \\ 48 \\ 13 \end{bmatrix} +
\begin{bmatrix} 9 \\ 32 \\ 9 \\ 28 \end{bmatrix} +
\begin{bmatrix} 16 \\ 5 \\ 20 \\ 45 \end{bmatrix}
$$
**Calculation:**
* Slot 0: $1 + 4 + 9 + 16 = \mathbf{30}$
* Slot 1: $12 + 21 + 32 + 5 = \mathbf{70}$
* Slot 2: $33 + 48 + 9 + 20 = \mathbf{110}$
* Slot 3: $64 + 13 + 28 + 45 = \mathbf{150}$
Final Result $[30, 70, 110, 150]$ matches the expected result perfectly. This method is efficient because it processes all rows simultaneously using only simple SIMD multiplications and rotations.
## Homomorphic Matrix-Vector Multiplication under Ciphertext Space
The above shows Homomorphic Matrix-Vector Multiplication under plaintext space. However, in fhe scheme we cannot see any plaintext message. We explain the execution under ciphertext space below.
### **Setup (Ciphertext Space)**
- **Ring:** Polynomials modulo $X^N + 1$ (where $N=8$ for the 4-slot example).
- **Decryption Rule:** $\text{Message} \approx c_0(X) + c_1(X) \cdot s(X)$.
- **Input Vector:** $\vec z = [1, 2, 3, 4]$ and $m(X)$ encoding $\vec z$.
- **Input Ciphertext:** $ct = (c_0, c_1)$
---
### **Step 1: Ciphertext Rotation (The Most Complex Part)**
We need to create rotated copies of $ct_{in}$. This step is called [homomorphic rotation](https://hackmd.io/d7HeidPUQ12ig9mYtCWXEQ). Check the link to see how homomorphic rotation works. After rotation, we have ciphertexts $ct, ct_1, ct_2, ct_3$ encrypting messages that encode $\rho(\vec z, 0)=\vec z, \rho(\vec z, 1), \rho(\vec z, 2), \rho(\vec z, 3)$
---
### **Step 2: Encoding the Diagonals (Plaintext Space)**
Recall the plaintext diagonals (from the previous example):
- Diagonal 0: $u_0=[A_{00}, A_{11}, A_{22}, A_{33}]=[1, 6, 11, 16]$
- Diagonal 1: $u_1=[A_{01}, A_{12}, A_{23}, A_{30}]=[2, 7, 12, 13]$
- Diagonal 2: $u_2=[A_{02}, A_{13}, A_{20}, A_{31}]=[3, 8, 9, 14]$
- Diagonal 3: $u_3=[A_{03}, A_{10}, A_{21}, A_{32}]=[4, 5, 10, 15]$
We have to encode these Diagonal vector into polynomials before multiplying. The encoding algorithm is the same as [here](https://hackmd.io/d7HeidPUQ12ig9mYtCWXEQ#Step-1-The-Initial-State). After encoding, we have $U_0(X), U_1(X), U_2(X), U_3(X)$
* $U_i(X)$ is a polynomial where $U_i(\zeta^1)=u_{i,0}, U_i(\zeta^5)=u_{i,1}$, etc.
---
### **Step 3: Homomorphic Multiplication (Scalar Mult)**
Now we multiply the rotated ciphertexts by the encoded diagonals.
We perform this for each diagonal $j=0$ to $3$.
- Operation for $j=0$:
We take the unrotated ciphertext $ct = (c_0, c_1)$ and the encoded diagonal $U_0(X)$.
$$ct' = (c_0 \cdot U_0, \; c_1 \cdot U_0)$$ Now, $ct'$ encrypts $[1, 2, 3, 4] \odot [1, 6, 11, 16] = [1, 12, 33, 64]$.
- Operation for $j=1$:
We take the rotated ciphertext $ct_{1} = (c_{0, r1}, c_{1,r1})$ and encoded diagonal $U_1(X)$.
$$ct_1' = (c_{0,r1} \cdot U_1, \; c_{1,r1} \cdot U_1)$$
Same, $ct_1'$ encrypts $[2, 3, 4, 1] \odot [2, 7, 12, 13] = [4, 21, 48, 13]$.
- Operation for $j=2$: *(ignore ...)*
- Operation for $j=3$: *(ignore ...)*
*(We can simply multiply the ciphertext polynomials by the plaintext polynomial).*
---
### **Step 4: Homomorphic Addition (Accumulation)**
Finally, we sum the four partial ciphertexts. In ciphertext space, addition is the simplest operation: just add the polynomials component-wise.
$$ct_{final} = \sum_{j=0}^{3} ct_j'$$
The resulting pair of polynomials $(c_{0,final}, c_{1,final})$ encrypts the sum of the underlying vectors: $[1, 12, 33, 64] + [4, 21, 48, 13] + ... = [30, 70, 110, 150]$
We finally finish doing Homomorphic Matrix-Vector Multiplication by using the following techiques:
- Vector Encoding Scheme
- Homomorphic Rotation
- Homomorphic Multiplication
- Key Switching
- Rescaling (since Homomorphic Multiplication needs to drop one modulus)
- Homomorphic Addition