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

Ctxt::bringToSet called with capacity=-14.9074, likely decryption error #285

Open
hdln opened this issue Feb 23, 2019 · 10 comments
Open

Ctxt::bringToSet called with capacity=-14.9074, likely decryption error #285

hdln opened this issue Feb 23, 2019 · 10 comments

Comments

@hdln
Copy link

hdln commented Feb 23, 2019

Hi,when I set a very big value to param p (like 999999999999659),the decrypted result is not correct ,it seams like a random num.
My params:
const long p = 999999999999659; const long r = 1; const long L = 4; const long c = 2; const long k = 80; const long s = 0; const long d = 1; const long w = 64;

Got result:
encrypt 100
decrypt the ciphertexts of 100 :122
sum 100+50
decrypt the ciphertexts of 100+50 :171
sub 150-20
decrypt the ciphertexts of 150 -20 :120
Ctxt::bringToSet called with capacity=-11.671, likely decryption error
Ctxt::bringToSet called with capacity=-10.5724, likely decryption error
Ctxt::bringToSet called with capacity=-56.354, likely decryption error
mul 1302
decrypt the ciphertexts of 130
2 :33557767100928

When the param p is small ,it's OK!

@shaih
Copy link
Collaborator

shaih commented Feb 23, 2019

HElib cannot work with very large p values. In principle you may be able to use p values upto 60 bits (about 1e20), but you will need huge values of L to make it work. (And also we never tested such large values, so perhaps things break with p values above 30 bits.) This is unlikely to ever change, as the technology inherently has poor behavior for very large p values. Some ways to get around this limitation are:

(a) work with p=2 and encode all your values in binary (HElib has some support for binary arithmetic and comparisons).
(b) Work with multiple instances, each with a small p value (all co-prime), and use Chinese-remaindering to reconstruct the values that you are interested in.
(c) Use the CKKS back end of HElib (still in draft status) to handle "analog computations" where you only care about the high-order bits of the results.

@peiworld
Copy link

I am having similar problem with smaller p values.

{
"PlaintextModule": 73,
"Lifting": 1,
"ModuleChainLevel": 30,
"KeySwitchingMatricesColumns": 2,
"SecKeyHammingWeight": 64,
"FieldExtensionDegree": 1,
"SecurityParameter": 80,
"Slot": 0,
"nSlot": 174
}

Ctxt::bringToSet called with empty set and capacity=11.3256, this is likely a bug
Ctxt::bringToSet called with empty set and capacity=12.8503, this is likely a bug
Ctxt::bringToSet called with empty set and capacity=11.3256, this is likely a bug
Ctxt::bringToSet called with empty set and capacity=27.2386, this is likely a bug
getSet4Size: no matching IndexSet found, likely decryption error
Ctxt::bringToSet called with capacity=-13.8163, likely decryption error
Ctxt::bringToSet called with capacity=-13.1942, likely decryption error
Ctxt::bringToSet called with capacity=-51.7861, likely decryption error
getSet4Size: no matching IndexSet found, likely decryption error

@shaih
Copy link
Collaborator

shaih commented Feb 24, 2019

Most likely you specified a value of L which is too low to buildModChain. We re-purposed the argument L, now it means the number of bits that you need rather than the number of levels. (For most settings you can use #-of-bits = 25x or 30x the #-of-levels.)

@hdln
Copy link
Author

hdln commented Feb 26, 2019

(a) work with p=2 and encode all your values in binary (HElib has some support for binary arithmetic and comparisons).

`long r = 1;
long p = 2;
long d = 1;
long c = 2;
long k = 80;
long L = 500;
long s = 0;
long chosen_m = 0;
long seed = 0;
SetSeed(ZZ(seed));
long w = 64;
long m = FindM(k, L, c, p, d, s, chosen_m, 0);
vector gens, ords;

FHEcontext context(m, p, r, gens, ords);
buildModChain(context, L, c);
ZZX G = makeIrredPoly(p, d);
FHESecKey secretKey(context);
const FHEPubKey &publicKey = secretKey;
secretKey.GenSecKey();
addSome1DMatrices(secretKey);
EncryptedArray ea(context, G);
PlaintextArray p0(ea);
PlaintextArray p1(ea);
random(ea, p0);
random(ea, p1);
Ctxt c0(publicKey), c1(publicKey);
ea.encrypt(c0, publicKey, p0);
ea.encrypt(c1, publicKey, p1);
                        //if p0=110  p1=010
mul(ea, p1, p0);     // p1*=p0  ,I think p1 should be 1100,but the result is 010
c1.multiplyBy(c0);  // c1.multiplyBy(c0)
c0.cleanUp();
c1.cleanUp();
PlaintextArray pp1(ea);
ea.decrypt(c1, secretKey, pp1);
if (equals(ea, pp1, p1))
    std::cout << "GOOD\n";
else std::cout << "BAD\n";`

If p0=110 p1=010,
p1*=p0 ,
I think p1 should be 1100,but the result is 010.

@hdln
Copy link
Author

hdln commented Feb 26, 2019

`
long m = FindM(k, L, c, p, d, s, 0);

FHEcontext context(m, p, r);
buildModChain(context, L, c);

stringstream secKeyStream;
stringstream pubKeyStream;

writeContextBase(secKeyStream, context);
writeContextBase(pubKeyStream, context);

secKeyStream << context << endl;
pubKeyStream << context << endl;

FHESecKey secretKey(context);
const FHEPubKey &publicKey = secretKey;
secretKey.GenSecKey(w);
// addSome1DMatrices(secretKey);

// Output keys to files
secKeyStream << secretKey << endl;
pubKeyStream << publicKey << endl;

cout<<secKeyStream.str()<<endl;
cout<<pubKeyStream.str()<<endl;

`

The publicKey string is the same with secretKey string,is that right?

@ama9000
Copy link

ama9000 commented Feb 27, 2019

Most likely you specified a value of L which is too low to buildModChain. We re-purposed the argument L, now it means the number of bits that you need rather than the number of levels. (For most settings you can use #-of-bits = 25x or 30x the #-of-levels.)

Thanks for the suggestion. I was facing a similar issue with my code for the same reason.
Does this also affect the hard-coded L value in the AES test example below? https://github.com/shaih/HElib/blob/7091789b0e00010399dafaf0291a6be59fb3104e/src/aes/Test_AES.cpp#L69-L78

Thanks.

@radhumal
Copy link

I am getting this error when I am trying to update value at specific location in deque.
eg:
a[i]=s;
where a is deque and i am assigning s to a[i]

The error is given below:

Ctxt::bringToSet called with empty set and capacity=13.0338, this is likely a bug
getSet4Size: no matching IndexSet found, likely decryption error
Ctxt::bringToSet called with capacity=-11.2463, likely decryption error
Ctxt::bringToSet called with capacity=-11.2463, likely decryption error

@shaih
Copy link
Collaborator

shaih commented May 11, 2020

This error means that you are using parameters that are too small, and ran out of capacity (note the negative capacity).

@radhumal
Copy link

radhumal commented May 11, 2020 via email

@DHCtaichi
Copy link

Hey guys, I have the same problem. I try to multiply a single variable many times using HElib, like A = Enc(a), B = Enc(b), A = A*B.
When I use normal encryption and multiply, I got the same problem like Ctxt::bringToSet called with capacity=-11.671, likely decryption error., but when I use binary multiply like examples/BGV_binary_arithmetic in HElib showed, I've never faced the same problem even 1000 times multiplication. Could someone tell me the reason?

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

6 participants