Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

Question about sending BinaryIO of context and pubKey to another party #175

Open
DylanWangWQF opened this issue Jun 24, 2021 · 10 comments
Open
Assignees

Comments

@DylanWangWQF
Copy link

Hi, @boland25 @deanthomasson .
I have a question: when I generate a new context by reading from stringstream, these two context should be equal. But if I encrypt the vector using the oldContext.publickey, then decrypt it using the newContext.seckey. It failed due to different context.
Could you give me some suggestions?

context.writeTo(ss);
Context newContext = Context::readFrom(ss);
cout << "Context isEqual: " << (newContext == meta.data->context) << endl; // result:1

SecKey secret_key(newContext);
secret_key.GenSecKey();
addSome1DMatrices(secret_key);
const PubKey& public_key = secret_key;
const helib::EncryptedArray& newEa = newContext.getEA();

cout << "PublicKey isEqual: " << (public_key == meta.data->publicKey) << endl; // result:0

vector<long> inputtest(256);
    for (long i = 0; i< 256; i++) {
        inputtest[i] = i;
    }
    
// oldContext.publicKey
Ctxt inputCtxt(meta.data->publicKey);
ea.encrypt(inputCtxt, meta.data->publicKey, inputtest);

//newContext.seckey
vector<long> outputtest1;
newEa.decrypt(inputCtxt, secret_key, outputtest1); // error: cannot decrypt due to different context

@DylanWangWQF
Copy link
Author

Due to some reasons, write to file and read from file is not considered.

@boland25
Copy link
Collaborator

@DylanWangWQF I would have to try this out myself, but if I remember right, you can't mix and match contexts. if you use the old context instead, does it work?

@deanthomasson deanthomasson self-assigned this Jun 25, 2021
@DylanWangWQF
Copy link
Author

@boland25
Sure, If I use the same context, it will work;
But If I want to send the context, pk, sk to another trusted party, I have to write the context to stringstream and another party read from stringstream to get this context, right?
We can see that the new and old context is equal according to the code

cout << "Context isEqual: " << (newContext == meta.data->context) << endl; // result:1

So, it seems that the generated pk and sk using these new and old context cannot be used to encrypt and decrypt.

@DylanWangWQF
Copy link
Author

DylanWangWQF commented Jun 28, 2021

@boland25 @deanthomasson
I'm thinking of another question about alpine-based HElib. could you help me understand it?

HElib is usually built against GLIBC, while Alpine Linux is based on the MUSL C library.

And for fhe-toolkit-linux project, it shows that we can successfully run helib in the alpine container. Why? (I'm doing some experiments with HElib in MUSL-based environment).

Thanks in advance!

@boland25
Copy link
Collaborator

@DylanWangWQF I have not dug deep enough into the Alpine docker implementation of it as that was done by another team member but its building off of cmake and using the gcc compiler. There must be some sort of wrapper that is done under the hood that makes it happen, but I am not sure of this completely.

As for your bug, I have someone working on this to try and re-create it, and should have an answer to you shortly. Thanks for your patience!

@DylanWangWQF
Copy link
Author

@boland25
Got it, looking forward to it!
Many thanks for your reply!

@boland25
Copy link
Collaborator

boland25 commented Jul 1, 2021

@DylanWangWQF can you please provide the source code that you were using where you ran into the issue so we can re-create?

@DylanWangWQF
Copy link
Author

DylanWangWQF commented Jul 1, 2021

Hi, @boland25
Here is the test code, I remove other codes: https://github.com/DylanWangWQF/hetest
It should return the context dismatch error.

For the current version of HElib, we cannot do like this: new Context(m,p,r), new Seckey(*context), etc..So how should we manage the used memory after running the code?

In the traditional way, we can new/delete or malloc/free to free memory.

But now, I don't understand the way of releasing memory since we must build the context using the contextbuilder() (no other choices). In addition, there are embedded class objects (like PAlgebra zMStar, PAlgebraMod alMod, etc..) when building context.
Considering my design, I want to utilize the heap memory as much as possible and free the memory by myself.

Sry for my noise.

@boland25
Copy link
Collaborator

boland25 commented Jul 6, 2021

@DylanWangWQF thanks for sending that over. I have someone working on re-creating your test. Bear with us, as he is only on the project part time so will take a bit to get a response. In regard to your last question, have you checked out the tutorial folder? There are a few different tutorials in there that might help, and you can use HEContext like this.... shared_ptr<HeContext> hePtr = HelibContext::create(HELIB_CKKS_8192);. When you are done using it, its a shared_ptr so you can just delete the object or remove it once its out of scope.

@DylanWangWQF
Copy link
Author

@boland25
Many thanks for your reply!
Here is another example to help us understand the issue.

    Context* activeTContext;
    unique_ptr<SecKey> activeSecKey;
    unique_ptr<PubKey> activePubKey;

void test::testStruct(){
    unsigned long p = 127;
    // Cyclotomic polynomial - defines phi(m)
    unsigned long m = 12800;
    // Hensel lifting (default = 1)
    unsigned long r = 1;
    // Number of bits of the modulus chain
    unsigned long bits = 119;
    // Number of columns of Key-Switching matrix (default = 2 or 3)
    unsigned long c = 2;
    
    std::cout << "Initialising context object..." << std::endl;
    helib::Context context = helib::ContextBuilder<helib::BGV>()
                                .m(m)
                                .p(p)
                                .r(r)
                                .bits(bits)
                                .c(c)
                                .build();
    helib::SecKey secret_key(context);
    secret_key.GenSecKey();
    helib::addSome1DMatrices(secret_key);
    const helib::PubKey& public_key = secret_key;
    
    stringstream ss;
    context.writeTo(ss);

    activeTContext = Context::readPtrFrom(ss);
    activeTContext->printout();

    // new generated pk and sk
    activeSecKey = make_unique<SecKey>(*activeTContext);
    activeSecKey->GenSecKey();
    addSome1DMatrices(*activeSecKey);
    activePubKey = make_unique<PubKey>(*activeSecKey);

    encryptt(*activeTContext, *activePubKey, *activeSecKey); // this works
    //  encryptt(*activeTContext, *activePubKey, secret_key); fail due to context dismatch
// or  encryptt(*activeTContext, public_key, *activeSecKey);  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;
    con.getEA().encrypt(ct, pk, inputtest);
    stringstream css;
    ct.writeTo(css);
    
    string s1 = css.str();
    uint8_t* c1 = (uint8_t*)s1.c_str();
    uint8_t* c2 = nullptr;
    stringstream ess;
    string s2 = string(c1, c1 + s1.size());
    ess << s2;
    Ctxt newct = Ctxt::readFrom(ess, pk);
    
    con.getEA().decrypt(newct, sk, outputtest);
    cout << outputtest << endl;
}

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

No branches or pull requests

3 participants