Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about the parameters #367

Closed
DylanWangWQF opened this issue Jul 7, 2021 · 3 comments
Closed

Question about the parameters #367

DylanWangWQF opened this issue Jul 7, 2021 · 3 comments

Comments

@DylanWangWQF
Copy link

DylanWangWQF commented Jul 7, 2021

Hi, team! @WeiDaiWD
I'm trying to move to SEAL (the previous used is HElib). I have some questions about select parameters to create context and keys.
First, I want to do some performance tests between SEAL and HElib, but something is wrong with the params (not that similar to HElib).
I was going to generate a 256-slot vector for batch encoding, encrypt and decrypt, but size_t poly_modulus_degree = 256; shows it's an invalid argument.
Then, I change to 1024., but the decrypted result is wrong.

Create Context: Done [1705 microseconds]
/
| Encryption parameters :
|   scheme: BFV
|   poly_modulus_degree: 1024
|   coeff_modulus size: 27 (27) bits
|   plain_modulus: 1038337
\

Batching enabled: true
Generating secret keys: Done [4 microseconds]
Generating public keys: Done [105 microseconds]
Number of slots: 1024
Plaintext matrix row size: 512
 Plaintext Vector: 

    [ 0, 1, 0, 1, ..., 0, 1, 0, 1 ]

Encode plaintext matrix: Done [10 microseconds]
Encrypt plain_matrix to encrypted_matrix: Done [175 microseconds]
Decode result: Done [58 microseconds]
Decrypt result: Done [15 microseconds]
 Decrypted Vector: 

    [ 992904, 441864, 440500, 244676, ..., 168071, 381196, 668442, 482075 ]

Basically, my questions:

  1. Can I set the slot_count = 256 in SEAL, less than 1024? Since in HElib, I need to find m,p,r like: Params param(/*m=*/12800, /*p=*/127, /*r=*/1, /*bits=*/119, /*c=*/2); \\ slot=256
  2. In Helib, bits is set to control the mul depth. In SEAL, How should I do? In my case, I will do matrix multiplication, the matrix elements are 0/1, so the plaintext_moduls could be a small value (in HElib, it's /*p=*/127). For the matrix multiplication, the number of multiplication is at most 1 or 2.
  3. Do we have to manage memory when doing operations in SEAL?
encrypted1.Reserve(3);
evaluator.MultiplyInplace(encrypted1, encrypted2);
  1. One more thing, in HElib or HEAAN, they use ZZX (ZZX.h in NTL) to represent the polynomial. what's that in SEAL? I propose this question is because I need to change my code to SEAL style, like the below codes.
    For example, some encode operations between vector and polynomial.
    in HElib:
ZZX*& poly = new zzX[length];
vector<vector<long>> lvals(length);
ea.encode(poly[k], lvals[k]);
ctxt.multByConstant(poly[k]);

in HEAAN:

ZZX*& poly =  new ZZX[length];
complex<double>** vals = new complex<double>*[length];
poly[i] = scheme.context.encode(vals[i], nslots, cBits);
result_ctxt = scheme.multByPoly(ctxt, poly[i], cBits);
  1. Does secret-key mode work in the same way as the public-key mode. In my case, I actually don't need the public key. The general workflow is: encrypt the matrix; multiplications and rotations; decrypt the result in another trusted party (who will also hold the secret key). Is there any sample code to introduce the secret-key mode?

Sry for so many questions. Sry for my noise.

@DylanWangWQF
Copy link
Author

This is the code, almost is the example code.

     EncryptionParameters parms(scheme_type::bfv);
    size_t poly_modulus_degree = 1024;
    parms.set_poly_modulus_degree(poly_modulus_degree);
    parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
    parms.set_plain_modulus(PlainModulus::Batching(poly_modulus_degree, 20));
    SEALContext context(parms);

    print_parameters(context);
    cout << endl;

    auto qualifiers = context.first_context_data()->qualifiers();
    cout << "Batching enabled: " << boolalpha << qualifiers.using_batching << endl;

    KeyGenerator keygen(context);
    SecretKey secret_key = keygen.secret_key();

    PublicKey public_key;
    keygen.create_public_key(public_key);

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

    size_t slot_count = batch_encoder.slot_count();
    cout << "Number of slots: " << slot_count << endl;
    size_t row_size = slot_count / 2;
    cout << "Plaintext matrix row size: " << row_size << endl;

    vector<uint64_t> vecMat(slot_count);
    for (size_t i = 0; i < slot_count; ++i)
    {
    	vecMat[i] = i % 2;
    }
    cout << " Plaintext Vector: " << endl;
    print_vector(vecMat);

    Plaintext plain_matrix;
    batch_encoder.encode(vecMat, plain_matrix);

    Ciphertext encrypted_matrix;
    encryptor.encrypt(plain_matrix, encrypted_matrix);

    Plaintext plain_result;
    vector<uint64_t> pod_result;

    decryptor.decrypt(encrypted_matrix, plain_result);
    batch_encoder.decode(plain_result, pod_result);

    cout << " Decrypted Vector: " << endl;
    print_vector(pod_result);

@DylanWangWQF DylanWangWQF changed the title Find propoer paramaters to create context and keys Question about the parameters Jul 7, 2021
@WeiDaiWD
Copy link
Contributor

WeiDaiWD commented Jul 9, 2021

Can I set the slot_count = 256 in SEAL, less than 1024? Since in HElib, I need to find m,p,r like: Params param(/m=/12800, /p=/127, /r=/1, /bits=/119, /c=/2); \ slot=256

In SEAL you set only the poly_modulus_degree, for BFV, that is also the number of slots. The HE security standard does not have parameters for degree 256. By default, SEAL will treat that as insecure. You may bypass the security check and use custom parameters by constructing SEALContext with extra input parameters. See this function. You can use SEALContext(params, true, sec_level_type::none).

In Helib, bits is set to control the mul depth. In SEAL, How should I do? In my case, I will do matrix multiplication, the matrix elements are 0/1, so the plaintext_moduls could be a small value (in HElib, it's /p=/127). For the matrix multiplication, the number of multiplication is at most 1 or 2.

The similar concept to "bits" is the total bit count of coeff_modulus in EncryptionParameters. This is configured by creating custom coeff_modulus with intended bit sizes.

Do we have to manage memory when doing operations in SEAL?
encrypted1.Reserve(3);
evaluator.MultiplyInplace(encrypted1, encrypted2);

No, Evaluator methods usually manages memory for output. Of course, encrypted1 must have size at least 2 to work as an input.

One more thing, in HElib or HEAAN, they use ZZX (ZZX.h in NTL) to represent the polynomial. what's that in SEAL? I propose this question is because I need to change my code to SEAL style, like the below codes.

In SEAL users don't need to manage polynomials, instead, only create Plaintext, Ciphertext, etc. Please follow the examples. You will see how your code in HElib or HEAAN are implemented in SEAL without the concept of polynomials.

Does secret-key mode work in the same way as the public-key mode. In my case, I actually don't need the public key. The general workflow is: encrypt the matrix; multiplications and rotations; decrypt the result in another trusted party (who will also hold the secret key). Is there any sample code to introduce the secret-key mode?

Yes, in examples. For instance, here.

@fionser
Copy link
Contributor

fionser commented Aug 5, 2021

Current SEAL's implementation is very different from HElib.
I strongly recommend to read papers about the full-RNS-variant of BFV.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants