The Learning With Errors problem is the basis of a few cryptosystems, and a foundation for many fully homomorphic encryption (FHE) schemes. In this article I’ll describe a technique used in some of these schemes called *modulus switching*.

In brief, an LWE sample is a vector of values in for some , and in LWE cryptosystems an LWE sample can be modified so that it hides a secret message . Modulus switching allows one to convert an LWE encryption from having entries in to entries in some other , i.e., change the modulus from to .

The reason you’d want to do this are a bit involved, so I won’t get into them here and instead back-reference this article in the future.

## LWE encryption

Briefly, the LWE encryption scheme I’ll use has the following parameters:

- A plaintext space , where is a positive integer. This is the space that the underlying message comes from.
- An
*LWE dimension*. - A discrete Gaussian
*error distribution*with a mean of zero and a fixed standard deviation.

An LWE secret key is defined as a vector in (uniformly sampled). An LWE ciphertext is defined as a vector , sampled uniformly over , and a scalar , where is drawn from and all arithmetic is done modulo .

Without the error term, an attacker could determine the secret key from a polynomial-sized collection of LWE ciphertexts with something like Gaussian elimination. The set of samples looks like a linear (or affine) system, where the secret key entries are the unknown variables. With an error term, the problem of solving the system is believed to be hard, and only exponential time/space algorithms are known.

However, the error term in an LWE encryption encompasses all of the obstacles to FHE. For starters, if your message is and the error distribution is wide (say, a standard deviation of 10), then the error will completely obscure the message from the start. You can’t decrypt the LWE ciphertext because you can’t tell if the error generated in a particular instance was 9 or 10. So one thing people do is have a much smaller *cleartext* space (actual messages) and encode cleartexts as plaintexts by putting the messages in the higher-order bits of the plaintext space. E.g., you can encode 10-bit messages in the top 10 bits of a 32-bit integer, and leave the remaining 22 bits of the plaintext for the error distribution.

Moreover, for FHE you need to be able to add and multiply ciphertexts to get the corresponding sum/product of the underlying plaintexts. One can easily see that adding two LWE ciphertexts produces an LWE ciphertext of the sum of the plaintexts (multiplication is harder and beyond the scope of this article). Summing ciphertexts also sums the error terms together. So the error grows with each homomorphic operation, and eventually the error may overtake the message, at which point decryption fails. How to deal with this error accumulation is 99% of the difficulty of FHE.

Finally, because the error can be negative, even if you store a message in the high-order bits of the plaintext, you can’t decrypt by simply clearing the low order error bits. In that case an error of -1 would result in a corrupted message. Instead, to decrypt, we *round *the value to the nearest multiple of , where $k$ is the number of bits “reserved” for error, as described above. In particular, decryption will only succeed if the error is small enough in absolute value. So to make this work in practice, one must coordinate the encoding scheme (how many bits to reserve for error), the dimension of the vector , and the standard deviation of the error distribution.

## Modulus switching

With a basic outline of an LWE ciphertext, we can talk about modulus switching.

Start with an LWE ciphertext for the plaintext . Call it , where

Given , we would like to produce a vector (all that has changed is I’ve put a prime on all the terms to indicate which are changing, most notably the new modulus ) that also encrypts , without knowing or , i.e., without access to the secret key.

**Failed attempt: **why not simply reduce each entry in the ciphertext vector modulo ? That would set and . Despite the fact that this operation produces a perfectly valid equation, it won’t work. The problem is that taking destroys part or all of the underlying message. For example, say is a 12-bit number stored in the top 12 bits of the plaintext, i.e., . If , then the message is a multiple of already, so the proposed modulus produces zero.

For this reason, we can’t hope to perfectly encrypt , as the output ciphertext entries may not have a modulus large enough to represent at all. Rather, we can only hope to encrypt *something like* “the message that’s encoded in , but instead with stored in lower order bits than originally used.” In more succinct terms, we can hope to encrypt . Indeed, the operation of shifts up by many bits (temporarily exceeding the maximum allowable bit length), and then shifting down by many bits.

For example, say the number is stored in the top 3 bits of a 32-bit unsigned integer (), i.e., and . Then , which stores the same underlying number , but in the top three bits of a 10-bit message. In particular, is in the same “position” in the plaintext space, while the plaintext space has shrunk around it.

Side note: because of this change to the cleartext-to-plaintext encoding, the decryption/decoding steps before and after a modulus switch are slightly different. In decryption you use different moduli, and in decoding you round to different powers of 2.

So the trick is instead to apply to all the entries of the LWE ciphertext vector. However, because the entries like use the entire space of bits in the plaintext, this transformation will not necessarily result in an integer. So we can round the result to an integer and analyze that. The final proposal for a modulus switch is

Because the error growth of LWE ciphertexts permeates everything, in addition to proving this transformation produces a valid ciphertext, we also have to understand how it impacts the error term.

## Analyzing the modulus switch

The statement summarizing the last section:

**Theorem:** Let be an LWE ciphertext encrypting plaintext with error term . Let . Then (where rounding is performed entrywise) is an LWE encryption of , provided is an integer.

*Proof.* The only substantial idea is that , where . This is true by the definition of rounding, but that particular way to express it allows us to group the error terms across a sum-of-rounded-things in isolation, and then everything else has a factor of that can be factored out. Let’s proceed.

Let , where and likewise for . need to show that , where is a soon-to-be-derived error term.

Expanding and using the “only substantial idea” above, we get

For some with magnitude at most . Continuing to expand, and noting that is related to the only modulo , we have

Because we’re switching moduli, it makes sense to rewrite this over the integers, which means we add a term for some integer and continue to expand

The terms with are still missing their rounding, so, just like , rewrite as , expanding, simplifying, and finally reducing modulo to get

Define the square bracketed term as , and we have proved the theorem.

The error after modulus switching is laid out. It’s the original error scaled, plus at most terms, each of which is at most . However, note that this is larger than it appears. If the new modulus is, say, , and the dimension is , then in the worst case the error right after modulus switching will leave us only bit left for the message. This is not altogether unrealistic, as production (128-bit) security parameters for LWE put around 600. But it is compensated for by the fact that the secret is chosen uniformly at random, and the errors are symmetric around zero. So in expectation only half the bits will be set, and half of the set bits will have a positive error, and half a negative error. Using these facts, you can bound the probability that the error exceeds, say, using a standard Hoeffding bound argument. I further believe that the error is bounded by . I have verified it empirically, but haven’t been able to quite nail down a proof.

Until next time!