zama-ai/tfhe-rs

Conditional blocks.

tarassh opened this issue · 9 comments

What is the problem you want to solve and can not with the current version?
I was trying to find a way to code server side logic with conditional blocks.

Describe the solution you'd like
The best case scenario would be feature like:

if ecrypted_a.eq(encrypted_b) {
     // do something...
}

Describe alternatives you've considered

  1. let result = condition.if_then_else(ct_true, ct_false) - is not working in this case as result != ct_true && result != ct_false
  2. Another alternative I was looking for is an indication of operation overflow. Let's say we have a type which is size of 1 bit, so when 1 + 1 would signal for carry out bit. Didn't find any.

Additional context
I understand this kind of feature is agains privacy principles, but let assume that client agrees to reveal some bits of information to the server. In this case we can implement more sophisticated computation logics (video/audio processing, etc).

hello @tarassh

So the first thing that I think you saw is that as is you cannot do branching code on the server side, the boolean is encrypted and for obvious security reasons the secret key of the client has to remain secret, meaning the server cannot decrypt and inspect that value, otherwise all the data that the client wanted to keep secret is decrytpable by the server, defeating the purpose of FHE.

I think you should be able to use the if_then_else though:

// Let's pretend we have two functions for the true and false branches of the if statement
fn true_case(...) -> Ciphertext {
    ...
}

fn false_case(...) -> Ciphertext {
    ...
}

let condition = ecrypted_a.eq(encrypted_b);
let result = condition.if_then_else(true_case(...), false_case(...));

would the above be something that can work for you ?

Cheers

For the overflow, we are adding signed overflowing operation for the next release, some unsigned overflowing operations are already available at the integer layer, maybe it is not exposed in the HL API that you seem to be using

https://docs.rs/tfhe/latest/tfhe/?search=overflow

It seems overflowing add and sub should be coming in our next release cycle in the HL API

@IceTDrinker than you for such fast response,

The feature that I am trying to express, I assume is more related to cryptography and maybe is not feasible. I am expecting that client is okay to reveal information to server in some cases:

for .... 100000000000 {
      // other logic

      let condition = ecrypted_a.eq(encrypted_b);
      
      let disposable_key = condition.get_onetime_key(server_key | public_key);
      
      if condition.decrypt(& disposable_key) {
                 break;
      }
}

so the problem here that I see is that condition is encrypted under a certain secret key SK1 and the disposable_key you have is able to decrypt condition, then it means all ciphertexts from SK1 are decryptable under disposable_key, meaning the data is no longer private at all.

A possibility is to have some communication between the client and the server where the client would decrypt certain ciphertexts and return the boolean to the server, this way you guarantee the server cannot decrypt the data of the client.

I don't know if it makes sense for your use case.

Note that having communication between the client and the server can probably leak information via timing attacks/measuring the traffic between the two if the attacker knows what circuit is executed on the server, let's say one branch of the if is super fast and the other one has more communication, you can guess which branch was taken if the traffic stops after the exchange between the client and the server for the encryped condition

I totally got the point of privacy.

Here is an example that I am trying to address. I need to re encode video which has thousands of frames. Video dimensions is 1024 x 768, and video is encoded by h264 codec which has variable bit rate, meaning we have roughly two type of frames:

  • key frame (KF) - 1024 x 768.
  • other frames are delta to to previous frame (D), they will have variadic size meaning not all bits from that matrix are with the data.
    They are processed in a sequence:
    KF1 -> D1 -> D2 -> D3 ... -> KF2 -> D1 ....
    Let's assume server performs some operation per each frame in a loop, so when we have a key frame we will go though all cycles of that loop, but when we have a delta frame we don't need to waste cycles as delta frame will contain less data to process or even none (delta == 0 no changes to previous frame).

If I want to use FHE for video re-encoding, it means the best what I can do is to expect to process each frame like it has all the data, which is waste of time.

how about sending some metadata with the frame ? You can send in the clear a FrameType::KeyFrame, FrameType::Delta(infos_on_the_frame_size) ?

If the metadata is ok to leak (as we are already leaking the frame size anyways) then I guess it could work for you ?

Not a case, but thank you for your help. I am closing the ticket.

what do you mean not a case ? if you want we can discuss further on the FHE.org discord https://discord.fhe.org/ on the TFHE-rs channel https://discord.com/channels/901152454077452399/1062367401737474058 🙂 or you can share your use case with the community !