【问题标题】:How to use CRT batch technique in Microsoft SEAL 3.1?如何在 Microsoft SEAL 3.1 中使用 CRT 批处理技术?
【发布时间】:2020-06-17 13:27:47
【问题描述】:

能否告诉我 SEAL 3.1 是否支持 PolyCRTBuilder 类?我正在尝试运行以下程序,但由于未在此范围内声明该类而失败。

/** 假设我有两个数组x = [1,2,3,4,5]xMean = [3,3,3,3,3]。我使用 PolyCRTBuilder(xCiphertext 和 xMeanCiphertext)组成并加密了这两个数组。如果我减去两个密文( xCiphertext MINUS xMeanCiphertext ),我应该得到 xResult = [-2, -1, 0, 1, 2] 但在同态减法之后,我得到 xResultDecrypted = [40959, 40960, 0 ,1, 2] 。我可以将溢出结果与普通模数集相关联,但是否有解决此问题的方法。这是代码: */

#include <iostream>
#include "seal/seal.h"
using namespace std;
using namespace seal;

/*
Helper function: Prints the parameters in a SEALContext.
*/
void print_parameters(shared_ptr<SEALContext> context)
{
    // Verify parameters

    if (!context)
    {
        throw invalid_argument("context is not set");
    }
    auto &context_data = *context->context_data();

    /*
    Which scheme are we using?
    */
    string scheme_name;
    switch (context_data.parms().scheme())
    {
    case scheme_type::BFV:scheme_name = "BFV";
        break;
    case scheme_type::CKKS:scheme_name = "CKKS";
        break;
    default:
        throw invalid_argument("unsupported scheme");
    }

    cout << "/ Encryption parameters:" << endl;
    cout << "| scheme: " << scheme_name << endl;
    cout << "| poly_modulus_degree: " << context_data.parms().poly_modulus_degree() << endl;

    /*
    Print the size of the true (product) coefficient modulus.
    */
    cout << "| coeff_modulus size: " << context_data.
        total_coeff_modulus_bit_count() << " bits" << endl;

    /*
    For the BFV scheme print the plain_modulus parameter.
    */
    if (context_data.parms().scheme() == scheme_type::BFV)
    {
        cout << "| plain_modulus: " << context_data.
            parms().plain_modulus().value() << endl;
    }

    cout << "\\ noise_standard_deviation: " << context_data.
        parms().noise_standard_deviation() << endl;
    cout << endl;
}

int main(){
    cout << "\nTotal memory allocated from the current memory pool: "<< (MemoryManager::GetPool().alloc_byte_count() >> 20) << " MB" << endl;
    EncryptionParameters parms(scheme_type::BFV);
    //EncryptionParameters parms;
    parms.set_poly_modulus_degree(4096);
    parms.set_coeff_modulus(coeff_modulus_128(4096));
    parms.set_plain_modulus(40961); ////Make the coefficient modulus prime>2n to enable CRT batching

    auto context = SEALContext::Create(parms);
    print_parameters(context);
    IntegerEncoder encoder(parms.plain_modulus());

    KeyGenerator keygen(context);
    PublicKey public_key = keygen.public_key();
    SecretKey secret_key = keygen.secret_key();
    // SEALContext context(parms);

    // KeyGenerator keygen(context);
    // auto public_key = keygen.public_key();
    // auto secret_key = keygen.secret_key();

    Encryptor encryptor(context, public_key);
    Evaluator evaluator(context);
    Decryptor decryptor(context, secret_key);

    PolyCRTBuilder crtbuilder(context);

    int slot_count = crtbuilder.slot_count();
    int row_size = slot_count / 2;

    vector<uint64_t> x_pod_matrix(slot_count, 0);
    x_pod_matrix[0] = 1;
    x_pod_matrix[1] = 2;
    x_pod_matrix[2] = 3;
    x_pod_matrix[3] = 4;
    x_pod_matrix[4] = 5;

    Plaintext x_plain_matrix;
    crtbuilder.compose(x_pod_matrix, x_plain_matrix);

    Ciphertext x_encrypted_matrix;

    encryptor.encrypt(x_plain_matrix, x_encrypted_matrix);

    vector<uint64_t> x_mean_pod_matrix(slot_count, 0);
    x_mean_pod_matrix[0] = 3;
    x_mean_pod_matrix[1] = 3;
    x_mean_pod_matrix[2] = 3;
    x_mean_pod_matrix[3] = 3;
    x_mean_pod_matrix[4] = 3;

    Plaintext x_mean_plain_matrix;
    crtbuilder.compose(x_mean_pod_matrix, x_mean_plain_matrix);

    Ciphertext x_mean_encrypted_matrix;

    encryptor.encrypt(x_mean_plain_matrix, x_mean_encrypted_matrix);

    evaluator.sub_plain(x_encrypted_matrix, x_mean_encrypted_matrix);

    // Decrypt x_encrypted_matrix
    Plaintext x_plain_result;

    decryptor.decrypt(x_encrypted_matrix, x_plain_result);

    vector<uint64_t> pod_result;

    crtbuilder.decompose(x_plain_result, pod_result);

    for(int i = 0; i < 5; i++)  {

        std::cout << pod_result[i] << '\n';

    }

  return 0;

}

【问题讨论】:

    标签: c++ encryption seal post-quantum-cryptography


    【解决方案1】:

    PolyCRTBuilder 已重命名为 BatchEncoder。查看 SEAL v3.1 中的 src/examples 目录(或较新版本中的 native/examples),您会看到很多示例。

    与您的问题有点相关:coeff_modulus_128 函数在 SEAL 中已经有一段时间不存在了; CoeffModulus::BFVDefault 函数提供了相同的功能。通过这些更改,您的代码甚至可以在 SEAL 3.5 中运行。

    【讨论】:

    • 非常感谢您的回答。它工作正常。顺便说一句,我们如何打印加密的密文以检查其多项式形式的性质?我已经为上面的代码尝试了 x_encrypted_matrix.to_string() 但它显示错误。而且,我们可以在将两个向量相乘后使用add_many函数通过CRT打包得到两个向量的内积吗?
    • 没有合理的方法来打印密文多项式。它们存储在 RNS 表示中(以每个 coeff_modulus 素数为模),也可以采用 NTT 转换形式(CKKS 的默认值)。此外,它们的尺寸很大,所以我不确定你会从检查中学到什么。对于您关于插槽总和的其他问题,我建议您完全创建一个单独的 SO 问题。这必须使用重复(对数多次)旋转和加法来完成;需要明确的是,add_many 不是您要找的。​​span>
    • 非常感谢您的回复。对于我,这说得通。我将提出一个新的 SO 问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2017-02-11
    • 2015-07-03
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多