.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_autoexamples/Demo_WAHC21.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_WAHC21.py: WAHC21 =========================== This demo includes all the code snippets from the WAHC21 Pyfhel paper (corresponding sections in parenthesis). .. GENERATED FROM PYTHON SOURCE LINES 8-17 1. Setup and Parameters (Sec. 4.1) ----------------------------------------------------- We start by importing the library with the three main classes: * Pyfhel class contains most of the functions. * PyPtxt is the plaintext class * PyCtxt is the ciphertext class Then we generate a context a context and a public/secret key pair. -> This is all managed by a Pyfhel instance under the hood. .. GENERATED FROM PYTHON SOURCE LINES 17-29 .. code-block:: Python from Pyfhel import Pyfhel, PyPtxt, PyCtxt HE = Pyfhel() # Creating empty Pyfhel object HE.contextGen(scheme='BFV', n=4096, t_bits=20, sec=128) # Generating context. The p defines the plaintext modulo. # There are many configurable parameters on this step # More info in Demo_ContextParameters, and # in Pyfhel.contextGen() HE.keyGen() # Key Generation: generates a pair of public/secret keys print("-----------------------------------------------------") print("1. Setup: ", HE) .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------------------------------- 1. Setup: .. GENERATED FROM PYTHON SOURCE LINES 30-33 2. Encryption & Decryption (Sec. 4.2) ----------------------------------------------------- We show how to encrypt and decrypt a plaintex, including encoding and decoding. .. GENERATED FROM PYTHON SOURCE LINES 33-53 .. code-block:: Python integer = 45 int_ptxt = HE.encode(integer) # PyPtxt [45, 45,...] int_ctxt = HE.encrypt(int_ptxt) # PyCtxt import numpy as np np_array = np.array([6, 5, 4, 3, 2, 1],dtype=np.int64) array_ptxt = HE.encode(np_array) # Accepts list too array_ctxt = HE.encrypt(array_ptxt) # PyCtxt # Decrypt and Decode ptxt_dec = HE.decrypt(int_ctxt, decode=False) # PyPtxt integer_dec = HE.decode(ptxt_dec) # integer print("-----------------------------------------------------") print("2. Encryption & Decryption: ") print("Encrypting integer: ", integer, " -> ", int_ptxt , " -> ", int_ctxt) print("Decrypting integer: ", int_ctxt, " -> ", ptxt_dec, " -> ", integer_dec[:3],"...") .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------------------------------- 2. Encryption & Decryption: Encrypting integer: 45 -> -> Decrypting integer: -> -> [45 45 45] ... .. GENERATED FROM PYTHON SOURCE LINES 54-57 3. Homomorphic Operations (Sec. 4.3) ----------------------------------------------------- we will define two integers, encrypt them and operate: .. GENERATED FROM PYTHON SOURCE LINES 57-81 .. code-block:: Python ptxt_a = HE.encode(-12) ptxt_b = HE.encode(34) ctxt_a = HE.encrypt(56) ctxt_b = HE.encrypt(-78) # ctxt-ctxt operations ctxt_s = ctxt_a + ctxt_b # or ctxt_a += ctxt_b (in place) ctxt_m = ctxt_a * ctxt_b # ctxt-ptxt operations ctxt_s_p = ptxt_a + ctxt_b # or 12 + ctxt_b ctxt_m_p = ctxt_a * ptxt_b # or ctxt_a * 34 # maintenance operations HE.relinKeyGen() # bfv only HE.relinearize(ctxt_s) # requires relinKey HE.rotateKeyGen() # HE.rescale_to_next(ctxt_r) # ckks only # rotations (length n) ctxt_c = HE.encrypt([1,2,3,4]) ctxt_rotated = ctxt_c << 1 # [2,3,4,0,...,0,1 .. GENERATED FROM PYTHON SOURCE LINES 82-84 4. IO & Serialization (Sec. 4.4) ----------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 84-120 .. code-block:: Python import os # to cleanup files ##### CLIENT HE = Pyfhel() HE.contextGen(scheme='BFV', n=4096, t_bits=0, t=65537, sec=128) HE.keyGen() # Generates public and private key # Save context and public key only HE.save_public_key("mypk.pk") HE.save_context("mycontext.con") # Encrypt and save inputs ctxt_a = HE.encrypt(15) # implicit encoding ctxt_b = HE.encrypt(25) ctxt_a.save("ctxt_a.ctxt") ctxt_b.save("ctxt_b.ctxt") ##### SERVER HE_server = Pyfhel() HE_server.load_context("mycontext.con") HE_server.load_public_key("mypk.pk") # no secret key # Load ciphertexts ca = PyCtxt(pyfhel=HE_server, fileName="ctxt_a.ctxt") cb = PyCtxt(pyfhel=HE_server, fileName="ctxt_b.ctxt") # Compute homomorphically and send result cr = (ca + cb) * 2 cr.save("cr.ctxt") ##### CLIENT # Load and decrypt result c_res = PyCtxt(pyfhel=HE, fileName="cr.ctxt") print("-----------------------------------------------------") print("Client_server result:", c_res.decrypt()) for f in ["mypk.pk", "mycontext.con", "ctxt_a.ctxt", "ctxt_b.ctxt", "cr.ctxt"]: os.remove(f) .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------------------------------- Client_server result: [80 80 80 ... 80 80 80] .. GENERATED FROM PYTHON SOURCE LINES 121-123 5. Exploring CKKS pitfalls (Sec. 5.1) ----------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 123-160 .. code-block:: Python print("-----------------------------------------------------") from Pyfhel import PyCtxt, Pyfhel, PyPtxt HE = Pyfhel() HE.contextGen(scheme='CKKS', n=16384, qi_sizes=[30,30,30,30,30], scale=2 ** 30) HE.keyGen() ctxt_x = HE.encrypt(3.1, scale=2 ** 30) # implicit encode ctxt_y = HE.encrypt(4.1, scale=2 ** 30) ctxt_z = HE.encrypt(5.9, scale=2 ** 30) ctxtSum = HE.add(ctxt_x, ctxt_y) ctxtProd = HE.multiply_plain(ctxt_z, HE.encode(5)) ctxt_t = HE.multiply(ctxtSum, ctxtProd) ptxt_ten = HE.encode(10, scale=2 ** 30) try: ctxt_result = HE.add_plain(ctxt_t, ptxt_ten) #error: mismatched scales except ValueError as e: assert str(e) == "scale mismatch" print("CKKS: Mismatched scales detected!") ptxt_d = HE.encode(10, 2 ** 30) ctxt_d = HE.encrypt(ptxt_d) HE.rescale_to_next(ctxt_t) # 2^90 -> 2^60 HE.rescale_to_next(ctxt_t) # 2^60 -> 2^30 HE.mod_switch_to_next(ctxt_d) # match first rescale HE.mod_switch_to_next(ctxt_d) # match second rescale ctxt_t.set_scale(2**30) ctxt_result = HE.add(ctxt_t, ctxt_d) # final result # NOTE: The original code (substituting `HE.multiply` and `HE.add` # by `+` and `*`) no longer generates an error: scales are # automatically aligned using HE.align_mod_n_scale when using # operator overloads `+`, `-`, `*` and `/`. .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------------------------------- CKKS: Mismatched scales detected! .. GENERATED FROM PYTHON SOURCE LINES 161-164 6. Implementing Key-Recovery for CKKS (Sec. 5.2) ----------------------------------------------------- Setup: Encrypt, Decrypt, Decode .. GENERATED FROM PYTHON SOURCE LINES 164-176 .. code-block:: Python ctxt = HE.encrypt(0, scale=2**40) ptxt_dec = HE.decryptPtxt(ctxt) values = HE.decodeComplex(ptxt_dec) # Attack ptxt_re = HE.encode(values, scale=2**40) a = HE.poly_from_ciphertext(ctxt,1) # PyPoly b = HE.poly_from_ciphertext(ctxt,0) # or b = ctxt[0] m = HE.poly_from_plaintext(ctxt, ptxt_re) # PyPoly s = (m - b) * ~a # ~a = inverse of a print("-----------------------------------------------------") .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------------------------------- .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.160 seconds) **Estimated memory usage:** 27 MB .. _sphx_glr_download__autoexamples_Demo_WAHC21.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: Demo_WAHC21.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: Demo_WAHC21.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_