c++encryptioncryptographyseal

SEAL: How to read Relinkeys data in forms of modulo coefficients?


When running examples in SEAL (v3.6), I can print out polynomial coefficients of secret_key, public_key data using support functions

ofstream sk;
sk.open(filename, ios::binary);
for (uint64_t i = 0; i < poly_modulus_degree; i++)
{
    sk << secret_key.data()[i] << endl;
}
sk.close();

with the coefficient data layout follow moduli is same with Simple Encrypted Arithmetic Library (SEAL) and the seal::Ciphertext variable.

Output coefficients 60 bits as examples:

348362126124274227
287021082413421529
790977662641979136
532895062119300067
...

But I can not understand the forms of relin_keys and how to use its class's support methods to print relin_keys data in forms of polynomial coefficients? Thank for your help.


Solution

  • RelinKeys is derived from KSwitchKeys which contains a data member in the type of vector<vector<PublicKey>>. Since PublicKey is basically the same with Ciphertext, RelinKeys is simply a 2-dimensional vector of Ciphertext.

    The first dimension enumerates the relinearization key generated for a certain power of secret key. For example, by default only a relinearization key for the 2nd power of secret key is generated, therefore the first dimension usually has size 1. This is accessible by relin_keys.key(2) described by this method, which returns vector<PublicKey>.

    The second dimension corresponds to the decomposition method used to generated relinearization keys and to perform relinearization. The size of the second dimension is usually equal to context.first_context_data()->parms().coeff_modulus().size(). After this point, you should know how to print out each Ciphertext object.

    The following code should help:

    void print_ciphertext(const Ciphertext &ciphertext) {
        // code to print coefficients of a Ciphertext object
    }
    
    RelinKeys relin_keys;
    // ... generate keys ...
    
    for (std::size_t key_power = 2; relin_keys.has_key(key_power); key_power++) {
        for (auto &public_key: relin_keys.key(key_power)) {
            print_ciphertext(public_key.data());
        }
    }