- Reference 1: Bootstrapping for BGV and BFV Revisited [14]
- Reference 2: Bootstrapping for HELib [15]
- Reference 3: A Note on Lower Digits Extraction Polynomial for Bootstrapping [16]
- Reference 4: Fully Homomorphic Encryption for Cyclotomic Prime Moduli [17]
In BFV, continuous ciphertext-to-ciphertext multiplication increases the noise in a multiplicative manner, and once the noise overflows the message bits, then the message gets corrupted. Bootstrapping is a process of resetting the grown noise.
In this subsection, we will assume the plaintext modulus , a prime number. Although can be generalized as where and (Summary D-2.3 in §D-2.3), we will explain BFV’s bootstrapping assuming for simplicity, and then generalize as in the end.
The core idea of the BFV bootstrapping is to homomorphically evaluate a special polynomial , a digit extraction polynomial modulo (for some positive integer ), where the input to is a noisy plaintext value modulo and the output is a noise-free plaintext value modulo , where the noise located at the least significant digits in a base- (prime) representation gets zeroed out. For example, . Given the noise resides in the least significant digits in base- representation, we can homomorphically recursively evaluate total times in a row, which zeros out the least significant (base-) digits of input . To homomorphically evaluate the noisy plaintext through , we need to first switch the plaintext modulus from to , where . The larger is, the more likely that the noise gets successfully zeroed out, but instead the computation overhead becomes larger. If is small, the computation gets faster, but the digit-wise distance between the noise and the plaintext gets smaller, potentially corrupting the plaintext during bootstrapping, because removing the most significant noise digit may remove the least significant plaintext digit as well. Therefore, should be chosen carefully.
The technical details of the BFV bootstrapping procedure are as follows. Suppose we have an RLWE ciphertext , where , and (i.e., the plaintext modulus is a prime).
# where is a modulo- ciphertext that encrypts a modulo- plaintext whose scaling factor
# is some integer polynomials to represent the coefficient values that wrap around
Let’s see how we derived the above relation. Suppose we compute , whose output will be . Now, instead of using the plaintext secret key , we use an encrypted secret key , where is a plaintext modulo , its scaling factor , and the ciphertext encrypting is in modulo . Then, the result of homomorphically computing will be an encryption of , where stands for the wrapping-around coefficient values of the multiples of .
Notice that we did not reduce by modulo during homomorphic decryption (without modulo- reduction), because such a homomorphic modulo reduction is not directly doable. Instead, we will handle in the later digit extraction step.
For simplicity, we will denote .
, where is the batch encoding matrix that converts input vector slot values into polynomial coefficients (Summary D-2.9.3 in §D-2.9.3).
In other words, we can view the ciphertext whose plaintext modulus is and scaling factor as another ciphertext whose plaintext modulus is and scaling factor .
Notice that the final ciphertext ’s scaling factor stays the same as before the bootstrapping, while the original noises and have been eliminated. On the other hand, the homomorphic operation of CoeffToSlot, digit extraction, and SlotToCoeff must have accumulated additional noises, but their size is fixed and smaller than and .
Next, we will explain each step more in detail.
The first step of the BFV bootstrapping is to do a modulus switch from to some prime power modulus where . Before the bootstrapping, suppose the encrypted plaintext with noise is . Then, after the modulus switch from , the plaintext would scale down to , where roughly contains plus the modulus switching noise of the plaintext’s scaling factor . The goal of the BFV bootstrapping is to zero out this noise .
Let’s denote the modulus-switched noisy plaintext as . We further denote polynomial ’s each degree term’s coefficient as base- number as follows:
Then, is a base- number comprising digits:
We assume that the highest base- digit index for the noise is , which is equivalent to the noise budget, and the pure plaintext portion solely resides at the base- digit index (i.e., the most significant base- digit in modulo ). Given this assumption, we extract the noise-free plaintext by computing the following:
# where the noise is assumed to be smaller than
The above formula is equivalent to shifting the base- number by digits to the right (and rounding the decimal value). However, remember that we don’t have direct access to polynomial unless we have the secret key to decrypt the ciphertext storing the plaintext. Instead, we can only derive as an encrypted form. Specifically, we can homomorphically decrypt the modulus-switched ciphertext by using the encrypted secret key as a bootstrapping key. For this ciphertext , the plaintext modulus is , the plaintext scaling factor is , and the ciphertext modulus is . With this encrypted secret key , we homomorphically decrypt the encrypted as follows:
# is some integer polynomials to represent the coefficient values that wrap around modulo as multiples of
During this homomorphic decryption, we did not reduce the plaintext result by modulo , because the homomorphic decryption is a ciphertext-to-plaintext multiplication and addition done in the ciphertext modulus (not ) by using and as plaintexts (with the plaintext modulus ) and as a ciphertext (with the ciphertext modulus ). This is why the wrapping term is preserved in the plaintext after the homomorphic decryption– we will handle this term at the later stage of bootstrapping. Also, notice that the computation of would not generate much noise. This is because is a plaintext modulo , and thus the new noise generated by ciphertext-to-plaintext multiplication is (where is the encryption noise of ). Since the ciphertext modulus , .
Once we have derived , our next step is to remove the noise in the lower digits (in terms of base- representation) of each for . This is equivalent to transforming noisy into noise-free where . BFV’s solution to do this is to design a -degree polynomial function which computes the same logical result as . We will later explain how to design this polynomial by using the digit extraction polynomial (§D-2.11.5).
However, in order to homomorphically evaluate this polynomial at each coefficient given the ciphertext , we need to move polynomial ’s each coefficient to the input vector slots of an RLWE ciphertext. This is because BFV supports homomorphic batched operations based on input vector slots of ciphertexts as operands. Therefore, we need to evaluate the noise-removing polynomial based on the values stored in the input vector slots of a ciphertext.
In the next sub-section, we will explain the CoeffToSlot procedure, a process of moving polynomial coefficients into input vector slots of a ciphertext homomorphically.
The goal of the CoeffToSlot step is to homomorphically move polynomial ’s coefficients to input vector slots.
In Summary D-2.9.3 (in §D-2.9.3), we learned that the encoding formula for converting a vector of input slots into a vector of polynomial coefficients is: , where is a basis of the -dimensional vector space crafted as follows:
# where the rotation helper function
Therefore, given the input ciphertext , we can understand its input vector slots as storing some values such that multiplying to each of them turns them into a coefficient of polynomial . This implies that if we homomorphically multiply to the input vector slots of , then the resulting ciphertext’s -dimensional input vector slots will contain the coefficients of , which is equivalent to moving the coefficients of to the input vector slots. Therefore, the CoeffToSlot step is equivalent to homomorphically computing . We can homomorphically compute matrix-vector multiplication by using the technique explained in §D-2.10.
After the CoeffToSlot step, we can homomorphically eliminate the noise in the lower base- digits of each by homomorphically evaluating the noise-removing polynomial (to be explained in the next subsection).
After we get noise-free coefficients of , we need to move them back from the input vector slots to their original coefficient positions. This step is called SlotToCoeff, which is an exact inverse procedure of CoeffToSlot. We also learned in Summary D-2.9.3 (in §D-2.9.3) that the inverse matrix of is , where:
Therefore, the SlotToCoeff step is equivalent to homomorphically multiplying to the output of the noise-eliminating polynomial evaluation.
In the next subsection, we will learn how to design the core algorithm of BFV, the noise elimination polynomial, based on the digit extraction polynomial .
Remember we defined polynomial as the scaled noisy plaintext: , and each is the -th coefficient of (where ). The goal of the digit extraction step is to homomorphically zero out the lower (base-) digits of each , where the noise resides.
First, we always think of as a base- number (since this is a modulo- value) as follows:
Next, we define a new notation that denotes in a different way as follows:
, where , and , and is ’s least significant base- digit index whose value is non-zero after digit index 0. Therefore, each is mapped to a unique set of .
Next, we define a lifting polynomial in terms of and its associated as follows:
Verbally speaking, processes in such a way that it keeps (i.e., ’s value at the base- digit index 0) the same as before, then finds the next least significant base- digit whose value is non-zero (whose digit index is denoted as ) and zeros it, during which the subsequent higher significant base- digits may get updated to any arbitrary values (i.e., the function doesn’t care about those values whose base- digit index is higher than because they fall outside the modulo range).
We will show an example of how is updated if it is evaluated by the function recursively total times in a row as follows:
1st Recursion: #
2nd Recursion: #
3rd Recursion: #
-th Recursion: #
In the above recursive computation, notice that the order of using function is specifically . We choose this specific order because we assume that for the initial input , we don’t know its associated value (i.e., the least significant base- digit index whose value is non-zero after digit index 0). If we choose the order , then regardless of the value of , we get the universal guarantee that the final output will be (i.e., the value of the base- digit index 0).
Now, we define the digit extraction function as follows:
Notice that is equivalent to zeroing out the least significant base- digit of . Let’s see what happens if we recursively evaluate at for (total times):
1st Recursion:
2nd Recursion:
3rd Recursion:
-th Recursion:
As shown above, recursively evaluating at for (total times) is equivalent to zeroing out the least significant (base-) digits modulo .
By recursively applying the digit extraction function as above, we can zero out the noise stored at the least significant (base-) digit indices.
Now, our final remaining task is to design the actual lifting polynomial that implements .
Designing : We will derive based on the following steps.
, where , is the least significant base- digit’s index of which has a non-zero value, and .
Basically, can be any number in whose base- representation has 0s between the base- digit index greater than 0 and smaller than .
Proof. Fermat’s Little Theorem states for all and prime . Therefore, . □
Proof.
□
Proof.
can be expressed as a base- number as follows:
Based on step 3’s claim (), we know that the value of depends only on (given and are fixed). Therefore, we can imagine that there exists some function whose input is and the output is . Alternatively, we can imagine that there exist different functions such that each is a polynomial whose input is and the output is , and . The input and output domain of each polynomial is . Therefore, we can design each as a -degree polynomial and derive each based on polynomial interpolation (§A-15) by using coordinate values.
Note that whenever we increase to , we add a new polynomial . However, the previous polynomials stay the same as before, because increasing by 1 only adds a new base- constant for the highest base- digit, while keeping the lower-digit constants the same as before. Therefore, the polynomials , each of which computes , also stay the same as before. □
Proof.
According to step 2’s claim (), we know that the following base- representation of :
will be the following:
, since the least significant base- digit of in the base- representation is always . Thus, the formula in step 4’s claim:
can be further concretized as follows:
□
Proof. Remember that in step 1, we defined as: . Therefore, . This implies that for each polynomial , the following is true:
We can further derive the following:
(where )
The above is true because:
(for some integer )
# multiplying to both sides
# and differ by some multiple of
Therefore, .
Now, given step 5’s claim (), we can derive the following:
# applying step 5’s claim
# since
□
The above relation implies that is equivalent to the least significant base- digit of (according to step 6’s claim). Therefore, if we plug in into and regard , then the output is some number whose least significant base- digit is and the 2nd least significant base- digit is . As we recursively apply the output back to and increment by 1, we iteratively zero out the 2nd least significant base- digit, the 3rd least significant base- digit, and so on. We repeat this process for times to zero out the upper base- digits, keeping only the least significant digit as it is (i.e., ). Therefore, is a valid lifting polynomial that can be iteratively used to extract the least significant digit of .
We use as the internal helper function within the digit extraction function that calls a total times.
Remember that homomorphically decrypting outputs an encryption of , whose entire value is bigger than . The final result of homomorphic digit extraction is equivalent to zeroing out the least significant (base-) digits of the input value . Therefore, at the end of digit extraction, we get a ciphertext that encrypts , where is a polynomial with coefficients which are some multiples of to account for the wrapping values of .
Therefore, the output of the digit extraction and SlotToCoeff steps is the ciphertext , where the plaintext modulus is and the plaintext scaling factor ( as we derived in §D-2.11.3). However, our desired outcome of the BFV bootstrapping is a noise-removed ciphertext whose plaintext modulus is and the plaintext scaling factor is . Without doing any actual additional computation, we can view the above ciphertext as an encryption of plaintext modulo whose scaling factor is . This is because:
Therefore, we can view the above ciphertext as whose plaintext modulus is and scaling factor , because the underlying ciphertext’s structure of these two viewpoints is identical. This leads to the corollary that evaluating the digit extraction function (§D-2.11.5) at recursively total times is logically equivalent to the noise elimination and plaintext modulus switch () as follows:
We can optionally design a more precise rounding-based function by modifying to as follows:
Generalization of : We have explained the BFV bootstrapping with the assumption that the plaintext modulus is a prime number. However, we can generalize as where can be any positive integer. The benefit of choosing with a small instead of with a big is the efficient noise management of the digit extraction process. As digit extraction requires many ciphertext-to-plaintext multiplications with , using a small generates a smaller noise during the homomorphic operations.
We summarize the BFV bootstrapping procedure (with the generalization of ) as follows.
Summary D-2.11.7 BFV Bootstrapping
Suppose we have an RLWE ciphertext , where and (i.e., the plaintext modulus is a power of some prime), , and .
# where , which is a modulus switch noise plus a rounding noise caused by treating .
# where
Now, we denote the modulus-switched noisy plaintext polynomial as .
, where is the batch encoding matrix (Summary D-2.9.3 in §D-2.9.3).
# where , and is ’s least significant base- digit index whose value is non-zero after digit index after digit index
# a -degree polynomial recursively used to finally extract the value
We homomorphically evaluate the digit extraction polynomial for recursively total times at each coefficient of stored at input vector slots, which zeros out the least significant (base-) digits of as follows:
, provided ’s each coefficient . At this point, each input vector slot contains the noise-removed coefficient .
The output of the previous step is , where , which is a modulo- ciphertext encrypting a modulo- plaintext with the scaling factor . Without any additional computation, we can theoretically view this ciphertext as a modulo- ciphertext encrypting a modulo- plaintext with the scaling factor . This is because:
For these two viewpoints, their underlying ciphertext structure is identical. Therefore, the digit extraction function (§D-2.11.5) at recursively total times is logically equivalent to the noise elimination and plaintext modulus switch () as follows:
A more precise rounding-based logic can be designed by modifying to as follows:
Necessity of Homomorphic Decryption: Suppose that we performed the BFV bootstrapping without homomorphic decryption. Then, the input to the digit extraction step would be , not . This is because the ciphertext encrypts , where . Therefore, applying the CoeffToSlot transformation to will store the coefficients of , not the coefficients of . In order to preserve the noise as well, we homomorphically decrypt by using an encrypted secret key to make it .