def __ipow__(self, other): # If one wants to perfor power n of a PyCtxt where n is not an int, we throw an error. if not isinstance(other, int): raise TypeError( "PyCtxt '**=' error: lhs must be of type int instead of type " + str(type(other))) # If we want to perform our PyCtxt to power 0, we return an encrypted vector of 1. if (other == 0): constCtxt = self.__pyfhel.encrypt( PyPtxt([1 for _ in range(self.__length)], self.__pyfhel) ) # Create new PyCtxt of encrypted vector of 1. self = constCtxt # If we want to perform our PyCtxt to power 1, we return our PyCtxt. elif (other == 1): #Do nothing. self = self # If we want to perform our PyCtxt to power 2, we return our PyCtxt square. elif (other == 2): self.__pyfhel.square(self) # If we want to perform our PyCtxt to power 3, we return our PyCtxt cube. elif (other == 3): self.__pyfhel.cube(self) # If we want to perform our PyCtxt to power n with n!=[0,1,2,3], we return our product(PyCtxt, n). else: # Create a copy of self. copySelf = self.copy(self) # Multiply the PyCtxt with himself to obtain PyCtxt*n. for i in range(other - 1): self *= copySelf return self
def __imod__(self, other): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt '%=' error: lhs must be of type PyCtxt " "or int instead of type " + str(type(other))) if isinstance(other, PyCtxt): self.__pyfhel.scalarProd(self, other) else: constCtxt = self.__pyfhel.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) self.__pyfhel.scalarProd(self, constCtxt) del constCtxt return self
def __iadd__(self, other): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt ADD error: lhs must be of type PyCtxt " "or int instead of type " + str(type(other))) if isinstance(other, PyCtxt): self.__pyfhel.add(self, other, False) # Add directly if other is PyCtxt else: constCtxt = self.__pyfhel.encrypt( # Create new PyCtxt from other if int PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) self.__pyfhel.add(self, constCtxt, False) # Perform addition from Afhel::add del constCtxt return self
def __add__(self, other): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt '+' error: lhs must be of type PyCtxt or " "int instead of " + str(type(other))) newCtxt = self.__pyfhel.set(self) # Create new Ctxt for result if isinstance(other, PyCtxt): # Add directly if other is PyCtxt newCtxt += other else: constCtxt = self.__pyfhel.encrypt( # Create new PyCtxt from other if int PyPtxt([other for _ in range(self.__length)],self.__pyfhel)) newCtxt += constCtxt # Perform addition like in '+=' operator del constCtxt return newCtxt
def __mod__(self, other): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt '%' error: lhs must be of type PyCtxt or " "int instead of " + str(type(other))) newCtxt = self.__pyfhel.set(self) if isinstance(other, PyCtxt): newCtxt %= other else: constCtxt = self.__pyfhel.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) newCtxt %= constCtxt del constCtxt return newCtxt
def __sub__(self, other): if not isinstance(other, PyCtxt): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt '-' error: lhs must be of type PyCtxt or " "int instead of " + str(type(other))) newCtxt = self.__pyfhel.set(self) if isinstance(other, PyCtxt): newCtxt -= other # Substract directly if other is PyCtxt else: constCtxt = self.__pyfhel.encrypt( # Crete new PyCtxt from other if int PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) newCtxt -= constCtxt # Perform substraction from Afhel::add del constCtxt return newCtxt
def __imul__(self, other): if not isinstance(other, (PyCtxt, int)): raise TypeError("PyCtxt '*=' error: lhs must be of type PyCtxt " "or int instead of type " + str(type(other))) if isinstance(other, PyCtxt): self.__pyHE.multiplyBy(self, other) else: constCtxt = self.__pyHE.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyHE)) self.__pyHE.multiplyBy(self, constCtxt) del constCtxt return self
def __imod__(self, other): # If one wants to perform scalar product on a PyCtxt with an object that is not either a PyCtxt or an int, we throw an error. if not isinstance(other, (PyCtxt, int)): raise TypeError( "PyCtxt '%=' error: lhs must be of type PyCtxt or int instead of type " + str(type(other))) # Perform the scalar product directly if other is PyCtxt. if isinstance(other, PyCtxt): self.__pyfhel.scalarProd(self, other) #Otherwise, if one wants to perform scalar product on a PyCtxt with an int, we have to create a vector of that int and then encrypted to transform it in PyCtxt. else: # Create new PyCtxt from other if int. constCtxt = self.__pyfhel.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) # Perform scalar product. self.__pyfhel.scalarProd(self, constCtxt) del constCtxt return self
def __imul__(self, other): # If one wants to multiply a PyCtxt with an object that is not either a PyCtxt or an int, we throw an error. if not isinstance(other, (PyCtxt, int)): raise TypeError( "PyCtxt '*=' error: lhs must be of type PyCtxt or int instead of type " + str(type(other))) # Multiply directly if other is PyCtxt. if isinstance(other, PyCtxt): self.__pyfhel.mult(self, other) #Otherwise, if one wants to multiply a PyCtxt with an int, we have to create a vector of that int and then encrypted to transform it in PyCtxt. else: # Create new PyCtxt from other if int. constCtxt = self.__pyfhel.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) # Perform multiplication from Afhel::mult self.__pyfhel.mult(self, constCtxt) del constCtxt return self
def __mul__(self, other): # If one wants to multiply a PyCtxt with an object that is not either a PyCtxt or an int, we throw an error. if not isinstance(other, (PyCtxt, int)): raise TypeError( "PyCtxt '*' error: lhs must be of type PyCtxt or int instead of " + str(type(other))) # Create new Ctxt for result. newCtxt = self.copy(self) # Multiply directly if other is PyCtxt. if isinstance(other, PyCtxt): newCtxt *= other #Otherwise, if one wants to multiply a PyCtxt with an int, we have to create a vector of that int and then encrypted to transform it in PyCtxt. else: # Create new PyCtxt from other if int. constCtxt = self.__pyfhel.encrypt( PyPtxt([other for _ in range(self.__length)], self.__pyfhel)) newCtxt *= constCtxt del constCtxt return newCtxt
print("\n") # We will first transform these two vectors in plaintext that could be # encrypted, then we'll tranform the plain text of these two vectors in # homeomorphic encrypted vector. Then we will add and multiply these two # encrypted vectors in an homeomorphic way. Finally, we will decrypted the # result of the addition and multiplication of the two encrypted vectors # and we verify the result is the same that the addition or multiplication # of the two vectors without encryption. print( "******Homeomorphic encryption of the two vectors used during the tests******" ) # Tranform the vectors (use to test the operation **n) in plaintext that # are objects that could be encrypted. ptxt_powern2 = PyPtxt(v_powern2, HE) # Tranform the vectors (use to test the operation polynomial) in plaintext # that are objects that could be encrypted. ptxt_poly = PyPtxt(v_poly, HE) # Encrypted the plaintexts to have Cypher texts that are encrypted in an # homeomorphic way with the key that have been generated before. These # Cypher txt will be use for the tests on the homeomorphic operations # (**n) ctxt_powern2 = HE.encrypt(ptxt_powern2) # Encrypted the plaintexts to have Cypher texts that are encrypted in an # homeomorphic way with the key that have been generated before. These # Cypher txt will be use for the tests on the homeomorphic operations # (polynomial)
"w": 64, "L": 32, "m": -1, "R": 3, "s": 0, "gens": [], "ords": [] } print("Pyfhel DEMO") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") v1 = [1, 2, 3, 4, 5] v2 = [1, 1, 1, 1, 1] p1 = PyPtxt(v1, HE) p2 = PyPtxt(v2, HE) print("Encryting v1: ", v1) c1 = HE.encrypt(p1) print("Encryting v2: ", v2) c2 = HE.encrypt(p2) c1 %= c2 r1 = HE.decrypt(c1) print("Encrypted sum v1 .* v2: ", r1)
"ords": [] } print("Pyfhel DEMO") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") v1 = [range(8), range(3)] v2 = [range(1, 9), range(1, 4)] v3 = [range(8), range(3)] v4 = [range(8), range(3)] v5 = [0] v6 = [1] p1 = PyPtxt(v1, HE) p2 = PyPtxt(v2, HE) p3 = PyPtxt(v3, HE) p4 = PyPtxt(v4, HE) p5 = PyPtxt(v5, HE) p6 = PyPtxt(v6, HE) print("Encrypting v1: ", v1) c1 = HE.encrypt(p1) print("Encrypting v2: ", v2) c2 = HE.encrypt(p2) print("Encrypting v3: ", v3) c3 = HE.encrypt(p3) print("Encrypting v4: ", v4) c4 = HE.encrypt(p4) print("Encrypting v5: ", v5)
"s": 0, "gens": [], "ords": [] } print("Pyfhel DEMO for binary operations") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") v1 = [0, 0, 1, 1] v2 = [0, 1, 0, 1] ones = [1] ptxt1 = PyPtxt(v1, HE) ptxt2 = PyPtxt(v2, HE) pones = PyPtxt(ones, HE) ctxt1 = HE.encrypt(ptxt1) ctxt2 = HE.encrypt(ptxt2) cones = HE.encrypt(pones, fill=1) print("Encrypted v1: ", v1) print("Encrypted v2: ", v2) #XOR operation ctxt1 += ctxt2 # `ctxt1 = ctxt1 + ctxt2` would also be valid v3 = HE.decrypt(ctxt1) print("v1 XOR v2 -> ", v3) print("v3: ", v3)
"sec":128, "w":64, "L":30, "m":-1, "R":3, "s":0, "gens":[], "ords":[]} print("Pyfhel DEMO") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") v1 = [range(8), range(3)] v2 = [range(1,9), range(1,4)] v3 = [range(8), range(3)] v4 = [range(8), range(3)] p1 = PyPtxt(v1, HE) p2 = PyPtxt(v2, HE) p3 = PyPtxt(v3, HE) p4 = PyPtxt(v4, HE) print("Encryting v1: ", v1) c1 = HE.encrypt(p1) print("Encryting v2: ", v2) c2 = HE.encrypt(p2) print("Encryting v3: ", v3) c3 = HE.encrypt(p3) print("Encryting v4: ", v4) c4 = HE.encrypt(p4)
} """Print the Key Generator parameters to let the user knows how his vectors will be encrypted.""" print(" Running KeyGen with params:") print(KEYGEN_PARAMS) """Generate the keys that will be use to encrypted the vectors. The generation of the keys uses the Key Generator parameters. Then print a message to inform the user that the key generation has been completed.""" HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") """Skip a line.""" print("\n") """We will first transform these two vectors in plaintext that could be encrypted, then we'll tranform the plain text of these two vectors in homeomorphic encrypted vector. Then we will add and multiply these two encrypted vectors in an homeomorphic way. Finally, we will decrypted the result of the addition and multiplication of the two encrypted vectors and we verify the result is the same that the addition or multiplication of the two vectors without encryption.""" print( "******Homeomorphic encryption of the two vectors used during the tests******" ) """Tranform the two vectors (use to test the operation +=, -=, *=, ...) in plaintext that are objects that could be encrypted.""" ptxt1 = PyPtxt(v1, HE) ptxt2 = PyPtxt(v2, HE) """Tranform the vectors (use to test the operation **=2, **=3) in plaintext that are objects that could be encrypted.""" ptxt_powerSquare = PyPtxt(v_powerSquare, HE) ptxt_powerCube = PyPtxt(v_powerCube, HE) """Tranform the vectors (use to test the operation **=n) in plaintext that are objects that could be encrypted.""" ptxt_powern = PyPtxt(v_powern, HE) """Tranform the two vectors (use to test the operation +, -, *, ...) in plaintext that are objects that could be encrypted.""" ptxt12 = PyPtxt(v12, HE) ptxt22 = PyPtxt(v22, HE) ptxt1_minus = PyPtxt(v1_minus, HE) ptxt2_minus = PyPtxt(v2_minus, HE) ptxt1_mult = PyPtxt(v1_mult, HE) ptxt2_mult = PyPtxt(v2_mult, HE) ptxt1_scalProd = PyPtxt(v1_scalProd, HE) ptxt2_scalProd = PyPtxt(v2_scalProd, HE)
"""Generate the keys that will be use to encrypted the vectors. The generation of the keys uses the Key Generator parameters. Then print a message to inform the user that the key generation has been completed.""" HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") """Skip a line.""" print("\n") """We will first transform these two vectors in plaintext that could be encrypted, then we'll tranform the plain text of these two vectors in homeomorphic encrypted vector. Then we will add and multiply these two encrypted vectors in an homeomorphic way. Finally, we will decrypted the result of the addition and multiplication of the two encrypted vectors and we verify the result is the same that the addition or multiplication of the two vectors without encryption.""" print("******Homeomorphic encryption of the two vectors used during the tests******") """Tranform the vectors (use to test the operation **n) in plaintext that are objects that could be encrypted.""" ptxt_powern2 = PyPtxt(v_powern2, HE) # v_powern2 = [1,2,3,4,4] """Tranform the vectors (use to test the operation polynomial) in plaintext that are objects that could be encrypted.""" ptxt_poly = PyPtxt(v_poly, HE) #v_poly= [1,2,3,4,5] """Encrypted the plaintexts to have Cypher texts that are encrypted in an homeomorphic way with the key that have been generated before. These Cypher txt will be use for the tests on the homeomorphic operations (**n)""" ctxt_powern2 = HE.encrypt(ptxt_powern2) """Encrypted the plaintexts to have Cypher texts that are encrypted in an homeomorphic way with the key that have been generated before. These Cypher txt will be use for the tests on the homeomorphic operations (polynomial)""" ctxt_poly = HE.encrypt(ptxt_poly) print("Encryption of v1...") print("Encryption of v2...")
def runTest(fileName, testID, p=257, r=1, d=1, c=2, sec=80, w=64, L=10, m=-1, R=3, s=0, gens=[], ords=[]): KEYGEN_PARAMS = { "p": 257, "r": 1, "d": 1, "c": 2, "sec": 80, "w": 64, "L": 10, "m": -1, "R": 3, "s": 0, "gens": [], "ords": [] } KEYGEN_PARAMS['p'] = p KEYGEN_PARAMS['r'] = r KEYGEN_PARAMS['d'] = d KEYGEN_PARAMS['c'] = c KEYGEN_PARAMS['sec'] = sec KEYGEN_PARAMS['w'] = w KEYGEN_PARAMS['L'] = L KEYGEN_PARAMS['m'] = m KEYGEN_PARAMS['R'] = R KEYGEN_PARAMS['s'] = s KEYGEN_PARAMS['gens'] = gens KEYGEN_PARAMS['ords'] = ords print("Pyfhel TEST %d" % (testID)) print(" File: " + fileName) # KEYGEN print(" KEYGEN") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) tic_keyGen = time.time() HE.keyGen(KEYGEN_PARAMS) toc_keyGen = time.time() print(" KeyGen completed") print(" nSlots = %d" % (HE.numSlots())) # DATA CREATION v1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] v2 = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2] v3 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] p1 = PyPtxt(v1, HE) p2 = PyPtxt(v2, HE) p3 = PyPtxt(v3, HE) # ENCRYPTION print(" ENCRYPTION") print(" Encrypting p1, p2, p3 into c1, c2, c3") tic_Encr = time.time() c1 = HE.encrypt(p1) c2 = HE.encrypt(p2) c3 = HE.encrypt(p3) toc_Encr = time.time() t_e = toc_Encr - tic_Encr print(" Encryption completed") # TIMING OPERATIONS print(" OPERATIONS") print(" c1 += c2") tic_Sum = time.time() c1 += c2 e1 = list(np.mod(np.array(v1) + np.array(v2), math.pow(p, r))) toc_Sum = time.time() tic_Decr_Sum = time.time() res1 = HE.decrypt(c1) toc_Decr_Sum = time.time() t_sum = toc_Sum - tic_Sum t_d_sum = toc_Decr_Sum - tic_Decr_Sum f_sum = res1[0] == e1 print(" Result: " + str(res1[0])) print(" Debug: " + str(e1)) print(" c1 *= c2") c1 = HE.encrypt(p1) tic_Prod = time.time() c1 *= c2 e2 = list(np.mod(np.array(v1) * np.array(v2), math.pow(p, r))) toc_Prod = time.time() tic_Decr_Prod = time.time() res2 = HE.decrypt(c1) toc_Decr_Prod = time.time() t_prod = toc_Prod - tic_Prod t_d_prod = toc_Decr_Prod - tic_Decr_Prod f_prod = res2[0] == e2 print(" Result: " + str(res2[0])) print(" Debug: " + str(e2)) print(" c1 %= c2") c1 = HE.encrypt(p1) tic_scpr = time.time() c1 %= c2 e3 = np.mod(sum(np.mod((np.array(v1) * np.array(v2)), math.pow(p, r))), math.pow(p, r)) toc_scpr = time.time() tic_Decr_scpr = time.time() res3 = HE.decrypt(c1) toc_Decr_scpr = time.time() t_scpr = toc_scpr - tic_scpr t_d_scpr = toc_Decr_scpr - tic_Decr_scpr f_scpr = res3[0][0] == e3 print(" Result: " + str(res3[0][0])) print(" Debug: " + str(e3)) # CHECKING LIMITS print(" Maximum number of Sums") t_maxSum = 0 t_maxSd = 0 n_maxSum = 0 resCorrect = 1 a = np.array(v2) b = np.array(v3) while (resCorrect): tic_aux = time.time() c2 += c3 toc_aux = time.time() a = list(a + b) tic_ad = time.time() res_aux = HE.decrypt(c2) toc_ad = time.time() resCorrect = (a == res_aux[0]) n_maxSum += 1 t_maxSum += (toc_aux - tic_aux) t_maxSd += (toc_ad - tic_ad) n_maxSum -= 1 print(" Maximum number of Mults") t_maxMult = 0 t_maxMd = 0 n_maxMult = 0 resCorrect = 1 v2 = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2] p2 = PyPtxt(v2, HE) c2 = HE.encrypt(p2) a = np.array(v2) while (resCorrect): tic_aux = time.time() c2 *= c3 toc_aux = time.time() ab = list(a * b) tic_ad = time.time() res_aux = HE.decrypt(c2) toc_ad = time.time() resCorrect = (ab == res_aux[0]) n_maxMult += 1 t_maxMult += (toc_aux - tic_aux) t_maxMd += (toc_ad - tic_ad) n_maxMult -= 1 # SAVE KEYGEN DATA ON FILE f = open(fileName, 'a') f.write("----------------- TESTCASE %d ----------------\n" % (testID)) f.write(" KeyGen: " + str(KEYGEN_PARAMS) + "\n") f.write(" - nslots = %d\n" % (HE.numSlots())) f.write(" Encryption: t = %f\n" % (t_e)) f.write(" SUM(%d): t = %f\n" % (f_sum, t_sum)) f.write(" PROD(%d): t = %f\n" % (f_prod, t_prod)) f.write(" SC.PROD(%d): t = %f\n" % (f_scpr, t_scpr)) f.write(" LIMITS:\n") f.write( " - SUM: n = %d, t = %f t_avg = %f, td = %f, td_avg=%f\n" % (n_maxSum, t_maxSum, t_maxSum / n_maxSum, t_maxSd, t_maxSd / n_maxSum)) f.write(" - PROD: n = %d, t = %f t_avg = %f, td = %f, td_avg=%f\n" % (n_maxMult, t_maxMult, t_maxMult / n_maxMult, t_maxMd, t_maxMd / n_maxMult)) f.write("---------------------------------------------\n") f.close() return
"R": 3, "s": 0, "gens": [], "ords": [] } print("Pyfhel DEMO") print(" Running KeyGen with params:") print(KEYGEN_PARAMS) HE.keyGen(KEYGEN_PARAMS) print(" KeyGen completed") v1 = [1, 2, 3, 4, 5] v2 = [2, 2, 2, 2, 2] ptxt1 = PyPtxt(v1, HE) ptxt2 = PyPtxt(v2, HE) ctxt1 = HE.encrypt(ptxt1, fill=1) ctxt2 = HE.encrypt(ptxt2, fill=1) print("Encrypted v1: ", v1) print("Encrypted v2: ", v2) ctxt1 += ctxt2 # `ctxt1 = ctxt1 + ctxt2` would also be valid v3 = HE.decrypt(ctxt1) print("add: v1 + v2 -> ", v3) print("v3: ", v3) print("v2: ", v2)