snucrypto / HEAAN

Other
359 stars 94 forks source link

Scheme::encode / Scheme::decode #34

Open gamma-2017 opened 4 years ago

gamma-2017 commented 4 years ago

Should't Scheme::encode then Scheme::decode give my values back?

Rephrasing the question: why does Scheme::encode call ring::encode with logq+logQ ? Shouldn't it pass logp and logq... Something is strange there. Interestingly, encrypt then decrypt somehow repairs this deficiency...

The following code (extended from Testscheme::testMult) should work and produce mmult2 roughly equal to mmult. But it does not, unless you remove the // comments.

srand(time(NULL));
SetNumThreads(8);
TimeUtils timeutils;
Ring ring;
SecretKey secretKey(ring);
Scheme scheme(secretKey, ring);

long n = (1 << logn);
complex<double>* mvec1 = EvaluatorUtils::randomComplexArray(n);
complex<double>* mvec2 = EvaluatorUtils::randomComplexArray(n);
complex<double>* mmult = new complex<double>[n];
for(long i = 0; i < n; i++) {
    mmult[i] = mvec1[i] * mvec2[i];
}

Plaintext pmult;
scheme.encode( pmult, mmult, n, logp, logq, 2.0 );
// pmult.logp += logQ;
// pmult.logq += logQ;
complex<double>* mmult2 = scheme.decode( pmult );
for (long i=0; i<n; i++) { cout << "[" << i << "]=" << mmult[i] << "=" << mmult2[i] << endl; }
/*
Ciphertext cmult;
scheme.encrypt( cmult, mmult, n, logp, logq, 2.0 );
mmult2 = scheme.decrypt( secretKey, cmult );
for (long i=0; i<n; i++) { cout << "[" << i << "]=" << mmult[i] << "=" << mmult2[i] << endl; }
cout << std::make_pair(&pmult,&scheme) << endl;
//*/
KyoohyungHan commented 4 years ago

why does Scheme::encode call ring::encode with logq+logQ?

To reduce the noise during encryption process, the encryption key is in modulus Qq. This means that after encryption we need to scale down to q. For this reason, encode process call ring::encode with logq+logQ.

If you want to test encode/decode process only, it would be better to call ring::encode.

gamma-2017 commented 4 years ago

Ok, I understand why logq+logQ comes in.

But then Scheme::encode is the wrong place. The produced plaintext obtains the wrong META info logp/logq and I cannot get it with the desired logp/logq. Instead I would change the calls of Scheme::encode in the procedures Scheme::encrypt*. BTW I have not understood yet, where the bogus META info is "repaired" in the encrypt/decrypt cycle; maybe there is a second misuse. Notice that the plaintext in the encrypt/decrypt cycle has two different "interpretations": between encode and encryptMsg its "true" params are plain.logp+logQ,plain.logq+logQ and later between decryptMsg and decode the "true" params are plain.logp,plain.logq. [I think I could modify the code in my sense, but I want to discuss it here to exclude possible other mismatches.]

Also, for clean programming, I should not have to use a lower-level procedure here.

KyoohyungHan commented 4 years ago

@gamma-2017 you are right. This should be revised. But I am not working on this code now. I will try to make pull request if I have some time for that. Thanks :-)

gamma-2017 commented 4 years ago

Thanks for your consideration and fast responses.

Is someone else working on the code now? Could you provide me a direct contact?

At present, I am modifying lots of things in a local copy, partly to better understand the library and partly to improve its usability (so far by adding assert-s and some operator<< additions for printing Plaintext and Ciphertexts).

KyoohyungHan commented 4 years ago

@gamma-2017 I think @du1204 is currently working on this code. You are right... there are many things to revise for clean programming and debugging things :-(

kmmate commented 4 years ago

Hi! Did you find a way in HEAAN-1.0 to have scheme::decode(scheme::encode(z))\approx z or at least scheme::decrypt(scheme::encrypt(z))\approx z ?

kmmate commented 4 years ago

@KyoohyungHan do you have any suggestion? Thanks!

KyoohyungHan commented 4 years ago

@KyoohyungHan do you have any suggestion? Thanks!

In case of encode and decode there is some issue from using P, but encrytion and decryption should give you correct answer.

It means that scheme::decrypt(scheme::encrypt(z))\approx z.

kmmate commented 4 years ago

It turned out that both encode-decode and encrypt-decrypt work well in the HEAAN-1.0 library. Only the example in the README is not compatible with HEAAN-1.0. To make the README example work with HEAAN-1.0 one needs the following changes in the README:

long slots = n; should be long slots = n/2;; and

 Ring ring;
 SecretKey secretKey(ring);
 Scheme scheme(secretKey, ring);

should be

int h = 64;
Context context(logn, logq);
SecretKey secretKey(logn, h);
Scheme scheme(secretKey, context);

; and

instead of n, one should pass slots to the scheme.encrypt.