What's the best way to use openFHE on two sides?

Dear,
I am contacting you because I am a beginner on openFHE library. Indeed, as part of my sensitive data protection POC, I need to use the openFHE library on two sides : Owner server side and Provider server side.

Owner server side

  1. Generate and share Keys

    Create InitContext
    
    Generate keys : privatekey, publickey, evalMultkey, evalSumkey, evalAtIndexkey
    
    Share  evalMultkey, evalSumkey, evalAtIndexkey	 keys  with  provider server side
    
  2. Encrypt and send data

    Create encryptContext
     	 
    encryptContext.Insert?(publickey)
          
    encryptedData1 = Encrypt(publicKey, Data1)
     	 
    encryptedData2 = Encrypt(publicKey, Data2)
     	 
    send encryptedData1, encryptedData2  to Provider
    
  3. Decrypt data with privatekey

    Receive encryptedResult from Provider
          
    Create decryptContext
          
    decryptContext.insert?(privatekey)
    
    result = Decrypt(privateKey, encryptedResult)
    

Provider server side

Receive encryptedData1, encryptedData2 from Owner Server

Create ComputeContext

ComputeContext.Insert?(evalMultkey);

ComputeContext.Insert?(evalSumkey);

ComputeContext.Insert?(evalAtIndexkey);

Compute HE operations :

    EvalMult(encryptedData1, encryptedData2)
    EvalAtIndex(? , index)
    EvalAddInPlace(?,?)

Send encryptedResult to Owner Server

My question is: How do I initialize OpenFHE’s cryptoContexts : encryptContext?, decryptContext?, ComputeContext ? and what’s the best way to implement my use case with openFHE?

Thanks in advance.

See the following examples for BFV, BGV, and CKKS.

The owner server side would serialize the created CryptoContexts into files, and the provider server side would deserialize the files back into CryptoContexts

1 Like

If you’re looking for a “larger scale” example, check out the material we’ve put out for palisade-serial-examples. Just remember that Palisade != OpenFHE so not everything there will transfer over (in terms of creating the cryptocontexts, etc) but the core idea of a two-party system is there.

Hope this helps!

Thanks #saroja for your reply

According your response don’t need to load evalMultkey, evalSumkey, evalAtIndexkey keys on provider server side?

You also need to serialize and deserialize any keys you are using! The examples linked above show how to do this with:

  • SerializeToFile and DeserializeFromFile for the cryptocontext, public key, private key, and ciphertexts
  • SerializeEvalMultKey and DeserializeEvalMultKey for the evalMultkey
  • SerializeEvalAutomorphismKey and DeserializeEvalAutomorphismKey for the evalRotatekey

Thanks @iquah for your reply.

There are not way to share cryptoContext as base64 text instead file?
And how to load shared keys : privateKey, publicKey,evalMultkey, evalSumkey, evalAtIndexkey ?

Thanks for help.
I’ll trying this way.

Thanks so much for links.

There are not way to share cryptoContext as base64 text instead file?

We provide capabilities to serialize to both json and binary strings. You’d then transmit the string to the receiver who then deserializes these strings.

std::stringstream s;
Serial::Serialize(serverCC, s, SerType::BINARY);

See Program Listing for File cryptocontext-ser.h — OpenFHE documentation for various functions that we provide.

And how to load shared keys : privateKey, publicKey,evalMultkey, evalSumkey, evalAtIndexkey ?

Those keys require an already-created cryptocontext. You use the cryptocontext to handle the serialization and deserialization of those objects. See the link I just shared to see what functions exist and what you can call

I’m checked openFHE docs about Serialization.

Hope this helps someone else with the same needs

Thanks again for your helps.

Hi, I wrote the serialization examples repo in palisade PALISADE / PALISADE serial examples · GitLab. It contains examples of two separate heavyweight processes that do what you want. At least it shows the things that need to be done in order to share a crypto context between two programs. Just don’t share the secret key!

I do not think it would be too much effort to port it to OpenFHE, especially if you use the serialization examples Saroja pointed you to – however all those examples are only for a single thread, and do not reveal all the required operations needed to get things to work correctly.

When you have two cooperating sequential processes they need to talk via a protocal that provides syncrhonisation, as well as just sending data back and forth. IIRC there is a file+mutex version and a simple socket I/O version using an open source library with simple ASIO sockets.

You always have to serialise the crypto objects though. they are not simple arrays of integegers, but actually C++ object with control information and are ususally implemented as smart shared pointers as well. Serialization automagically converts all the object information into a json (huge but barely readable) or binary (as small as it can get but no readable) buffer which gets written to a file or socket.

Hope this will help
Dave

1 Like

Thanks @dcousins for your reply.

In my use case, i need share crypo Objects, pk, sk, evalK as stringstream stored on database
I think File Serialize/Deserialize IO/Socket are very expensive for my use case.

Ghislain

Hi, I am trying to use real_socket_server example on PALISADE / PALISADE serial examples. when ı run it, i take segmentation fault.
in the server
SERVER: creating acceptor for 8080
SERVER: accepting socket
SERVER: sending CC and Keys
SERVER: sending cryptocontext
streamed to buffer 5 bytes
SERVER: send size to socket
SERVER: sent 8 bytes to socket
SERVER: sending data to socket
SERVER: sent 5 data bytes to socket
SERVER: sending Public key
streamed to buffer 2623680 bytes
SERVER: send size to socket
SERVER: sent 8 bytes to socket
SERVER: sending data to socket
Exception: send: Broken pipe
SERVER: Total time: 27003 mSec

in the client side
CLIENT: connecting to localhost:8080
CLIENT: connected
CLIENT: reading length from socket
CLIENT: read 8 bytes from socket
CLIENT: will read 5 bytes from socket
CLIENT: read 5 bytes CC from socket
Segmentation fault

I have 16gb RAM and ı use WSL(ubuntu).

do you know how can ı solve this problem?

You can compile with the debug flags on and run the client in gdb to identify where it is segfaulting.

The server side is a message that the client died and took the socket with them.

Not sure if 16 GB ram is sufficient you might be running out of memory, can you check with top or htop?

thank you for answer.

I checked the memory, the basic example use approximately 2gb RAM. When i compile with the debug mode, the fault is arised from :
in client.cpp → CC clientCC= recvCC(s);


Could it be due to WSL?

I personally never use wsl, and so I never tested this example in that environment. What is happening here is that the message that is coming back from the sever may be empty or corrupted. I am a bit confused, in that it loos like openfhe code and you said you were using palisade?

I just looked at this thread. I am using wsl and typically get the same behavior with it as with a native Ubuntu build. As far as I can see, the PALISADE serialization example is being run against OpenFHE. I would not expect the PALISADE serialization example to work correctly as many changes were made in OpenFHE since it forked off from PALISADE at the beginning of 2022. Why not use serialization examples from openfhe-development/src/pke/examples at main · openfheorg/openfhe-development · GitHub?

the question is related to the communication between the two programs. That was why the palisade version was brought up. – but that said the palisade code is NOT interoperable with the openfhe code.

Thank you.

Before I sent you the error, I made changes to the Palisade code to make it work in OpenFHE (according to How To Migrate A User Project From Palisade To OpenFHE). I also solved my above problem with a new change. it is working now.