0
votes

Sry, I post the same question here, since this question is also about the HElib coding.

This question is about the serialization of pk, sk, and context in HElib. In my scenario, there are two trusted parties (A and B), these two parties can encrypt the messages and decrypt the ciphertexts.

So, A will send the context, pk, and sk to B. Then, A encrypts the message and send ctxtA to B, B decrypts ctxtA and sends another ctxtB to A. This example is just for explanation.

But it's confusing in the implementation of HElib, get the error: context dismatch, sample code is shown below:

 Context* newContext;
    unique_ptr<SecKey> newSecKey;
    unique_ptr<PubKey> newPubKey;

void test::testStruct(){
    unsigned long p = 127;
    unsigned long m = 12800;
    unsigned long r = 1;
    unsigned long bits = 119;
    unsigned long c = 2;
    
    helib::Context context = helib::ContextBuilder<helib::BGV>()
                                .m(m)
                                .p(p)
                                .r(r)
                                .bits(bits)
                                .c(c)
                                .build();
    helib::SecKey oldSk(context);
    oldSk.GenSecKey();
    helib::addSome1DMatrices(oldSk);
    const helib::PubKey& oldPk = oldSk;
    
    stringstream ss;
    context.writeTo(ss);

    newContext = Context::readPtrFrom(ss);
    cout << "Context isEqual: " << (newContext == context) << endl; // result:1

    // new generated pk and sk
    newSecKey = make_unique<SecKey>(*newContext);
    newSecKey->GenSecKey();
    addSome1DMatrices(*newSecKey);
    newPubKey = make_unique<PubKey>(*newSecKey);

    encryptt(*newContext, *newPubKey, *newSecKey); // this works
    //  encryptt(*newContext, *newPubKey, oldSk); fail due to context dismatch
// or  encryptt(*newContext, oldPk, *newSecKey);  fail due to context dismatch
}

void test::encryptt(const Context& con, const PubKey& pk, const SecKey& sk){
    vector<long> inputtest(256);
    for (long i = 0; i< 256; i++) {
        inputtest[i] = i % 2;
    }
    cout << inputtest << endl;
    
    Ctxt ct(pk);
    vector<long> outputtest;

    //Encryption
    con.getEA().encrypt(ct, pk, inputtest);
    //Decryption
    con.getEA().decrypt(ct, sk, outputtest);

    cout << outputtest << endl;
}

Overall, (oldContext, oldSk, oldPk) and (newContext, newSk, newPk) cannot be mixed.

encryptt(*newContext, *newPubKey, oldSk); fail due to context dismatch
// or  encryptt(*newContext, oldPk, *newSecKey);  fail due to context dismatch

But, we can see that the new and old context is equal according to the code:

 cout << "Context isEqual: " << (newContext == context) << endl; // result:1

P.S. Write to and read from the file is not considered, only stringstream.