If conditional Implementation in Python

Hello. I have been using FHE scheme that does not support if conditional. I am searching for TFHE in Python. Would Concrete-numpy be useful for my machine learning algorithm (note that my ML algorithm is not in Concrete-ml).

Hello. Could you give us a bit more details in the algorithm you are trying to implement? This will help to address your question properly.

Thanks!

Thank you for your reply. Actually, I am working with gene expression data sets that have two dimensions by [Biclustering algorithms] (https://www.researchgate.net/profile/George_Church/publication/2329589_Biclustering_of_Expression_Data/links/550c04030cf2063799394f5e.pdf). Previously I used Pyfhel in my project but I realized that it did not support if conditionals then I have to change my scheme in the middle. I wonder whether Concrete-numpy can possibly be alternative solution to impelement conditional for two values (one constant and one numpy array)?

1 Like

Thanks for the details. So yes Concrete-Numpy allows you to reproduce the if conditionals in FHE using table lookup. This is what we use in Concrete-ML to implement decision trees. However, it will require you to implement the if else using an operator like numpy.where rather than actual if else statements which are not currently supported as is in Concrete-Numpy.

Edit: I might have been a bit too quick on this answer. The operator numpy.where is not currently supported in the current version but will come in a future release. That being said as long as you can build a TLU to represent your if conditional you should be able to do what you want.

1 Like

Thank you for clarifying the issue!
Is it possible to show a brief demo of the sample implementation of what you mentioned?

Hey,

For example: if you want to compute

 y = x < 4 ? 2x : x + 1, for an x in [0, ..., 31],

which stands for “if x < 4, then 2x else x+1”, you can build a table T, which is defined by

T[i] = i < 4 ? 2i : i + 1, for an i in [0, ..., 31],

and just replace your IF by y = T[x]. Table lookups are explained in Table Lookup — Concrete Numpy Manual.

In a further release of Concrete-Numpy, this conversion is done automatically for the user.

Cheers

2 Likes

sir array with negative values is not working in lookup table method

numpy.array must be of dtype uint{8,16,32,64}

Hey,

Sorry, I have not understood what you mean. And what’s the link with the original question, again? Docs about TLU: Table Lookup — Concrete Numpy Manual

Yes, but I don’t know what’s the link with the original question or your question related to negative things.

i am trying to implement if condition with lookup table. but my lookup table entries have negative values.

  1. i am trying to access those values i am not getting correctly.
    2)Generating above error trying access negative index.(like access elements with negative index in python)

Hi, the current version of concrete-numpy doesn’t support negative inputs to the function or negative values in the table lookup. However, it does accept negative inputs to the table lookup. So you can do:

import concrete.numpy as hnp

table = hnp.LookupTable([2, 1, 3, 0])

def function(x):
    return table[-x]

compiler = hnp.NPFHECompiler(function, {"x": "encrypted"})

inputset = range(4)
circuit = compiler.compile_on_inputset(inputset)

for i in range(4):
    print(function(i), "==", circuit.encrypt_run_decrypt(i))

Those features are being worked on right now and they will be available in the upcoming releases.

According to what you mentioned in the previous post, I tried to implement if statement within a lookup table:

table = hnp.LookupTable() #how to fill this lookup table for working with a constant?
def conditional_Constant(x):
     if x <= 300:
          stop = True
     else:
          stop = False
      return stop

inputset = msr #int 
compiler = hnp.NPFHECompiler(conditional, {"x": "encrypted"})
circuit = compiler.compile_on_inputset(inputset)
circuit.keygen()
public_args = circuit.encrypt(msr)
encrypted_result = circuit.run(public_args)
decrypted_result = circuit.decrypt(encrypted_result)
print(decrypted_result)

For the second example, I have to compare two encrypted values (msr (constant int), and msr_row (numpy.ndarray)
if msr <= msr_row:
return msr

For both situations (comparison of two values and/or one constant value) how can possibly get the result without errors such as “object is not iterable”?

Hi, your inputset should be iterable. So you can do:

inputset = [msr]
circuit = compiler.compile_on_inputset(inputset)

But having a single input in the inputset is not recommended as inputset is used for bounds measurement and a single input is not enough to do that.

As for how to fill your table lookup, I’m not sure how you are planning to use it. It’s not a complete replacement for if statements, it’s just a replacement of certain if statements.

If you have this code for example:

def f(x):
    if x < 10:
        return x * 5
    else:
        return x + 5

you can convert it to this:

table = []
for i in range(16):  # 4-bits of input
    if x < 10:
        table.append(x * 5)
    else:
        table.append(x + 5)

def f(x):
   return hnp.LookupTable(table)[x]

But if you want to have complex loop logic, conditional break, or early returns, you cannot do it with the table lookups.

1 Like