Thank you for all of you work and for this project .
I am trying to use binary gates in a sequence (approx ~70) with the best performance. But I see that there are some differences when decrypted compared to the operations done on the clear ciphertext. I have a median similarity of 70% (i.e. 70% of the decrypted cipher text is the same as the clear file).
Also, I would like to know if there has been some verifications/statistics about noise propagation when boostrapping ? From what I understood from the code, after each gate there is bootstrapping.
I copy pasted my code down there if you want to have a look, this one gives ~52% accuracy
def sat_clause(x_0, x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, thr, perf_params, cloud_key):
params = cloud_key.params
# I have 23 terms with OR gates, so each of this term is initialized with an empty ciphertext
_0 = empty_ciphertext(thr, params, x_0.shape)
_1 = empty_ciphertext(thr, params, x_0.shape)
_2 = empty_ciphertext(thr, params, x_0.shape)
_3 = empty_ciphertext(thr, params, x_0.shape)
_4 = empty_ciphertext(thr, params, x_0.shape)
_5 = empty_ciphertext(thr, params, x_0.shape)
_6 = empty_ciphertext(thr, params, x_0.shape)
_7 = empty_ciphertext(thr, params, x_0.shape)
_8 = empty_ciphertext(thr, params, x_0.shape)
_9 = empty_ciphertext(thr, params, x_0.shape)
_10 = empty_ciphertext(thr, params, x_0.shape)
_11 = empty_ciphertext(thr, params, x_0.shape)
_12 = empty_ciphertext(thr, params, x_0.shape)
_13 = empty_ciphertext(thr, params, x_0.shape)
_14 = empty_ciphertext(thr, params, x_0.shape)
_15 = empty_ciphertext(thr, params, x_0.shape)
_16 = empty_ciphertext(thr, params, x_0.shape)
_17 = empty_ciphertext(thr, params, x_0.shape)
_18 = empty_ciphertext(thr, params, x_0.shape)
_19 = empty_ciphertext(thr, params, x_0.shape)
_20 = empty_ciphertext(thr, params, x_0.shape)
_21 = empty_ciphertext(thr, params, x_0.shape)
_22 = empty_ciphertext(thr, params, x_0.shape)
# each term will be save in their respective ciphertext (term 0 is saved in ciphertext 0_ , ... )
# x_5|x_8|~x_7
gate_or(thr, cloud_key, _0, x_5, x_8, perf_params)
gate_oryn(thr, cloud_key, _0, _0.copy(), x_7, perf_params)
# x_5|~x_1|~x_7
gate_oryn(thr, cloud_key, _1, x_5, x_1, perf_params)
gate_oryn(thr, cloud_key, _1, _1.copy(), x_7, perf_params) # doing (x_5 | ~x_1) | ~x_7
# x_5|~x_3|~x_7
gate_oryn(thr, cloud_key, _2, x_5, x_3, perf_params)
gate_oryn(thr, cloud_key, _2, _2.copy(), x_7, perf_params)
# x_5|~x_4|~x_7
gate_oryn(thr, cloud_key, _3, x_5, x_4, perf_params)
gate_oryn(thr, cloud_key, _3, _3.copy(), x_7, perf_params)
# x_5|~x_6|~x_7
gate_oryn(thr, cloud_key, _4, x_5, x_6, perf_params)
gate_oryn(thr, cloud_key, _4, _4.copy(), x_7, perf_params)
# x_0|x_2|x_6|~x_4
gate_or(thr, cloud_key, _5, x_0, x_2, perf_params)
gate_or(thr, cloud_key, _5, _5.copy(), x_6, perf_params)
gate_oryn(thr, cloud_key, _5, _5.copy(), x_4, perf_params)
# x_1|x_2|x_7|~x_4
gate_or(thr, cloud_key, _6, x_1, x_2, perf_params)
gate_or(thr, cloud_key, _6, _6.copy(), x_7, perf_params)
gate_oryn(thr, cloud_key, _6, _6.copy(), x_4, perf_params)
# x_1|x_4|x_8|~x_6
gate_or(thr, cloud_key, _7, x_1, x_4, perf_params)
gate_or(thr, cloud_key, _7, _7.copy(), x_8, perf_params)
gate_oryn(thr, cloud_key, _7, _7.copy(), x_6, perf_params)
# x_2|x_3|x_7|~x_4
gate_or(thr, cloud_key, _8, x_2, x_3, perf_params)
gate_or(thr, cloud_key, _8, _8.copy(), x_7, perf_params)
gate_oryn(thr, cloud_key, _8, _8.copy(), x_4, perf_params)
# x_3|x_7|x_8|~x_5
gate_or(thr, cloud_key, _9, x_3, x_7, perf_params)
gate_or(thr, cloud_key, _9, _9.copy(), x_8, perf_params)
gate_oryn(thr, cloud_key, _9, _9.copy(), x_5, perf_params)
# x_1|x_2|~x_0|~x_4
gate_or(thr, cloud_key, _10, x_1, x_2, perf_params)
gate_oryn(thr, cloud_key, _10, _10.copy(), x_0, perf_params)
gate_oryn(thr, cloud_key, _10, _10.copy(), x_4, perf_params)
# x_2|x_7|~x_4|~x_8
gate_or(thr, cloud_key, _11, x_2, x_7, perf_params)
gate_oryn(thr, cloud_key, _11, _11.copy(), x_4, perf_params)
gate_oryn(thr, cloud_key, _11, _11.copy(), x_8, perf_params)
# x_4|x_7|~x_5|~x_6
gate_or(thr, cloud_key, _12, x_4, x_7, perf_params)
gate_oryn(thr, cloud_key, _12, _12.copy(), x_5, perf_params)
gate_oryn(thr, cloud_key, _12, _12.copy(), x_6, perf_params)
# x_6|x_7|~x_4|~x_5
gate_or(thr, cloud_key, _13, x_6, x_7, perf_params)
gate_oryn(thr, cloud_key, _13, _13.copy(), x_4, perf_params)
gate_oryn(thr, cloud_key, _13, _13.copy(), x_5, perf_params)
# x_1|x_3|x_5|x_8|~x_4
gate_or(thr, cloud_key, _14, x_1, x_3, perf_params)
gate_or(thr, cloud_key, _14, _14.copy(), x_5, perf_params)
gate_or(thr, cloud_key, _14, _14.copy(), x_8, perf_params)
gate_oryn(thr, cloud_key, _14, _14.copy(), x_4, perf_params)
# x_6|~x_0|~x_4|~x_7
gate_oryn(thr, cloud_key, _15, x_6, x_0, perf_params)
gate_oryn(thr, cloud_key, _15, _15.copy(), x_4, perf_params)
gate_oryn(thr, cloud_key, _15, _15.copy(), x_7, perf_params)
# x_6|~x_1|~x_4|~x_8
gate_oryn(thr, cloud_key, _16, x_6, x_1, perf_params)
gate_oryn(thr, cloud_key, _16, _16.copy(), x_4, perf_params)
gate_oryn(thr, cloud_key, _16, _16.copy(), x_8, perf_params)
# x_0|x_4|x_5|~x_1|~x_6
gate_or(thr, cloud_key, _17, x_0, x_4, perf_params)
gate_or(thr, cloud_key, _17, _17.copy(), x_5, perf_params)
gate_oryn(thr, cloud_key, _17, _17.copy(), x_1, perf_params)
gate_oryn(thr, cloud_key, _17, _17.copy(), x_6, perf_params)
# ~x_0|~x_1|~x_6|~x_8
n_x_0 = empty_ciphertext(thr, params, x_0.shape)
gate_not(thr, cloud_key, n_x_0, x_0, perf_params)
gate_oryn(thr, cloud_key, _18, x_0, x_1, perf_params)
gate_oryn(thr, cloud_key, _18, _18.copy(), x_6, perf_params)
gate_oryn(thr, cloud_key, _18, _18.copy(), x_8, perf_params)
# x_1|x_7|~x_0|~x_5|~x_6
gate_or(thr, cloud_key, _19, x_1, x_7, perf_params)
gate_oryn(thr, cloud_key, _19, _19.copy(), x_0, perf_params)
gate_oryn(thr, cloud_key, _19, _19.copy(), x_5, perf_params)
gate_oryn(thr, cloud_key, _19, _19.copy(), x_6, perf_params)
# x_1|x_3|x_6|x_8|~x_2|~x_7
gate_or(thr, cloud_key, _20, x_1, x_3, perf_params)
gate_or(thr, cloud_key, _20, _20.copy(), x_6, perf_params)
gate_or(thr, cloud_key, _20, _20.copy(), x_8, perf_params)
gate_oryn(thr, cloud_key, _20, _20.copy(), x_2, perf_params)
gate_oryn(thr, cloud_key, _20, _20.copy(), x_7, perf_params)
# x_4|~x_0|~x_1|~x_6|~x_7
gate_oryn(thr, cloud_key, _21, x_4, x_0, perf_params)
gate_oryn(thr, cloud_key, _21, _21.copy(), x_1, perf_params)
gate_oryn(thr, cloud_key, _21, _21.copy(), x_6, perf_params)
gate_oryn(thr, cloud_key, _21, _21.copy(), x_7, perf_params)
# x_7|~x_1|~x_5|~x_6|~x_8
gate_oryn(thr, cloud_key, _22, x_7, x_1, perf_params)
gate_oryn(thr, cloud_key, _22, _22.copy(), x_5, perf_params)
gate_oryn(thr, cloud_key, _22, _22.copy(), x_6, perf_params)
gate_oryn(thr, cloud_key, _22, _22.copy(), x_8, perf_params)
answer = empty_ciphertext(thr, params, x_0.shape)
# apply AND gate on each term
gate_and(thr, cloud_key, answer, _0, _1, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _2, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _3, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _4, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _5, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _6, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _7, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _8, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _9, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _10, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _11, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _12, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _13, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _14, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _15, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _16, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _17, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _18, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _19, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _20, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _21, perf_params)
gate_and(thr, cloud_key, answer, answer.copy(), _22, perf_params)
return answer