Closed patriciaOrtuno28 closed 2 years ago
Hi @patriciaOrtuno28,
It looks like there's a bug in the way you're performing relinearization and rescaling. Specifically, the library has an 'overload' option for most functions that can accept a destination parameter or, if not provided, returns a corresponding CipherText
or PlainText
containing the result of the function called.
For example, when you perform relinearization you're not specifying a destination parameter nor capturing the output of the function. So your call:
evaluator.relinearize(rA, relinKey);
Is internally creating a copy rA
, performs relinearization on the copy, and returns the copy - but you're not capturing it (thrown away).
For both of your calls to relinearize
and rescaleToNext
, you should either pass in a destination parameter or use the output that it returns (if you don't supply a destination parameter). For example:
const rARelinDest = seal.CipherText();
evaluator.relinearize(rA, relinKey, rARelinDest);
// or
const rARelinDest = evaluator.relinearize(rA, relinKey);
Hi @s0l0ist ,
Thank you for your help, it worked perfectly fine. I was also missing the modulus switching for the parmsId. I'll attach the new code just in case someone has the same doubt in the future.
// Turn N into a PlainText
const NPlaintext = seal.PlainText();
const NArray = Float64Array.from([N]);
encoder.encode(NArray, scale, NPlaintext);
// Compute rA = N*Sxy
NPlaintext.setScale(cipherTextSxy.scale);
const NPlaintextModSwitch = evaluator.plainModSwitchToNext(NPlaintext);
let rA = seal.CipherText();
evaluator.multiplyPlain(cipherTextSxy, NPlaintextModSwitch, rA);
const rARelin = evaluator.relinearize(rA, relinKey);
const rARescale = evaluator.rescaleToNext(rARelin);
// Compute rB = Sx*Sy
let rB = seal.CipherText();
evaluator.multiply(cipherTextSx, cipherTextSy, rB);
const rBRelin = evaluator.relinearize(rB, relinKey);
const rBRescale = evaluator.rescaleToNext(rBRelin);
// Compute rAB = rA - rB
let rAB = seal.CipherText();
rBRescale.setScale(rARescale.scale);
const rBRescaleModSwitch = evaluator.cipherModSwitchTo(rBRescale, rARescale.parmsId);
evaluator.sub(rARescale, rBRescaleModSwitch, rAB);
The issue:
I am trying to substract rB from rA, but I'm having an issue with the scales. The cipherTextSxy was previously relinearized and rescaled in other steps of the code. I have already tried to set rA's scale to rB's scale but then we'd lose the real value of rA and the substraction, even though it would not fail, would not be realistic. I have also tried to turn N's plaintext to a ciphertext and work with the evaluator.multiply() function, but there is also an scale issue with that approach.
Screenshot of the scales' values:
Scales of cipherTextSxy and NPlainText:
Scales of rA and rB:
My code:
Encryption parameters: