Since we can't really choose which slots will be rotated, the general way to achieve this is more of a workaround:
Given seal::Ciphertext x, int steps and appropriate evaluator/encoder and keys as in the Seal Rotation Example (including Explanations) we can do the following:
- make a copy of x
seal::Ciphertext copy = x;
- rotate the copy
evaluator.rotate_vector_inplace(copy, steps, galoisKeys); (assuming you're using the CKKS scheme)
- multiply with a mask (plaintext with 0 or 1 in the slots)
std::vector<unsigned long int> mask = {1,1,1,1,1,0,0,0,0 /*...*/};
seal::Plaintext mask_ptxt;
encoder.encode(mask, mask_ptxt);
evaluator.multiply_plain_inplace(copy, mask_ptxt);
- multiply the original with the inverse mask
std::vector<unsigned long int> inv_mask = {0,0,0,0,0,1,1,1,1 /*...*/};
seal::Plaintext inv_mask_ptxt;
encoder.encode(inv_mask , inv_mask_ptxt);
evaluator.multiply_plain_inplace(x, mask_ptxt);
- add the original and rotated ciphertext together
evaluator.add_inplace(x,copy);