def evaluate_response(public_key, private_key, response): # rebuild the encrypted numbers with our public key data = response.json() e_south_border_distance = paillier.EncryptedNumber(public_key, int(data['lat'])) e_north_border_distance = paillier.EncryptedNumber(public_key, int(data['lat2'])) e_west_border_distance = paillier.EncryptedNumber(public_key, int(data['lng'])) e_east_border_distance = paillier.EncryptedNumber(public_key, int(data['lng2'])) # decrypt the encrypted distances south_border_distance = private_key.decrypt(e_south_border_distance) north_border_distance = private_key.decrypt(e_north_border_distance) west_border_distance = private_key.decrypt(e_west_border_distance) east_border_distance = private_key.decrypt(e_east_border_distance) # evaluate the distances match_x = east_border_distance >= 0 and west_border_distance <= 0 match_y = north_border_distance >= 0 and south_border_distance <= 0 if match_x and match_y: print('Position is in Colorado') elif match_x: print('Position is in between longitude boundaries') elif match_y: print('Position is in between latitude boundaries') else: print('Position is elsewhere')
def calculate_geo(): # rebuild public key g = int(request.args.get('g')) n = int(request.args.get('n')) # g is n+1 on both sides pubkey = paillier.PaillierPublicKey(n=n) # load the coordinates as EncryptedNumber type lat = paillier.EncryptedNumber(pubkey, int(request.args.get('lat'))) lng = paillier.EncryptedNumber(pubkey, int(request.args.get('lng'))) # use same key to encrypt the geobox west = pubkey.encrypt(geobox[0]) south = pubkey.encrypt(geobox[1]) east = pubkey.encrypt(geobox[2]) north = pubkey.encrypt(geobox[3]) latoffset = (south - lat) * random() latoffset2 = (north - lat) * random() lngoffset = (west - lng) * random() lngoffset2 = (east - lng) * random() return json.dumps({ "lat": str(latoffset.ciphertext()), "lat2": str(latoffset2.ciphertext()), "lng": str(lngoffset.ciphertext()), "lng2": str(lngoffset2.ciphertext()), })
def calculsomme(nom1, nom2): connec = db_connexion(db_user, db_password, db_host, db_db) cur = connec.cursor() query = "SELECT salairePHE FROM salaire WHERE nom=(%s) OR nom=(%s)" cur.execute(query, (nom1, nom2)) somme = 0 for salairePHE in cur: #Chargement des attributs dans une variables recuperationPHE = json.loads(salairePHE[0]) #Recuperation de la clé publique contenue n = recuperationPHE['public_key'] public_key = paillier.PaillierPublicKey(n=int(n)) #Regénération de l'objet chiffré valeurSalaire = paillier.EncryptedNumber( public_key, int(recuperationPHE['ciphertext']), int(recuperationPHE['exponent'])) #Somme des salaires somme += valeurSalaire cur.close db_close(connec) #Sérialisation de la somme serieSomme = { 'public_key': public_key.n, 'ciphertext': str(somme.ciphertext()), 'exponent': somme.exponent } return serieSomme
def read_csv_database(filename, public_key, is_encrypted=True): """Generate an encrypted database from a CSV.""" database = [] row_len = 0 with open(filename, newline='') as csvfile: reader = csv.reader(csvfile) for row in reader: if not row_len: row_len = len(row) elif len(row) != row_len: raise RuntimeError("Uneven csv, lengths {} and {}".format( len(row), row_len)) db_row = [] for cell_val in map(int, row): if is_encrypted: enc_val = paillier.EncryptedNumber(public_key, cell_val) else: enc_val = public_key.encrypt(cell_val) db_row.append(enc_val) database.append(tuple(db_row)) return tuple(database)
def decryptcipher(self, cipher, public_key=None, private_key=None): if not public_key: public_key = self.public_key if not private_key: private_key = self._private_key value = paillier.EncryptedNumber(public_key, cipher) return self.decrypt(value, private_key)
def receiveVotes(self): self.comm.initiateConn() res = self.comm.receiveMessage('bb') f = open('../common/comm.line', 'r') self.votes = json.loads(f.read()) f.close() self.comm.closeConn() print(self.votes) self.comm.joinConn(self.eb_location[0], self.eb_location[1]) res = self.comm.receiveMessage('eb') msg = json.loads(res) self.ebpPub = paillier.PaillierPublicKey(g=int(msg['g']), n=int(msg['n'])) for i in range(len(self.votes)): for j in range(len(self.votes[i])): self.votes[i][j] = paillier.EncryptedNumber( self.ebpPub, int(self.votes[i][j]), 0) totals = [] if (len(self.votes) > 0): totals = self.votes.pop(0) for i in self.votes: if len(self.votes) != len(totals): quit() for j in self.votes[i]: totals[j] += self.votes[i][j] totals_expanded = [str(x.ciphertext()) for x in totals] f = open('../common/comm.line', 'w') f.write(json.dumps(totals_expanded)) f.close() self.comm.sendMessage("SENTOFF" * 10) self.comm.closeConn() quit()
def query_pred(input_vector: List[float]) -> int: public_key, private_key = paillier.generate_paillier_keypair() encrypted_number_list = [ int(public_key.encrypt(x, precision=2**(-16)).ciphertext()) for x in input_vector ] data = { 'pub_key_n': public_key.n, 'enc_feature_vector': encrypted_number_list } response = post(URL + ':' + PORT + END_POINT, json=data) if response.status_code != 200: raise Exception(response.text) raw_enc_prediction = response.json()['enc_prediction'] enc_prediction = paillier.EncryptedNumber( public_key, raw_enc_prediction, exponent=-8) prediction = private_key.decrypt(enc_prediction) return prediction
def encrFromJson(json): pubK = paillier.PaillierPublicKey(n=json['public_key']['n']) value = paillier.EncryptedNumber( public_key=pubK, ciphertext=json['_EncryptedNumber__ciphertext'], exponent=json['exponent']) value._EncryptedNumber__is_obfuscated = json[ '_EncryptedNumber__is_obfuscated'] return value
def query_pred(arr, func=send_query): exponent = 16 server_side_exponent = 16 public_key, private_key = paillier.generate_paillier_keypair(n_length=2048) enc_input = [public_key.encrypt(int(x * 2**exponent)) for x in arr] val = func(public_key.n, [int(x.ciphertext()) for x in enc_input]) enc_val = paillier.EncryptedNumber(public_key, val) result = private_key.decrypt(enc_val) / (2**(exponent + server_side_exponent)) return result
def KStateTransition(self): print( "#######################K-th State Transistion#############################" ) print("---Matrix transition---") print(self.mat) #Restore the data from the DB self.__retrieveData() #Generation of the K-th random number self.r_a.append(random.randint(0, self.Q_len - 1)) print("---r_a---") print(self.r_a) #Blinding all the matrix element for i in range(0, self.Al_len): for j in range(0, self.Q_len): self.mat[i][j] = (self.mat[i][j] + self.r_a[self.k]) % self.Q_len #Shift left of r_a(k-1) position self.mat[i] = np.roll(self.mat[i], -self.r_a[self.k - 1]) print("---Rolled matrix---") print(self.mat) #Now i have to read data sent from client length = int(self.headers.get('Content-length')) data = self.rfile.read(length) recive_data = json.loads(data) puk = recive_data['PublicKey'] #Rebuild of the encrypted vector sent by the client public_key = paillier.PaillierPublicKey(n=int(puk['n'])) encrypted_e = [ paillier.EncryptedNumber(public_key, int(x[0]), int(x[1])) for x in recive_data['CipherText'] ] #v is the encrypted vector obtained by multiplicating transition matrix to encrypted vector recived enc_mean = np.mean(encrypted_e) v_encrypt = np.dot(self.mat, encrypted_e) #Setting of the data to sent to client data = {} data["BlindVector"] = [(str(x.ciphertext()), x.exponent) for x in v_encrypt] self.__sendResponse(data) if self.k != self.t_len: self.k = self.k + 1 #storage of the data into the DB self.__storeData()
def client_sync(self, server_addr, target_data, method, params): dt = self.data.data url = f"http://{server_addr}/{method}" # print(url) while True: try: r = requests.get(url, params=params) print(params) except Exception as e: # print(f"request error: {e}") print(r.status_code, 'error') if r.status_code == 200: try: # print(r.json()) data = r.json()['content'] if type(data) is list: public_key = dt['public_key'] if type(data[0]) is list: data = [ paillier.EncryptedNumber( public_key, int(x[0]), int(x[1])) for x in data ] data = np.asarray(data) elif type(data[0]) is float: data = np.asarray(data) else: data = paillier.EncryptedNumber( public_key, int(data[0]), int(data[1])) elif type(data) is dict: data = paillier.PaillierPublicKey(n=int(data['n'])) dt.update({target_data: data}) break except Exception as e: print("fail to transform data error: %s" % e) print(data) else: print( f"{self.name} failed to run method {method}, waiting....") sleep(1) print(f"{self.name} successfully finished {method}")
def HE_deserialize(received_dict_JSON): """take JSON and extract public_key and array of encrypted numbers""" received_dict = json.loads(received_dict_JSON) pk = received_dict['public_key'] public_key_rec = paillier.PaillierPublicKey(n=int(pk['n'])) enc_nums_rec = [ paillier.EncryptedNumber(public_key_rec, int(x[0]), int(x[1])) for x in received_dict['encrypted_numbers'] ] return public_key_rec, enc_nums_rec
def results(): if request.method == 'POST': tally_mongo_encrypted = [i for i in collection.find()] encriptado_temp = [ paillier.EncryptedNumber(public_key_server, int(j)) for j in tally_mongo_encrypted[len(tally_mongo_encrypted) - 1]["votes"] ] # gets the current tally values that are record in the db. Convert those values in EncryptedNumber objects. (Current values is last ) temp = {} temp['output'] = [ private_key_server.decrypt(x) for x in encriptado_temp ] # decrypt values to be shown. return json.dumps(temp)
def GetRDDlist(pub_key, rddfile): hedatadict = {} with open(rddfile, 'r') as f: head = columnname.strip().split(',') #ignore fist line f.readline() line = f.readline() while line: line_list = line[:-1].split(',') tmp_dict = dict(zip(head, line_list)) for header in head: tmpdatalist = tmp_dict[header].split("\t") if header not in hedatadict: hedatadict[header] = [ paillier.EncryptedNumber(pub_key, int(tmpdatalist[0]), int(tmpdatalist[1])) ] else: hedatadict[header].append( paillier.EncryptedNumber(pub_key, int(tmpdatalist[0]), int(tmpdatalist[1]))) line = f.readline() return hedatadict
def prediction(): try: query = request.json if request.method == "POST" and request.json else {} cipher = query.get("enc_feature_vector") pk_n = query.get("pub_key_n") except: return ERR_BAD_ENCODING, 400 if pk_n is None: return ERR_NO_PUB_KEY, 400 if cipher is None: return ERR_NO_INPUT, 400 if not isinstance(cipher, list) or len(cipher) != len(model_coeffs): return ERR_BAD_DIM, 400 if len(set(cipher)) <= 2: return ERR_ATTACK_DETECT, 403 try: pk = paillier.PaillierPublicKey(pk_n) model_coeffs_enc = [ paillier.EncodedNumber.encode(pk, coeff, precision=precision) for coeff in model_coeffs ] model_bias_enc = paillier.EncodedNumber.encode(pk, model_bias, precision=precision) except: return ERR_BAD_PK, 400 try: cts = [] for ct in cipher: if not isinstance(ct, int) or ct < 0 or ct > pk.nsquare: raise cts += [paillier.EncryptedNumber(pk, ct, -4)] cres = sum( (ct * coeff for (ct, coeff) in zip(cts, model_coeffs_enc))) + model_bias_enc ctres = cres.ciphertext() except: return ERR_BAD_IN, 400 return_dict = {"enc_prediction": ctres} return jsonify(return_dict), 200
def process(): if request.method == 'POST': received_dict = json.loads(request.data) public_key_rec = paillier.PaillierPublicKey( n=int(received_dict['public_key']['n'])) enc_nums_rec = [ paillier.EncryptedNumber(public_key_rec, int(x[0]), int(x[1])) for x in received_dict['values'] ] x = randint(1, 10) result = {} result['values'] = [(str(enc_num.ciphertext()), enc_num.exponent) for enc_num in [(num * x) for num in enc_nums_rec]] return json.dumps(result)
def _reencrypt_phe_to_fhe(self, values_cipher): phe_sk = self.session['private_keys']['phe_sk'] phe_pk = self.session['public_keys']['phe_pk'] values_enc = [ paillier.EncryptedNumber(phe_pk, int(x), 0) for x in values_cipher ] values = [phe_sk.decrypt(x) for x in values_enc] fhe_sk = self.session['private_keys']['fhe_sk'] fhe_pk = self.session['public_keys']['fhe_pk'] ctx = self.session['ctx'] vm = ctx.make_virtual_machine(fhe_pk) fhe_values = [EncUInt8.from_uint8(vm, fhe_sk, ctx, x) for x in values] return fhe_values
def receiveTotals(self): self.voting = False self.waiting = True self.comm.sendMessage(json.dumps('ENDVOTING')) self.comm.closeConn() self.comm.initiateConn() pub_rec = {'g': int(self.pPub.g), 'n': int(self.pPub.n)} self.comm.sendMessage(json.dumps(pub_rec)) res = self.comm.receiveMessage('ca') print('got here') f = open('../common/comm.line', 'r') res = f.read() f.close() msg = json.loads(res) print(msg) tmp = [paillier.EncryptedNumber(self.pPub, int(v), 0) for v in msg] decrypted_total_list = [self.pPriv.decrypt(v) for v in tmp] print(decrypted_total_list)
def vote(request): if request.method == 'POST': # create a form instance and populate it with data from the request: form = VoteForm(request.POST) # check whether it's valid: if form.is_valid(): key = paillier.PaillierPublicKey(int(PublicKey.objects.all()[0].n)) voted_for = form.cleaned_data['candidate'] for candidate in Candidate.objects.all(): if candidate == voted_for: value = 1 else: value = 0 new_vote = key.encrypt(value) if len(candidate.voted) > 0: new_vote = new_vote + paillier.EncryptedNumber( key, int(candidate.voted)) candidate.voted = new_vote.ciphertext() candidate.save() return render(request, 'thanks.html') return render(request, 'vote.html', {'form': VoteForm()})
def results(request): if request.method == 'POST': form = DecryptResultsForm(request.POST) if form.is_valid(): pub_key = paillier.PaillierPublicKey( int(PublicKey.objects.all()[0].n)) p = int(form.cleaned_data['p']) q = int(form.cleaned_data['q']) results = {} priv_key = paillier.PaillierPrivateKey(pub_key, p, q) for candidate in Candidate.objects.all(): if len(candidate.voted) == 0: results[candidate] = 0 else: results[candidate] = priv_key.decrypt( paillier.EncryptedNumber(pub_key, int(candidate.voted))) return render(request, 'results.html', {'results': results}) return render(request, 'decrypt_results.html', {'form': DecryptResultsForm()})
def get_phe_votes(): data = request.json keys = data.keys() data = data.values() print(keys) with open('phe_keys.pickle', 'rb') as f: public_key, private_key = pickle.load(f) # print (public_key.n) votes = [ paillier.EncryptedNumber(self.phe_pk, int(x), 0) for x in data ] votes_dec = [private_key.decrypt(x) for x in votes] print("PHE VOTES: ", votes_dec) votes = np.array(votes) self.votes_enc = votes + self.votes_enc return ''
def process(): if (request.method == 'POST'): data = request.json if data: print("Input Data: ", data) numbers = [int(e) for e in data['input'].split(',')] json_content = encrypt(numbers) result = requests.post(data['dns'], json=json_content) data = json.loads(result.text) #decryption enc_nums = [ paillier.EncryptedNumber(public_key, int(x[0]), int(x[1])) for x in data['values'] ] plain_nums = {} plain_nums['output'] = [private_key.decrypt(x) for x in enc_nums] results = json.dumps(plain_nums) return results
def decrypt_weight(encrypted_gradient, param_dict): search_dict = {} search_dict.update(param_dict) search_dict.pop("target_client") private_key_dict = mongo.db.private_key.find_one(search_dict) if private_key_dict: private_key_dict.pop("_id") private_key = PrivateKey(**private_key_dict) private_key = private_key.regenerate_object() public_key = private_key.public_key encrypted_gradient = [ paillier.EncryptedNumber(public_key, int(x[0]), int(x[1])) for x in encrypted_gradient ] gradient = [private_key.decrypt(x) for x in encrypted_gradient] gradient_dict = {} gradient_dict.update(param_dict) gradient_dict.update({'content': gradient}) mongo.db.gradient.insert_one(gradient_dict) else: print("fail to find the corresponding private key") print(param_dict)
def deserialiseEncrypted(pubKey, input): cipher, exponent = input.split(" ") output = paillier.EncryptedNumber(pubKey, int(cipher), int(exponent)) return output
# Result: boolean flag that indicates the end of the protocol #} headers = { 'Content-length': len(ser_data), 'Cookie': response.headers['Set-Cookie'], 'Result': False } connection.request('GET', '/', ser_data.encode(), headers=headers) #Server's response containing the blinded vector and cardinality of states set response = connection.getresponse() data = json.loads(response.read()) #Rebuild and decryption of the data received from the previous request en_vet = [ paillier.EncryptedNumber(pubkey, int(x[0]), int(x[1])) for x in data['BlindVector'] ] vet = [privkey.decrypt(x) for x in en_vet] print("---Vector receive---") print(vet) r_b = vet[i] #Last GET request that communicates the end of the trace of the user headers = { 'Content-length': 0, 'Cookie': response.headers['Set-Cookie'], 'Result': True } connection.request('GET', '/', headers=headers)
# Get keys for the encryption public_key, private_key = paillier.generate_paillier_keypair() # Encrypt the numbers in the list encrypted_number_list = [public_key.encrypt(x).ciphertext() for x in vector] prediction_data = { "email": "*****@*****.**", "pk": public_key.n, "encrypted_input": encrypted_number_list, "model": 1 } post2 = requests.post(prediction_service_addr, json=prediction_data) # Get the encrypted prediction encrypted_prediction = json.loads(post2.text)["encrypted_prediction"] # print("Encrypted predicion: {}".format(encrypted_prediction)) # Decrypt the prediction and deliver it for the token pred = paillier.EncryptedNumber(public_key, encrypted_prediction) decrypted_prediction = private_key.decrypt(pred) # print("Decrypted prediction: {}".format(decrypted_prediction)) token_data = { "email": "*****@*****.**", "prediction": decrypted_prediction } post3 = requests.post(get_token_addr, json=token_data) token = json.loads(post3.text)["token"] print(token)
def process(): ''' Workflow: - Gets request from the client through Ajax - The data contains the encrypted ballot, id, hash. - id value look up in the database. Verify if is registered and has not voted. - Client send encrypted message with the private key. The server look up the id in the database and returns the public key already registered ''' if request.method == 'POST': vote_encrypted = json.loads( request.data) # gets encrypted ballot, id and secret mesage. try: # in case of failure, returns an output with the message "Failure", otherwise, "Success id_value = vote_encrypted[1] # id of the voter package = vote_encrypted[0][ 'values'] # encrypted values ciphertext that conntins the encrypted ballot. It is also use to form the hash to check integrity and detect tampering encrypted_hash = vote_encrypted[ 2] # signed hash to be compared with the encripted message generated for the server ''' encrypted_message is a message signed with the private key of the client and verify with the public key that the server has. The server look up for the public key in the database using the id of the voter. Mensaje is extracted from the "package" and after the encrypted message is decrypted, it is compare with "mensaje" and checks if they are equal. ''' if voters_info.count_documents( {"id": id_value}, limit=1 ) != 0: # checks if the voter has been already register. NOTE: it's safe to assume that if a ballot reach this point, the voter existes since the client perform a pre-screening voter_public_key, has_voted = search_voter_registration( id_value) #gets from the voter database the public key value_hash = hash_integrity(package) if has_voted == True: # user has already cast a vote app.logger.info("voter already voted") return warnings( "Error. Vote already casted for this voter.") try: check_signature_integrity(voter_public_key, value_hash, encrypted_hash) app.logger.info("Good signature") except: app.logger.info( "Possible tampering" ) # when there is a problem with the integrity of the signature, a modification can be assumed. return warnings("Error. Possible vote tampering.") ''' Gets public key from the decrypt_server and transform it to an object. It is used to transform the ciphertext of the current tally into EncryptedNumber objects that can perform addition with encrypted data ''' public_key_rec = get_public_he( ) #server_decrypt holds private and public key, here the public key is obtanained ''' Encrypted ballot is sent from the client in ciphertext. With the public key, this ciphertext is transformed in EncryptedNumber with H.E properties. THis contains the encrypted ballot. ''' vote_received_enc = [ paillier.EncryptedNumber(public_key_rec, int(x[0]), int(x[1])) for x in package ] # convert the cipher values oof the ballot to objects. ''' Extract from the election database the current tally and transform the ciphertext into encryptednumber objects with encrypted information of the tally that can perform additions. ''' tally_mongo_encrypted = [i for i in tally_votes.find() ] # gets tally from database encriptado_temp = [ paillier.EncryptedNumber(public_key_rec, int(j)) for j in tally_mongo_encrypted[len(tally_mongo_encrypted) - 1]["votes"] ] # gets the current tally values that are record in the db. Convert those values in EncryptedNumber objects. (Current values is last ) ''' Perform an addition between the tally and the ballot. Update tally ''' add_vote(encriptado_temp, vote_received_enc) # add the ballot to the tally cipher_values = [ str(i.ciphertext()) for i in encriptado_temp ] # creates list with the ciphertext to be stored in mongodb verification_hash = hash_audit(cipher_values) app.logger.info(verification_hash) ''' Insert the updated tally to the election database ''' try: tally_votes.insert_one({ "votes": cipher_values, "verification_hash": verification_hash }) # insert value to except: ''' If for any reason, writting the ballot fails, it stops anything else and return error. No roll back needed ''' message = "Error. Updated tally where not registered correctly. Try again" app.logger.info(message) return warnings(message) ''' Update the information of the elector's database. Delete the public key to avoid make extra sure that a person cannot vote twice. ''' try: voters_info.update_one( {'id': id_value}, {"$set": { "has_voted": True, "pk": "" }}) except: ''' If updating the information of the voters fails for any reason (update the voters "has_voted" is not set to true) then it rolls back the vote just entered and ask to try again. ''' message = "Error. The voter's status couldn't be updated. Rolling back vote. Try again" votes_list = [i for i in tally_votes.find()] tally_votes.delete_one({'_id': votes_list[-1]["_id"]}) app.logger.info(message) return warnings(message) temp = {} temp[ 'output'] = "Success! For audit, please keep this code: " + verification_hash # confirmation. If gets to this point we can assume the vote has been registered correctly else: app.logger.info("Voter is not registered!") return warnings("Failure! Voter is not registered.") except: temp = {} temp['output'] = "Failure! Error in server." # confirmation results = json.dumps(temp) return results
def testCreateEncryptedNumber(self): paillier.EncryptedNumber(self.public_key, 5)
from math import gcd import sys sys.setrecursionlimit(100000) p = 310013024566643256138761337388255591613 q = 319848228152346890121384041219876391791 n = p * q g = 99157116611790833573985267443453374677300242114595736901854871276546481648884 c = 2433283484328067719826123652791700922735828879195114568755579061061723786565164234075183183699826399799223318790711772573290060335232568738641793425546869 k = 1 l = ((p - 1) * (q - 1)) // gcd(p - 1, q - 1) pk = paillier.PaillierPublicKey(n) pp = paillier.PaillierPrivateKey(pk, p, q) en = paillier.EncryptedNumber(pk, c) m = pp.decrypt(en) print(unhexlify(hex(m)[2:])) #m = div(pow(c, l, n * n), pow(g, l, n * n)) ''' [msieve153] > .\msieve153.exe -q -v 99157116611790833573985267443453374677300242114595736901854871276546481648883 Msieve v. 1.53 (SVN 1005) Sat Apr 20 10:47:37 2019 random seeds: b3564e14 fdbd8498 factoring 99157116611790833573985267443453374677300242114595736901854871276546481648883 (77 digits) searching for 15-digit factors commencing quadratic sieve (77-digit input) using multiplier of 3 using generic 32kb sieve core
print(f"encrypted_b=\n{hex(encrypted_b)}\n") # Generating the template with open("src/paillier_hello_template.c", "r") as template_file, \ open("dist/paillier_hello.c", "w") as output_file: template_content = template_file.read() template = jinja2.Template(template_content) output = template.render(public_key_hex=hex(public_key.n)[2:], encrypted_a=encrypted_a, encrypted_b=encrypted_b) output_file.write(output) print("Generated 'dist/paillier_hello.c' - please compile, and load") print( "Compile: emcc -o ./dist/paillier_hello.html ./dist/paillier_hello.c <PATH to libpaillier>/libpaillier/*.c <Path to libGMP>/libgmp.a" ) print("Load: emrun --no_browser --port 8080 ./dist") # Getting the result result = input(">> encrypted_result=") # Decrypting result_value = paillier.EncryptedNumber(public_key, int(result, 16)) decrypted_result = private_key.decrypt(result_value) print(f"decrypted_result=\n{decrypted_result}") test_result = a + b if decrypted_result == test_result: print("Results match!")