zeroing out slots in SEAL ciphertext I've been messing around with SEAL library for a few days and I've got a following question.
I've got a bunch of datapoints [x_1, ..., x_n], n &lt; poly_mod_deg of type 'double' and I use batch encoding and CKKS sceheme to calculate
their average and variance. Calculating average works fine and I like the result, but I would like to calculate variance in more efficient way.
To explain what I mean:
Going into variance calculation I have following data:
Encrypted([x_1, x_2, x_3, ..., x_n, 0, ..., 0]) and
Encrypted([x_avg, x_avg, x_avg, ..., x_avg]) (*)
Next I calculate their difference and get something like:
Encrypted([x_1 - x_avg, x_2 - x_avg, x_3 - x_avg, ..., x_n - x_avg, -x_avg, -x_avg, ..., -x_avg]) (**)
Then I square and get:
Encrypted([(x_1 - x_avg)^2, (x_2 - x_avg)^2, (x_3 - x_avg)^2, ..., (x_n - x_avg)^2, x_avg^2, x_avg^2, ..., x_avg^2]) (***)
And then I sum first n values using n left by-one rotations and divide the result by n to finally get the variance.
-----------------------------------------------------------------

This works fine for small n. But I want to zero-out useless components at (*) or (**) or (***) so that after squaring I'd get the following:
Encrypted([(x_1 - x_avg)^2, (x_2 - x_avg)^2, (x_3 - x_avg)^2, ..., (x_n - x_avg)^2, 0, ..., 0])
I want that because then I'm able to calculate their sum using only log2(poly_mod_deg/2) sumations using technique described in https://www.youtube.com/watch?v=XaYEHnaAg8M&amp;t=47m29s
Is it possible to achieve that in simple, secure in efficient way?
I've tried to multiply (*) or (**) or (***) by [1.0, 1.0, ..., 1.0, 0.0, ..., 0.0], where all but the first n components are zero.
It didn't work because compiler complained with 'result ciphertext is transparent' and
aborted the mission and I didn't like that solution anyway since it uses one more multiplication, which hopefully is excessive.
Increasingly desperate I also tried to copy encrypted zero from Encrypted([x_1, x_2, x_3, ..., x_n, 0, ..., 0]) into last components of
Encrypted([x_avg, x_avg, x_avg, ..., x_avg]).
 I did something like:
c_zero = Encrypted([x_1, x_2, x_3, ..., x_n, 0, ..., 0])[n+1];
while n &lt; i &lt; poly_mod_deg:
     Encrypted([x_avg, x_avg, x_avg, ..., x_avg])[i] = c_zero;
     i++;
But i guess this stuff just doesn't work this way, since printing out last 20 or 30 values of Encrypted([x_1, x_2, x_3, ..., x_n, 0, ..., 0]) shows no repetition.
On that note, this also probably means that i always have to inform &quot;server-side&quot; about the number of encrypted datapoints in ciphertext? How unsafe is that?
I didn't want to bloat the post with code, so it's here: https://pastebin.com/Uy0wdgG9. Also deleted comments from the code, since they were in my native tongue. Sorry.
Also on the chance that someone from the SEAL team sees this: great job,  fun stuff!
As a caveat, I have never worked with Microsoft SEAL. But the following may still be useful.
The formula for the variance of a finite dataset $(x_1,\dots, x_n)$ can be written as:
$$\sigma^2 = \frac{1}{n}\sum_{i = 1}^n(x_i - \mu)^2$$
where:
$$\mu = \frac{1}{n}\sum_{i = 1}^n x_i$$
Note that $n\mu = \sum_{i = 1}^n x_i$ --- I will switch between these two expressions freely.
One can algebraically manipulate the expression for $\sigma^2$ to the following expression:
$$\sigma^2 = \frac{n\sum_{i = 1}^n x_i^2 - \sum_{i = 1}^n x_i}{n^2}$$
(check that this is an identical formula)!
This expression can be computed more easily as follows. Let $\vec{x} = (x_1,x_2,\dots, x_n, 0,0,\dots,0)$ be your plaintext vector, where I assume $n$ is a secret parameter (things are easier if this is not the case, but not by much).
Let $c$ be the encryption of $\vec{x}$.

Compute the ciphertext vector $c_{n\mu} =(n\mu, n\mu,\dots, n\mu)$ via your rotation trick (you already do this)

Square $c$ coordinate-wise to get the vector $c_{x_i^2}$ with &quot;slots&quot; $(x_1^2,\dots, x_n^2, 0^2,\dots, 0^2)$

Apply your rotation trick to $c_{x_i^2}$ get the vector $c_{\sum_i x_i^2} = (\sum_i x_i^2, \sum_i x_i^2,\dots, \sum_i x_i^2)$


Now, any slot of $c_{n\mu}$ (they all take the value $n\mu$), any slot of $c_{\sum_i x_i^2}$ (they all take the value $\sum_{i = 1}^n x_i^2$), and $N$ are sufficient to compute the variance via the formula:
$$\sigma^2 = \frac{n\sum_{i = 1}^n x_i^2 - n\mu}{n^2}$$
If you can defer this computation to decryption (even as $N\to\infty$ it should remain quite efficient, like 4 arithmetic operations) then you should do that (and the ciphertext can take the form $(c_{n\mu}[0], c_{\sum_i x_i^2}[0], c_N)$, where $c_N$ is a ciphertext encrypting $N$).
If not, the problem is reduced to being able to extract (any) &quot;slot&quot; of a SEAL ciphertext, which is likely quite possible without doing more multiplications.
This leads to a number of different situations:

If $N$ must be kept secret and you cannot defer this computation, you then must clearly compute the multiplications $c_N\times c_N$, $c_N\times c_{\sum_i x_i^2}$ (which can be done in parallel, increasing multiplicative depth by 1), and the division by $c_N\times c_N$, leading to a computation of multiplicative depth 3 (the same complexity as your &quot;bad&quot; situation of zeroing things by multiplying by the ciphertext encryption $(1,1,\dots,1,0,0,\dots,0)$.)

If $N$ can be public, you only have to compute scalar multiplications, so can be done in (total) multiplicative depth 1

If you can defer the computation to decryption, you can do the entire computation in total multiplicative depth 1 again (even while keeping $N$ secret).


All of this discussion is assuming that you want to minimize multiplicative depth. It looks like you are using CKKS as your underlying scheme, and I can't remember if its complexity is controlled by multiplicative depth or something more esoteric (such as GSW's way of computing the complexity of multiplications). Still, the two points of:

Rewriting computations to be algebraically identical, while (hopefully) simpler to compute homomorphically
Deferring (small) parts of the computation for execution on the client when possible

are worth keeping in mind as generic ways to optimize things.