Is the 'x' sent by the client to servers in plaintext or ciphertest?
giraffeCjl opened this issue · comments
In /tf-encrypted/tf_encrypted/serving.py, tfe defines a 'run(self, sess, x)' function which gets image from 'x_test' and sends x
to servers. But the print result seems that 'x' is in plaintext.
I have a question: In the homomorphic encryption computing mode, shouldn't the data be encrypted on the client and then sent to the server? Why is the input of the client in plaintext here?
TL;DR the inputs/outputs to this function are encrypted/decrypted for you. The QueueClient & QueueServer are working at a high-level of abstraction, and the details of how the input & output to the serving queue are kept secure is determined by the current protocol (& config) being used.
I think you're referring to this function:
tf-encrypted/tf_encrypted/serving/queues.py
Lines 140 to 145 in 8b7cfb3
This calls QueueClient.send_input
, which is probably the source of confusion:
tf-encrypted/tf_encrypted/serving/queues.py
Lines 112 to 125 in 8b7cfb3
The name send_input
is a bit misleading here, especially given that it's checking the input to be a raw numpy array. However, there is work being done behind the scenes to make this numpy array secret before it's sent away from the QueueClient
. This extra work is defined here, when we call tfe.define_private_placeholder
:
tf-encrypted/tf_encrypted/serving/queues.py
Lines 87 to 93 in 8b7cfb3
Under the hood, this is creating a tf.Placeholder
that is then secret shared according to the currently active protocol, producing a reference to some future private value. This secret sharing happens wherever the QueueClient
is being used, so the result of send_input
is actually a set of multiple shares making up the private value. The QueueServer
is then a wrapper around a protocol-specific Queue, and for Pond this is essentially managing one FIFOQueue
for each compute server's physical device. The shares in this queue can then be used in further protocol computation before being dequeued and returned to the client, where the shares will be reconstructed into the plaintext computation result (which is what the client sees at the end of it all).
@jvmncs Thank you for such a detailed answer, the send_input function is indeed a bit misleading, and I studied it until late LOL.
In general, can I understand this way, the QueueClient can see the calculated ciphertext result and the decrypted output, but the QueueServer cannot output the ciphertext in the whole process? I once tried to only output a ‘PondPrivateTensor’ on the QueueServer side.
Closing this. Please open a new issue if there is further question.