D-2.9 Homomorphic Rotation of Input Vector Slots

In this section, we will explain how to homomorphically rotate the elements of an input vector v after it is already encoded as a polynomial and encrypted as an RLWE ciphertext. In §A-5.2, we learned how to rotate the coefficients of a polynomial. However, rotating the plaintext polynomial M(X) or RLWE ciphertext polynomials (A(X),B(X)) does not necessarily rotate the input vector, which is the source of them.

The key requirement of homomorphic rotation of input vector slots (i.e., input vector) is that this operation should be performed on the RLWE ciphertext such that after this operation, if we decrypt the RLWE ciphertext and decode it, the recovered input vector will be in a rotated state as we expect. We will divide this task into the following two sub-problems:

1.
How to indirectly rotate the input vector by updating the plaintext polynomial M to M?
2.
How to indirectly update the plaintext polynomial M to M by updating the RLWE ciphertext polynomials (A,B) to (A,B)?
D-2.9.1 Rotating Input Vector Slots by Updating the Plaintext Polynomial

In this task, our goal is to modify the plaintext polynomial M(X) such that the first-half elements of the input vector v are shifted to the left by h positions in a wrapping manner among them, and the second-half elements of v are also shifted to the left by h positions in a wrapping manner among them. Specifically, if v is defined as follows:

v = (v0,v1,,vn1)

Then, we will denote the h-shifted vector vh as follows:

vh = (vh,vh+1,,v0,v1,,vh2,vh1, The first-half n 2 elements h-rotated to the left vn 2 +h,vn 2 +h+1,,vn 2 +h2,vn 2 +h1 The second-half n 2 elements h-rotated to the left)

Remember from §D-2.2 that the BFV encoding scheme’s components are as follows:

v = (v0,v1,v2,,vn1) # n-dimensional input vector

W = [ 1 1 1 1 (ω) (ω3) (ω5) (ω2n1) (ω)2 (ω3)2 (ω5)2 (ω2n1)2 (ω)n1 (ω3)n1 (ω5)n1 (ω2n1)n1 ]

= [ 1 1 1 1 1 1 (ω) (ω3) (ωn 2 1) (ω(n 2 1)) (ω3) (ω1) (ω)2 (ω3)2 (ωn 2 1)2 (ω(n 2 1))2 (ω3)2 (ω1)2 (ω)n1 (ω3)n1 (ωn 2 1)n1 (ω(n 2 1))n1 (ω3)n1 (ω1)n1 ]

, where ω = gt1 2n mod t (g is a generator of t×)

# The encoding matrix that converts v into m ( i.e., n coefficients of the plaintext polynomial M(X) )

Δm = n1 ΔW InR v

# A vector containing the scaled n integer coefficients of the plaintext polynomial

ΔM = i=0n1(ΔmiXi)

# The integer polynomial that isomorphically encodes the input vector v

We learned from §A-10.6 that decoding the polynomial M(X) back to v is equivalent to evaluating M(X) at the following n distinct primitive (μ = 2n)-th root of unity: {ω,ω3,ω5,,ω2n3,ω2n1}. Thus, the above decoding process is equivalent to the following:

v = WT Δm Δ = (W0T m, W1T m, W2T m, , Wn1T m)

= ( M(ω), M(ω3), M(ω5),,M(ω2n3), M(ω2n1) )

= ( M(ω), M(ω3), M(ω5),,M(ωn3), M(ωn1), M(ω(n1)), M(ω(n3)),,M(ω3), M(ω1) )

Now, our next task is to modify M(X) to M(X) such that decoding M(X) will give us a modified input vector vh that is a rotation of the first half elements of v by h positions to the left (in a wrapping manner among them), and the second half elements of it also rotated by h positions to the left (in a wrapping manner among them). To accomplish this rotation, we will take a 2-step solution:

1.
To convert M(X) into M(X), we will define the new mapping σM as follows:

σM : (M(X),h) (Rn,t, n)M(X) Rn,t

, where h is the number of rotation positions to be applied to v.

2.
To decode M(X) into the rotated input vector vh, we need to re-design our decoding scheme by modifying Encoding1’s (§D-2.2.1) isomorphic mapping σ : M(X) Rn,tv n

Converting 𝐌(𝐗) into 𝐌(𝐗): Our first task is to convert M(X) into M(X), which is equivalent to applying our new mapping σM : (M(X),h) (Rn,t, n)M(X) Rn,t, such that decoding M(X) gives a rotated input vector vh whose first half of the elements in v are rotated by h positions to the left (in a wrapping manner among them), and the second half of the elements are also rotated by h positions to the left (in a wrapping manner among them). To design σM that satisfies this requirement, we will use the number 5j which has the following two special properties (based on number theory):

For example, suppose the modulus 2n = 16. Then,

50 mod 16 = 1
51 mod 16 = 5
52 mod 16 = 9
53 mod 16 = 13
(5)0 mod 16 = 15
(5)1 mod 16 = 11
(5)2 mod 16 = 7
(5)3 mod 16 = 3

As shown above, 0 j < 4 generate all odd numbers between [0,16). Also, for each j in 0 j < 4, (5j mod 16) + (5j mod 16) = 16.

Let’s define J(h) = 5h mod 2n, and J(h) = 5h mod 2n. Based on J(h) and J(h), we will define the mapping σM : M(X) M(X) as follows:

σM : M(X) M(XJ(h))

Given a plaintext polynomial M(X), in order to give its decoded version of input vector v the effect of the first half of the elements being rotated by h positions to the left (in a wrapping manner) and the second half of the elements also being rotated by h positions to the left (in a wrapping manner), we update the current plaintext polynomial M(X) to a new polynomial M(X) = M(XJ(h)) = M(X5h ) by applying the σM mapping, where h is the number of positions for left rotations for the first half and second half of the elements of v.

Decoding 𝐌(𝐗) into vh: Our second task is to modify our original decoding scheme in order to successfully decode M(X) into the rotated input vector vh. For this, we will modify our original isomorphic mapping σ : M(X)v, from:

σ : M(X) Rn,q(M(ω),M(ω3),M(ω5),,M(ω2n1)) n # designed in §A-10.6

, to the following:

σJ : M(X) Rn,t(M(ωJ(0)),M(ωJ(1)),M(ωJ(2)),,M(ωJ(n 2 1)),

σJ : M(X) Rn,q( M(ωJ(0)), M(ωJ(1)), M(ωJ(2)),,M(ωJ(n 2 1) ) n

The common aspect between σ and σJ is that they both evaluate the polynomial M(X) at n distinct primitive (μ = 2n)-th roots of unity (i.e., wi for all odd i between [0,2n] ). In the case of the σJ mapping, note that J(j) = 5j mod 2n and J(j) = 5j mod 2n for each j in 0 j < n 2 cover all odd numbers between [0,2n]. Therefore, ωJ(j) and ωJ(j) between 0 j < n 2 cover all n distinct primitive (μ = 2n)-th roots of unity.

Meanwhile, the difference between σ and σJ is the order of the output vector elements. In the σ mapping, the order of evaluated coordinates for M(X) is ω,ω3,,ω2n1, whereas in the σJ mapping, the order of evaluated coordinates is ωJ(0),ωJ(1),,ωJ(n 2 1),ωJ(0),ωJ(1),,ωJ(n 2 1). We will later explain why we modified the ordering like this.

In the original Decoding2 process (§D-2.2), applying the σ mapping to a plaintext polynomial M(X) was equivalent to computing the following:

v = ( M(ω), M(ω3), M(ω5),,M(ω2n3), M(ω2n1))

= ( M(ω), M(ω3), M(ω5),,M(ωn1), M(ω(n1)),, M(ω3), M(ω1) )

= ( W0T m, W1T m, W2T m, , Wn1T m ) # where WiT is the (i + 1)-th row of WT

= WT m

Similarly, the modified σJ mapping to the plaintext polynomial M(X) is equivalent to computing the following:

v = ( M(ωJ(0)), M(ωJ(1)), M(ωJ(2)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),,M(ωJ(n 2 1)) )

= ( W~0m, W~1m, W~2m, , W~n1m )

= W~m, where

W~ = [ 1 (ωJ(0)) (ωJ(0))2 (ωJ(0))n1 1 (ωJ(1)) (ωJ(1))2 (ωJ(1))n1 1 (ωJ(2)) (ωJ(2))2 (ωJ(2))n1 1 (ωJ(n 2 1)) (ωJ(n 2 1))2 (ωJ(n 2 1))n1 1 (ωJ(0)) (ωJ(0))2 (ωJ(0))n1 1 (ωJ(1)) (ωJ(1))2 (ωJ(1))n1 1 (ωJ(2)) (ωJ(2))2 (ωJ(2))n1 1 (ωJ(n 2 1)) (ωJ(n 2 1))2 (ωJ(n 2 1))n1 ]

W~ = [ 1 1 1 1 1 1 (ωJ(n 2 1)) (ωJ(n 2 2)) (ωJ(0)) (ωJ(n 2 1)) (ωJ(n 2 2)) (ωJ(0)) (ωJ(n 2 1))2 (ωJ(n 2 2))2 (ωJ(0))2 (ωJ(n 2 1))2 (ωJ(n 2 2))2 (ωJ(0))2 (ωJ(n 2 1))n1 (ωJ(n 2 2))n1 (ωJ(0))n1 (ωJ(n 2 1))n1 (ωJ(n 2 2))n1 (ωJ(0))n1 ]

From this point, we will replace W in the Encoding1 process (§D-2.2) by W~, and WT in the Decoding2 process by W~.

To demonstrate that W~ is a valid encoding matrix like W and W~ is a valid decoding matrix like WT , we need to prove the following 2 aspects:

Therefore, W~ and W~ are valid encoding & decoding matrices that transform v into M(X).

Now, let’s think about what will be the structure of vh (i.e., the first-half elements of v being rotated h positions to the left in a wrapping manner among them and the second-half elements of it also being rotated h positions to the left in a wrapping manner among them). Remember that v is as follows:

v = ( M(ωJ(0)), M(ωJ(1)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),,M(ωJ(n 2 1)))

= ( W~0m, W~1m, W~2m, , W~n1m )

Thus, the state of vh which is equivalent to rotating v by h positions to the left for the first-half and second-half element groups will be the following:

vh = ( M(ωJ(h)), M(ωJ(h+1)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),, M(ωJ(h2)), M(ωJ(h1)),

M(ωJ(h)), M(ωJ(h+1)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),, M(ωJ(h2)), M(ωJ(h1)) )

Notice that the above computation of vh is equivalent to vertically rotating the upper n 2 rows of W~ by h positions upward (in a wrapping manner among them), rotating the lower n 2 rows of W~ by h positions upward (in a wrapping manner among them), and multiplying the resulting matrix with m. However, it is not desirable to directly modify the decoding matrix W~ like this in practice, because then the decoding matrix loses its consistency. Therefore, instead of directly modifying W~, we will modify m to m (i.e., modify M(X) to M(X)) such that the relation vh = W~m holds. Let’s extract the upper-half rows of W~ and denote this n 2 ×n matrix as H~1. Then, H~1 is equivalent to a Vandermonde matrix (Definition A-10.2 in §A-10.2) in the form of V (ωJ(0),ωJ(1),,ωJ(n 2 1)). Similarly, let’s extract the lower-half rows of W~ and denote this n 2 ×n matrix as H~2. Then, H~2 is equivalent to a Vandermonde matrix (Definition A-10.2 in §A-10.2) in the form of V (ωJ(0),ωJ(1),,ωJ(n 2 1)).

Now, let’s vertically rotate the rows of H~1 by h positions upward and denote it as H~1h; and vertically rotate the rows of H~2 by h positions upward and denote it as H~2h. And let’s denote the n 2-dimensional vector comprising the first-half elements of vh as v1h, and the n 2-dimensional vector comprising the second-half elements of vh as v2h. Then, computing (i.e., decoding) v1h = H~1hm is equivalent to modifying M(X) to M(X) = M(XJ(h)) (whose coefficient vector is mh) and then computing (i.e., decoding) v1h = H~1mh. This is because:

v1h = H~1hm

= ( W~hm, W~h+1m, W~h+2m,,W~n 2 1m, W~0m, W~1m,, W~h2m, W~h1m)

= ( M((ωJ(h))J(0)), M((ωJ(h))J(1)), M((ωJ(h))J(2)),,M((ωJ(h))J(n 2 1)) )

# This is equivalent to evaluating the polynomial M(XJ(h)) at the following n 2 distinct (μ = 2n)-th roots of unity: ωJ(0),ωJ(1),ωJ(2),,ωJ(n 2 1)

= ( M(ωJ(h)J(0)), M(ωJ(h)J(1)), M(ωJ(h)J(2)),,M(ωJ(h)J(n 2 1)) )

= ( M(ω5h50 ), M(ω5h51 ), M(ω5h52 ),,M(ω5h5n21 ) )

= ( M(ω5h ), M(ω5h+1 ), M(ω5h+2 ),,M(ω5h+n21 ) ) # note that 5n 2 mod 2n = 1

= ( M(ωJ(h)), M(ωJ(h+1)), M(ωJ(h+2)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),

, M(ωJ(h2)), M(ωJ(h1)))

= H~1mh # where mh contains the n coefficients of the polynomial M(XJ(h))

Similarly, computing (i.e., decoding) v2h = H~2hm is equivalent to modifying M(X) to M(X) = M(XJ(h)) (whose coefficient vector is mh) and then computing (i.e., decoding) v2h = H~2mh. This is because,

v2h = H~2hm

= ( W~n 2 +hm, W~n 2 +h+1m, W~n 2 +h+2m,,W~n1m, W~n 2 m, W~n 2 +1m,,

 W~n 2 +h2m, W~n 2 +h1m)

= ( M((ωJ(h))J(0)), M((ωJ(h))J(1)), M((ωJ(h))J(2)),,M((ωJ(h))J(n 2 1)) )

# This is equivalent to evaluating the polynomial M(XJ(h)) at the following n 2 distinct (μ = 2n)-th roots of unity: ωJ(0),ωJ(1),ωJ(2),,ωJ(n 2 1)

= ( M(ωJ(h)J(0)), M(ωJ(h)J(1)), M(ωJ(h)J(2)),,M(ωJ(h)J(n 2 1)) )

= ( M(ω5h50 ), M(ω5h51 ), M(ω5h52 ),,M(ω5h5n21 ) )

= ( M(ω5h ), M(ω5h+1 ), M(ω5h+2 ),,M(ω5h+n21 ) ) # note that (5n 2 mod 2n) = 1

= ( M(ωJ(h)), M(ωJ(h+1)), M(ωJ(h+2)),,M(ωJ(n 2 1)), M(ωJ(0)), M(ωJ(1)),

, M(ωJ(h2)), M(ωJ(h1)))

= H~2mh

The above derivations demonstrate that v1h = H~1mh, and v2h = H~2mh. Combining these two findings, we reach the conclusion that vh = W~mh: rotating the first-half elements of the input vector v by h positions to the left and the second-half elements of it by h positions also to the left is equivalent to updating the plaintext polynomial M(X) to M(XJ(h)) and then decoding it with the decoding matrix W~.

However, now a new problem is that we cannot directly update the plaintext M(X) to M(XJ(h)), because M(X) is encrypted as an RLWE ciphertext. Therefore, we need to instead update the RLWE ciphertext components (A,B) to indirectly by updating M(X) to M(XJ(X)). We will explain this in the next subsection.

D-2.9.2 Updating the Plaintext Polynomial by Updating the Ciphertext Polynomials

Given an RLWE ciphertext 𝖼𝗍 = (A,B), our goal is to update 𝖼𝗍 = (A,B) to Ch = (Ah,Bh) such that decrypting it gives the input vector vh. That is, the following relation should hold:

𝖱𝖫𝖶𝖤S,σ1( Ch = (Ah,Bh) ) = ΔM(XJ(h)) + E

Remember that in the RLWE cryptosystem (§B-3)’s alternative version (§B-4.4), the plaintext and ciphertext pair have the following relation:

ΔM(X) + E(X) = A(X) S(S) + B(X) ΔM(X)

If we apply X = XJ(h) in the above relation, we can derive the following relation:

ΔM(XJ(h)) + E(XJ(h)) = A(XJ(h)) S(XJ(h)) + B(XJ(h)) ΔM(XJ(h))

This relation implies that if we decrypt the ciphertext Ch = (A(XJ(h)),B(XJ(h))) with S(XJ(h)) as the secret key, then we get ΔM(XJ(h)). Therefore, Ch = (A(XJ(h)),B(XJ(h))) is the RLWE ciphertext we are looking for, because decrypting it and then decoding its plaintext M(XJ(h)) will give us the input vector vh.

We can easily convert 𝖼𝗍 = (A(X),B(X)) into Ch = (A(XJ(h)),B(XJ(h))) by applying XJ(h) to X for each of the A(X) and B(X) polynomials. However, after that, notice that the decryption key of the RLWE ciphertext Ch = (A(XJ(h)),B(XJ(h))) has been changed from S(X) to S(XJ(h)). Thus, we need to additionally switch the ciphertext Ch’s key from S(XJ(h)) S(X), which is equivalent to converting 𝖱𝖫𝖶𝖤S(XJ(h)),σ(Ch = (A(XJ(h)),B(XJ(h)))) into 𝖱𝖫𝖶𝖤S,σ(Ch = (A(XJ(h)),B(XJ(h)))). For this, we will apply the BFV key switching technique (Summary D-2.8) learned in §D-2.8 as follows:

𝖱𝖫𝖶𝖤S(X),σ(ΔM(XJ(h))) the result of plaintext-to-ciphertext addition = ( 0,B(XJ(h)) ) the plaintext B(XJ(h)) (trivial ciphertext) + 𝖣𝖾𝖼𝗈𝗆𝗉β,l(A(XJ(h))), 𝖱𝖫𝖾𝗏 S(X),σβ,l(S(XJ(h)))  an RLWE ciphertext encrypting A(XJ(h)) S(XJ(h)) which is key-switched from S(XJ(h)) S(X)

D-2.9.3 Summary

We summarize the procedure of rotating the BFV input vectors as follows:

Summary D-2.9 BFV’s Homomorphic Rotation of Input Vector Slots

To support input vector slot rotation, we update the original encoding matrix in Encoding1 as follows:

W~ = [ 1 1 1 1 1 1 (ωJ(n2 1)) (ωJ(n2 2)) (ωJ(0)) (ωJ(n2 1)) (ωJ(n2 2)) (ωJ(0)) (ωJ(n2 1))2 (ωJ(n2 2))2 (ωJ(0))2 (ωJ(n2 1))2 (ωJ(n2 2))2 (ωJ(0))2 (ωJ(n2 1))n1 (ωJ(n2 2))n1 (ωJ(0))n1 (ωJ(n2 1))n1 (ωJ(n2 2))n1 (ωJ(0))n1 ]

, and update the original decoding matrix in Decoding2 as follows:

W~ = [ 1 (ωJ(0)) (ωJ(0))2 (ωJ(0))n1 1 (ωJ(1)) (ωJ(1))2 (ωJ(1))n1 1 (ωJ(2)) (ωJ(2))2 (ωJ(2))n1 1 (ωJ(n 2 1)) (ωJ(n 2 1))2 (ωJ(n 2 1))n1 1 (ωJ(0)) (ωJ(0))2 (ωJ(0))n1 1 (ωJ(1)) (ωJ(1))2 (ωJ(1))n1 1 (ωJ(2)) (ωJ(2))2 (ωJ(2))n1 1 (ωJ(n 2 1)) (ωJ(n 2 1))2 (ωJ(n 2 1))n1 ]

, where J(h) is the rotation helper formula: J(h) = 5h mod 2n, J(h) = 5h mod 2n

Suppose we have an RLWE ciphertext and a key-switching key as follows:

𝖱𝖫𝖶𝖤S,σ(ΔM) = (A,B), 𝖱𝖫𝖾𝗏S,σβ,l(S(XJ(h)))

Then, the procedure of rotating the first-half elements of the ciphertext’s original input vector v by h positions to the left (in a wrapping manner among them) and the second-half elements of v by h positions to the left (in a wrapping manner among them) is as follows:

1.
Update A(X), B(X) to A(XJ(h)), B(XJ(h)).
2.
Perform the following key switching (§D-3.8) from S(XJ(h)) to S(X):

𝖱𝖫𝖶𝖤S(X),σ(ΔM(XJ(h))) = (0,B(XJ(h))) + 𝖣𝖾𝖼𝗈𝗆𝗉β,l(A(XJ(h))), 𝖱𝖫𝖾𝗏S(X),σβ,l(S(XJ(h)))

D-2.9.4 Encoding Example

Suppose we have the following setup:

μ = 8,n = μ 2 = 4, t = 17, q = 26 = 64, n1 = 13, Δ = 2

R4,17 = 17[X](X4 + 1)

The roots of X4 + 1(𝑚𝑜𝑑17) are X = {2,8,15,9}, as demonstrated as follows:

24 84 154 94 16 1 mod 17

Definition A-8.1 (in §A-8.1) states that the roots of the μ-th cyclotomic polynomial are the primitive μ-th roots of unity. And Definition A-7.1 (in §A-7.1) states that the order of the primitive μ-th roots of unity is μ. These definitions apply to both the cyclotomic polynomials over X (complex numbers) and the cyclotomic polynomials over X t (ring).

Since {2,8,15,9}are the roots of the (μ = 8)-th cyclotomic polynomial X4 + 1 over the ring 17, they are also the (μ = 8)-th primitive roots of unity of 17. Therefore, their order (§A-4.1) is μ = 8 as demonstrated as follows:

28 88 158 98 1 mod 17

24 84 154 94 161 mod 17

Definition A-8.1 (in §A-8.1) and Theorem A-8.2 (§A-8.2) also state that for each primitive μ-th root of unity ω, {ωk}𝗀𝖼𝖽(k,μ)=1 generates all roots of the μ-th cyclotomic polynomial. Notice that in the case of the (μ = 8)-th cyclotomic polynomial X4 + 1, its roots {2,8,15,9} generate all (μ = 8)-th roots of unity as follows:

{21,23,25,27}{81,83,85,87}{151,153,155,157}{91,93,95,97}{2,8,15,9}mod 17

Among {2,8,15,9} as the roots of X4 + 1, let’s choose ω = 9 as the base root to construct the encoding matrix W~ and the decoding matrix W~ as follows:

W~ = [ 1 1 1 1 ωJ(1) ωJ(0) ωJ(1) ωJ(0) (ωJ(1))2 (ωJ(0))2 (ωJ(1))2 (ωJ(0))2 (ωJ(1))3 (ωJ(0))3 (ωJ(1))3 (ωJ(0))3 ] # where J(h) = 5h mod 8

= [ 1 1 1 1 95 91 93 97 (95)2 (91)2 (93)2 (97)2 (95)3 (91)3 (93)3 (97)3 ] [ 1 1 1 1 8 9 15 2 13 13 4 4 2 15 9 8 ]mod17

W~ = [ 1 ωJ(0) (ωJ(0))2 (ωJ(0))3 1 ωJ(1) (ωJ(1))2 (ωJ(1))3 1 ωJ(0) (ωJ(0))2 (ωJ(0))3 1 ωJ(1) (ωJ(1))2 (ωJ(1))3 ] [ 1 9 13 15 1 8 13 2 1 2 4 8 1 15 4 9 ]mod17

Notice that Theorem A-11.5 (in §A-11.5) is demonstrated as follows:

W~W~ = [ 1 9 13 15 1 8 13 2 1 2 4 8 1 15 4 9 ][ 1 1 1 1 8 9 15 2 13 13 4 4 2 15 9 8 ] = [ 0 0 0 4 0 0 4 0 0 4 0 0 4 0 0 0 ] = nInR (𝑚𝑜𝑑17)

Now suppose that we encode the following two input vectors (i.e., input vector slots) in 17:

v1 = (10,3,5,13)

v2 = (2,4,3,6)

v1 + v2 = (10,3,5,13) + (2,4,3,6) (12,7,8,2) mod 17

These two vectors are encoded as follows:

m1 = n1W~InRv = 13[ 1 1 1 1 8 9 15 2 13 13 4 4 2 15 9 8 ][ 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 ][ 10 3 5 13 ] (12,11,12,1)mod17

m2 = n1W~InRv = 13[ 1 1 1 1 8 9 15 2 13 13 4 4 2 15 9 8 ][ 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 ][ 2 4 3 6 ] (8,5,14,6)mod17

ΔM1(X) = 2 (12 + 11X + 12X2 + 1X3) = 24 + 22X + 24X2 + 2X3(𝑚𝑜𝑑q) # where q = 64

ΔM2(X) = 2 (8 + 5X + 14X2 + 6X3) = 16 + 10X + 28X2 + 12X3(𝑚𝑜𝑑q)

ΔM1+2(X) = ΔM1(X) + ΔM2(X) = Δ(M1(X) + M2(X)) = 40 + 32X + 52X2 + 14X3 (𝑚𝑜𝑑q)

Note that the coefficients of the scaled polynomials ΔM1(X) and ΔM2(X) are still within the range of the ciphertext domain q = 64 (which must hold throughout all homomorphic computations to preserve correctness).

We decode M1(X) and M2(X) as follows:

m1 = Δm1 Δ = (24,22,24,2) 2 = (12,11,12,1)

m2 = Δm2 Δ = (16,10,28,12) 2 = (8,5,14,6)

m1+2 = Δm1+2 Δ = (40,32,52,14) 2 = (20,16,26,7)

v1 = W~m1 = [ 1 9 13 15 1 8 13 2 1 2 4 8 1 15 4 9 ][ 12 11 12 1 ] = (10,3,5,13) (𝑚𝑜𝑑17)

v2 = W~m2 = [ 1 9 13 15 1 8 13 2 1 2 4 8 1 15 4 9 ][ 8 5 14 6 ] = (2,4,3,6) (𝑚𝑜𝑑17)

v1+2 = W~m1+2 = [ 1 9 13 15 1 8 13 2 1 2 4 8 1 15 4 9 ][ 20 16 26 7 ] = (12,7,8,2) (𝑚𝑜𝑑17)

The decoded v1,v2, and v1+2 match the expected values.

D-2.9.5 Rotation Example

Suppose we have the following setup:

μ = 16,n = μ 2 = 8, t = 17, q = 26 = 64, n1 = 13, Δ = 2

R8,17 = 17[X](X8 + 1)

The roots of X8 + 1(𝑚𝑜𝑑17) are X = {3,5,6,7,10,11,12,14}, as demonstrated as follows:

38 58 68 78 108 118 128 148 16 1 mod 17

Among {3,5,6,7,10,11,12,14} as the roots of X8 + 1, let’s choose ω = 3 as the base root to construct the encoding matrix W~ and the decoding matrix W~ as follows:

W~ = [ 1 1 1 1 1 1 1 1 ωJ(3) ωJ(2) ωJ(1) ωJ(0) ωJ(3) ωJ(2) ωJ(1) ωJ(0) (ωJ(3))2 (ωJ(2))2 (ωJ(1))2 (ωJ(0))2 (ωJ(3))2 (ωJ(2))2 (ωJ(1))2 (ωJ(0))2 (ωJ(3))3 (ωJ(2))3 (ωJ(1))3 (ωJ(0))3 (ωJ(3))3 (ωJ(2))3 (ωJ(1))3 (ωJ(0))3 (ωJ(3))4 (ωJ(2))4 (ωJ(1))4 (ωJ(0))4 (ωJ(3))4 (ωJ(2))4 (ωJ(1))4 (ωJ(0))4 (ωJ(3))5 (ωJ(2))5 (ωJ(1))5 (ωJ(0))5 (ωJ(3))5 (ωJ(2))5 (ωJ(1))5 (ωJ(0))5 (ωJ(3))6 (ωJ(2))6 (ωJ(1))6 (ωJ(0))6 (ωJ(3))6 (ωJ(2))6 (ωJ(1))6 (ωJ(0))6 (ωJ(3))7 (ωJ(2))7 (ωJ(1))7 (ωJ(0))7 (ωJ(3))7 (ωJ(2))7 (ωJ(1))7 (ωJ(0))7 ]

[ 1 1 1 1 1 1 1 1 12 14 5 3 10 11 7 6 8 9 8 9 15 2 15 2 11 7 6 10 14 5 3 12 13 13 13 13 4 4 4 4 3 12 14 5 6 10 11 7 2 15 2 15 9 8 9 8 7 6 10 11 5 3 12 14 ]mod17

W~ = [ 1 ωJ(0) (ωJ(0))2 (ωJ(0))3 (ωJ(0))4 (ωJ(0))5 (ωJ(0))6 (ωJ(0))7 1 ωJ(1) (ωJ(1))2 (ωJ(1))3 (ωJ(1))4 (ωJ(1))5 (ωJ(1))6 (ωJ(1))7 1 ωJ(2) (ωJ(2))2 (ωJ(2))3 (ωJ(2))4 (ωJ(2))5 (ωJ(2))6 (ωJ(2))7 1 ωJ(3) (ωJ(3))2 (ωJ(3))3 (ωJ(3))4 (ωJ(3))5 (ωJ(3))6 (ωJ(3))7 1 ωJ(0) (ωJ(0))2 (ωJ(0))3 (ωJ(0))4 (ωJ(0))5 (ωJ(0))6 (ωJ(0))7 1 ωJ(1) (ωJ(1))2 (ωJ(1))3 (ωJ(1))4 (ωJ(1))5 (ωJ(1))6 (ωJ(1))7 1 ωJ(2) (ωJ(2))2 (ωJ(2))3 (ωJ(2))4 (ωJ(2))5 (ωJ(2))6 (ωJ(2))7 1 ωJ(3) (ωJ(3))2 (ωJ(3))3 (ωJ(3))4 (ωJ(3))5 (ωJ(3))6 (ωJ(3))7 ]

[ 1 3 9 10 13 5 15 11 1 5 8 6 13 14 2 10 1 14 9 7 13 12 15 6 1 12 8 11 13 3 2 7 1 6 2 12 4 7 8 14 1 7 15 3 4 11 9 12 1 11 2 5 4 10 8 3 1 10 15 14 4 6 9 5 ]mod17

Notice that Theorem A-11.5 (in §A-11.5) is demonstrated as follows:

W~W~ = [ 1 3 9 10 13 5 15 11 1 5 8 6 13 14 2 10 1 14 9 7 13 12 15 6 1 12 8 11 13 3 2 7 1 6 2 12 4 7 8 14 1 7 15 3 4 11 9 12 1 11 2 5 4 10 8 3 1 10 15 14 4 6 9 5 ][ 1 1 1 1 1 1 1 1 12 14 5 3 10 11 7 6 8 9 8 9 15 2 15 2 11 7 6 10 14 5 3 12 13 13 13 13 4 4 4 4 3 12 14 5 6 10 11 7 2 15 2 15 9 8 9 8 7 6 10 11 5 3 12 14 ]

= [ 0 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 8 0 0 0 0 0 0 0 ] = nInR (𝑚𝑜𝑑17)

Now suppose that we encode the following input vector (i.e., input vector slots) in 17:

v = (1,2,3,4,5,6,7,8)

By rotating this vector by 3 positions to the left (i.e., the first-half slots and the second-half slots separately wrapping around within their own group), we get a new vector:

vr = (4,1,2,3,8,5,6,7) mod 17

v is encoded as follows:

m = n1W~ InR v

= 13[ 1 1 1 1 1 1 1 1 12 14 5 3 10 11 7 6 8 9 8 9 15 2 15 2 11 7 6 10 14 5 3 12 13 13 13 13 4 4 4 4 3 12 14 5 6 10 11 7 2 15 2 15 9 8 9 8 7 6 10 11 5 3 12 14 ][ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ][ 1 2 3 4 5 6 7 8 ]

(13,16,10,5,9,12,7,1) mod 17

ΔM(X) = 2 (13 + 16X + 10X2 + 5X3 + 9X4 + 12X5 + 7X6 + X7)

= 26 + 32X + 20X2 + 10X3 + 18X4 + 24X5 + 14X6 + 2X7(𝑚𝑜𝑑q) # where q = 64

ΔM(XJ(3)) = ΔM(X13) = 26 + 24X 20X2 2X3 + 18X4 32X5 14X6 + 10X7(𝑚𝑜𝑑q)

Note that the coefficients of the scaled polynomials ΔM(XJ(3)) are still within the range of the ciphertext domain q = 64 (which must hold throughout all homomorphic computations to preserve correctness).

We decode M(XJ(3)) as follows:

mJ(3) = ΔmJ(3) Δ = (26,24,20,2,18,32,14,10) 2 = (13,12,10,2,18,32,14,10) (𝑚𝑜𝑑17)

vJ(3) = W~mJ(3) = [ 1 3 9 10 13 5 15 11 1 5 8 6 13 14 2 10 1 14 9 7 13 12 15 6 1 12 8 11 13 3 2 7 1 6 2 12 4 7 8 14 1 7 15 3 4 11 9 12 1 11 2 5 4 10 8 3 1 10 15 14 4 6 9 5 ][ 13 12 10 2 18 32 14 10 ]

= (4,1,2,3,8,5,6,7)(𝑚𝑜𝑑17)

= vr

The decoded vJ(3) matches the expected rotated input vector vr.

In practice, we do not directly update ΔM(X) to ΔM(XJ(3)), because we would not have access to the plaintext polynomial M(X) unless we have the secret key S(X). Therefore, we instead update 𝖼𝗍 = (A(X),B(X)) to 𝖼𝗍h=3 = (A(XJ(3)),B(XJ(3))), which is equivalent to homomorphically rotating the encrypted input vector slots. Then, decrypting 𝖼𝗍h=3 and decoding it would output vr.

Source Code: Examples of BFV’s batch encoding and homomorphic input vector rotation can be executed by running this Python script.