.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_autoexamples/Demo_5_CS_Client.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr__autoexamples_Demo_5_CS_Client.py: Client/Server demo with Pyfhel ======================================== This demo shows an example of Client-Server interaction, where the client sends an encrypted vector and the server answers with the weighted average based on his weights. To run with real Client/Server separation (using `flask` and Demo_5bis_CS_Server.py), change the flag below to True. .. GENERATED FROM PYTHON SOURCE LINES 12-15 .. code-block:: Python USE_REAL_SERVER: bool = False .. GENERATED FROM PYTHON SOURCE LINES 16-18 1. Setup Client -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 18-48 .. code-block:: Python import numpy as np from Pyfhel import Pyfhel, PyCtxt if USE_REAL_SERVER: try: import requests except ImportError: print("This demo requires the `requests` python module (install with pip). Exiting.") exit(0) # Generate Pyfhel session print(f"[Client] Initializing Pyfhel session and data...") HE_client = Pyfhel(context_params={'scheme':'ckks', 'n':2**13, 'scale':2**30, 'qi_sizes':[30]*5}) HE_client.keyGen() # Generates both a public and a private key HE_client.relinKeyGen() HE_client.rotateKeyGen() # Generate and encrypt data x = np.array([1.5, 2, 3.3, 4]) cx = HE_client.encrypt(x) # Serializing data and public context information s_context = HE_client.to_bytes_context() s_public_key = HE_client.to_bytes_public_key() s_relin_key = HE_client.to_bytes_relin_key() s_rotate_key = HE_client.to_bytes_rotate_key() s_cx = cx.to_bytes() print(f"[Client] sending HE_client={HE_client} and cx={cx}") .. rst-class:: sphx-glr-script-out .. code-block:: none [Client] Initializing Pyfhel session and data... [Client] sending HE_client= and cx= .. GENERATED FROM PYTHON SOURCE LINES 49-51 2. Setup Server ----------------------- .. GENERATED FROM PYTHON SOURCE LINES 51-67 .. code-block:: Python print(f"[Client] launching server (could be launched separately)...") if(USE_REAL_SERVER): import subprocess, os from pathlib import Path dir = Path(os.path.realpath("__file__")).parent process = subprocess.Popen( ["python", str(dir / "Demo_5bis_CS_Server.py")], stderr=subprocess.STDOUT, ) import time time.sleep(6) # Wait for server initialization else: print(f"[Server] mock started!...") print("[Client] server initialized...") .. rst-class:: sphx-glr-script-out .. code-block:: none [Client] launching server (could be launched separately)... [Server] mock started!... [Client] server initialized... .. GENERATED FROM PYTHON SOURCE LINES 68-71 3. Launch a request to the server ---------------------------------------- We map the bytes into strings based on https://stackoverflow.com/a/27527728 .. GENERATED FROM PYTHON SOURCE LINES 71-104 .. code-block:: Python if(USE_REAL_SERVER): r = requests.post('http://127.0.0.1:5000/fhe_mse', json={ 'context': s_context.decode('cp437'), 'pk': s_public_key.decode('cp437'), 'rlk':s_relin_key.decode('cp437'), 'rtk':s_rotate_key.decode('cp437'), 'cx': s_cx.decode('cp437'), }) c_res = PyCtxt(pyfhel=HE_client, bytestring=r.text.encode('cp437')) else: # Mocking server code (from Demo_5bis_CS_Server.py) # Read all bytestrings HE_server = Pyfhel() HE_server.from_bytes_context(s_context) HE_server.from_bytes_public_key(s_public_key) HE_server.from_bytes_relin_key(s_relin_key) HE_server.from_bytes_rotate_key(s_rotate_key) cx = PyCtxt(pyfhel=HE_server, bytestring=s_cx) print(f"[Server] received HE_server={HE_server} and cx={cx}") # Encode weights in plaintext w = np.array([0.5, -1.5, 4, 5]) ptxt_w = HE_server.encode(w) # Compute weighted average c_mean = (cx * ptxt_w) c_mean /= 4 # 4 c_mean += (c_mean >> 1) # cumulative sum c_mean += (c_mean >> 2) # element [3] contains the result print(f"[Server] Average computed! Responding: c_mean={c_mean}") c_res = c_mean.copy() # Copying with a single command .. rst-class:: sphx-glr-script-out .. code-block:: none [Server] received HE_server= and cx= [Server] Average computed! Responding: c_mean= .. GENERATED FROM PYTHON SOURCE LINES 105-108 4. Process Response -------------------------- Decrypting result .. GENERATED FROM PYTHON SOURCE LINES 108-116 .. code-block:: Python res = HE_client.decryptFrac(c_res) # Checking result w = np.array([0.5, -1.5, 4, 5]) # in the server expected = np.mean(x*w) print(f"[Client] Response received! Result is {np.round(res[3], 4)}, should be {expected}") .. rst-class:: sphx-glr-script-out .. code-block:: none [Client] Response received! Result is 7.7382, should be 7.7375 .. GENERATED FROM PYTHON SOURCE LINES 117-120 .. code-block:: Python if USE_REAL_SERVER: process.kill() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.354 seconds) **Estimated memory usage:** 377 MB .. _sphx_glr_download__autoexamples_Demo_5_CS_Client.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: Demo_5_CS_Client.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: Demo_5_CS_Client.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_