In this section, we will explain how to homomorphically rotate the elements of an input vector
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
or RLWE ciphertext
polynomials
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
to ?
-
2.
- How to indirectly update the plaintext polynomial
to
by updating the RLWE ciphertext polynomials
to ?
D-2.9.1 Rotating Input Vector Slots by Updating the Plaintext Polynomial
In this task, our goal is to modify the plaintext polynomial
such that the first-half
elements of the input vector
are shifted to the left by
positions in a wrapping manner among them, and the second-half elements of
are also shifted to the left by
positions in a wrapping manner
among them. Specifically, if
is defined as follows:
Then, we will denote the -shifted
vector
as follows:
Remember from §D-2.2 that the BFV encoding scheme’s components are as follows:
#
-dimensional
input vector
, where
( is a
generator of )
# The encoding matrix that converts
into ( i.e.,
coefficients of the
plaintext polynomial
)
# A vector containing the scaled
integer coefficients of the plaintext polynomial
# The integer polynomial that isomorphically encodes the input vector
We learned from §A-10.6 that decoding the polynomial
back to
is equivalent to
evaluating at the
following distinct
primitive -th
root of unity: .
Thus, the above decoding process is equivalent to the following:
Now, our next task is to modify
to such that decoding
will give us a modified input
vector that is a rotation
of the first half elements of
by
positions to the left (in a wrapping manner among them), and the second half elements of it also rotated
by
positions to the left (in a wrapping manner among them). To accomplish this rotation, we will take a
2-step solution:
-
1.
- To convert
into ,
we will define the new mapping
as follows:
, where
is the number of rotation positions to be applied to .
-
2.
- To decode
into the rotated input vector ,
we need to re-design our decoding scheme by modifying Encoding1’s (§D-2.2.1) isomorphic
mapping
Converting into
: Our first task is
to convert into
, which is equivalent to
applying our new mapping ,
such that decoding gives a
rotated input vector whose
first half of the elements in
are rotated by
positions to the left (in a wrapping manner among them), and the second half of the elements are also rotated
by
positions to the left (in a wrapping manner among them). To design
that satisfies this requirement,
we will use the number
which has the following two special properties (based on number theory):
-
and
generate all odd numbers between
for the integer
where .
- For each integer
where ,
.
For example, suppose the modulus .
Then,
As shown above, generate
all odd numbers between .
Also, for each
in ,
.
Let’s define ,
and .
Based on and
, we will define
the mapping
as follows:
Given a plaintext polynomial ,
in order to give its decoded version of input vector
the effect of the first half of
the elements being rotated by
positions to the left (in a wrapping manner) and the second half of the elements also being rotated by
positions to the left (in a wrapping manner), we update the current plaintext polynomial
to a new
polynomial by
applying the
mapping, where
is the number of positions for left rotations for the first half and second half of the elements of
.
Decoding
into :
Our second task is to modify our original decoding scheme in order to successfully decode
into the rotated input vector
. For this, we will modify our
original isomorphic mapping ,
from:
#
designed in §A-10.6
, to the following:
The common aspect between
and is that they both
evaluate the polynomial
at distinct
primitive -th roots
of unity (i.e., for
all odd between
). In the case of
the mapping,
note that
and for
each in
cover all odd
numbers between .
Therefore,
and between
cover all
distinct
primitive -th
roots of unity.
Meanwhile, the difference between
and is the order of the output vector
elements. In the mapping, the
order of evaluated coordinates for
is , whereas in the
mapping, the order of
evaluated coordinates is .
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
was equivalent to computing the following:
# where
is the
-th row
of
Similarly, the modified mapping
to the plaintext polynomial
is equivalent to computing the following:
,
where
From this point, we will replace
in the Encoding1 process (§D-2.2) by ,
and in the Decoding2
process by .
To demonstrate that is
a valid encoding matrix like
and is a valid
decoding matrix like ,
we need to prove the following 2 aspects:
Therefore, and
are valid encoding & decoding
matrices that transform
into .
Now, let’s think about what will be the structure of
(i.e., the first-half
elements of
being rotated
positions to the left in a wrapping manner among them and the second-half elements of it also being
rotated
positions to the left in a wrapping manner among them). Remember that
is as
follows:
Thus, the state of which
is equivalent to rotating
by
positions to the left for the first-half and second-half element groups will be the following:
Notice that the above computation of is
equivalent to vertically rotating the upper
rows of
by
positions upward (in a wrapping manner among them), rotating the lower
rows of
by
positions upward (in a wrapping manner among them), and multiplying the resulting matrix with
.
However, it is not desirable to directly modify the decoding matrix
like this in
practice, because then the decoding matrix loses its consistency. Therefore, instead of directly modifying
, we will
modify
to (i.e.,
modify to
) such that the relation
holds. Let’s extract
the upper-half rows of
and denote this
matrix as .
Then,
is equivalent to a Vandermonde matrix (Definition A-10.2 in §A-10.2) in the form of
. Similarly, let’s extract
the lower-half rows of
and denote this
matrix as .
Then,
is equivalent to a Vandermonde matrix (Definition A-10.2 in §A-10.2) in the form of
.
Now, let’s vertically rotate the rows of
by positions upward and
denote it as ; and vertically
rotate the rows of by
positions upward and denote
it as . And let’s denote the
-dimensional vector comprising
the first-half elements of
as , and the
-dimensional vector comprising
the second-half elements of
as . Then, computing
(i.e., decoding) is
equivalent to modifying
to (whose coefficient
vector is ) and then
computing (i.e., decoding) .
This is because:
# This is equivalent to evaluating the polynomial
at the following
distinct
-th roots of
unity:
# note
that
# where
contains the
coefficients of
the polynomial
Similarly, computing (i.e., decoding)
is equivalent to modifying
to (whose coefficient
vector is ) and then
computing (i.e., decoding) .
This is because,
# This is equivalent to evaluating the polynomial
at the following
distinct
-th roots of
unity:
# note
that
The above derivations demonstrate that ,
and .
Combining these two findings, we reach the conclusion that
: rotating the first-half
elements of the input vector by
positions to the left and the
second-half elements of it by
positions also to the left is equivalent to updating the plaintext polynomial
to
and then decoding it with
the decoding matrix .
However, now a new problem is that we cannot directly update the plaintext
to
,
because
is encrypted as an RLWE ciphertext. Therefore, we need to instead update the RLWE ciphertext components
to indirectly
by updating
to . 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 ,
our goal is to update to
such that decrypting it
gives the input vector .
That is, the following relation should hold:
Remember that in the RLWE cryptosystem (§B-3)’s alternative version (§B-4.4), the plaintext and
ciphertext pair have the following relation:
If we apply
in the above relation, we can derive the following relation:
This relation implies that if we decrypt the ciphertext
with
as the secret key,
then we get .
Therefore,
is the RLWE ciphertext we are looking for, because decrypting it and then decoding its plaintext
will give us the
input vector .
We can easily convert
into by
applying to
for each of
the and
polynomials. However, after that, notice that the decryption key of the RLWE ciphertext
has been
changed from to
. Thus, we need to additionally
switch the ciphertext ’s
key from , which is
equivalent to converting
into .
For this, we will apply the BFV key switching technique (Summary D-2.8) learned in §D-2.8 as
follows:
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:
, and update the original decoding matrix in Decoding2 as follows:
, where
is the rotation helper formula: ,
Suppose we have an RLWE ciphertext and a key-switching key as follows:
,
Then, the procedure of rotating the first-half elements of the ciphertext’s original input vector
by
positions to the left (in a wrapping manner among them) and the second-half elements of
by
positions to the left (in a wrapping manner among them) is as follows:
-
1.
- Update ,
to ,
.
-
2.
- Perform the following key switching (§D-3.8) from
to :
D-2.9.4 Encoding Example
Suppose we have the following setup:
The roots of
are , as
demonstrated as follows:
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
(complex numbers) and the
cyclotomic polynomials over
(ring).
Since are the roots
of the -th cyclotomic
polynomial over the
ring , they are also the
-th primitive roots of
unity of . Therefore,
their order (§A-4.1) is
as demonstrated as follows:
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 ,
generates all roots of the
-th cyclotomic polynomial.
Notice that in the case of the -th
cyclotomic polynomial ,
its roots
generate all -th
roots of unity as follows:
Among as the
roots of , let’s choose
as the base root to construct
the encoding matrix
and the decoding matrix
as follows:
#
where
Notice that Theorem A-11.5 (in §A-11.5) is demonstrated as follows:
Now suppose that we encode the following two input vectors (i.e., input vector slots) in
:
These two vectors are encoded as follows:
#
where
Note that the coefficients of the scaled polynomials
and
are still within the range
of the ciphertext domain
(which must hold throughout all homomorphic computations to preserve correctness).
We decode
and as
follows:
The decoded
and
match the expected values.
D-2.9.5 Rotation Example
Suppose we have the following setup:
The roots of
are , as
demonstrated as follows:
Among as the
roots of , let’s choose
as the base root to construct
the encoding matrix
and the decoding matrix
as follows:
Notice that Theorem A-11.5 (in §A-11.5) is demonstrated as follows:
Now suppose that we encode the following input vector (i.e., input vector slots) in
:
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:
is
encoded as follows:
#
where
Note that the coefficients of the scaled polynomials
are still within the range
of the ciphertext domain
(which must hold throughout all homomorphic computations to preserve correctness).
We decode
as follows:
The decoded matches the
expected rotated input vector .
In practice, we do not directly update
to ,
because we would not have access to the plaintext polynomial
unless we have the
secret key . Therefore,
we instead update
to ,
which is equivalent to homomorphically rotating the encrypted input vector slots. Then, decrypting
and decoding it
would output .
Source Code: Examples of BFV’s batch encoding and homomorphic input vector rotation can be
executed by running this Python script.