def test_encryption(self): for tv in self.tve: d = self.convert_tv(tv, True) key = ElGamal.construct(d['key']) ct = key._encrypt(d['pt'], d['k']) self.assertEquals(ct[0], d['ct1']) self.assertEquals(ct[1], d['ct2'])
def test_signing(self): for tv in self.tvs: d = self.convert_tv(tv, True) key = ElGamal.construct(d['key']) sig1, sig2 = key._sign(d['h'], d['k']) self.assertEquals(sig1, d['sig1']) self.assertEquals(sig2, d['sig2'])
def _test_random_key(self, bits): elgObj = ElGamal.generate(bits, Random.new().read) self._check_private_key(elgObj) self._exercise_primitive(elgObj) pub = elgObj.publickey() self._check_public_key(pub) self._exercise_public_primitive(elgObj)
def deserialize_ElGamalPrivateKey(bytestring): '''constructs an ElGamal Public Key from a bytestring''' padded_size = len(bytestring) // 4 assert padded_size * 4 == len(bytestring), "Wrong bytestring length" p = Integer.from_bytes(bytestring[:padded_size]) g = Integer.from_bytes(bytestring[padded_size:2 * padded_size]) y = Integer.from_bytes(bytestring[2 * padded_size:3 * padded_size]) x = Integer.from_bytes(bytestring[3 * padded_size:]) return ElGamal.construct((p, g, y, x))
def test_verification(self): for tv in self.tvs: d = self.convert_tv(tv, True) key = ElGamal.construct(d['key']) # Positive test res = key._verify( d['h'], (d['sig1'],d['sig2']) ) self.failUnless(res) # Negative test res = key._verify( d['h'], (d['sig1']+1,d['sig2']) ) self.failIf(res)
def test_verification(self): for tv in self.tvs: d = self.convert_tv(tv, True) key = ElGamal.construct(d['key']) # Positive test res = key._verify(d['h'], (d['sig1'], d['sig2'])) self.failUnless(res) # Negative test res = key._verify(d['h'], (d['sig1'] + 1, d['sig2'])) self.failIf(res)
def predict_rating(self, i, k): # predict rating of user i, item k denoted P_i,k enc_obj = ElGamal.construct( (self.p, self.g, self.user_list[i].getPubKey())) encrypted_ratings = self.user_list[i].sendRatings(self.m) sum_of_sims = 0 l = 10 #modified top_l = sorted(range(len(self.simMat[k])), key=lambda i: self.simMat[k][i])[-1 * l:] #modified #print(top_l) #print(self.simMat[k]) for j in range(self.m): if k != j: sum_of_sims += self.simMat[k][j] R_k = self.avg_ratings[k] * 200 #print(R_k) #print(sum_of_sims) #print(R_k*sum_of_sims) a = number.getRandomRange(2, self.p - 1, Random.new().read) first_term = elgEncrypt(enc_obj, pow(self.g, int(R_k * sum_of_sims), self.p), a) result = (1, 1) result = self.addElgamal(result, first_term, self.p) for j in range(self.m): if k != j: a = number.getRandomRange(2, self.p - 1, Random.new().read) R_j = self.avg_ratings[j] * 200 denom = elgEncrypt(enc_obj, pow(self.g, int(R_j), self.p), a) denom_inv = self.inv_pair(denom) inter_result = self.addElgamal(encrypted_ratings[j], denom_inv, self.p) #inter_result = encrypted_ratings[j] inter_result = (inter_result[0]**self.simMat[k][j], inter_result[1]**self.simMat[k][j]) result = self.addElgamal(result, inter_result, self.p) a = number.getRandomRange(2, self.p - 1, Random.new().read) encrypted_denom = elgEncrypt(enc_obj, pow(self.g, sum_of_sims, self.p), a) # send results to user obtain rating predicted_rating = self.user_list[i].calculate_prediction( result, encrypted_denom) result = predicted_rating / 200 #result = self.avg_ratings[k]# only the average if result > 5: result = 5 return result
def initiateContact(self, other: str, pgVals: (int, int) = None): if (pgVals is None): elGam = ElGamal.generate( 256, RandBytes) # Would be larger p in practice p = int(elGam.p) g = int(elGam.g) else: p = pgVals[0] g = pgVals[1] self.pgPairs[other] = (p, g) self.private[other] = random.randrange(p) self.public[other] = pow(g, self.private[other], p) return ((p, g), self.name, other)
def deserialize_ElGamalPublicKey(bytestring): '''constructs an ElGamal Public Key from a bytestring''' padded_size = len(bytestring) // 3 assert padded_size * 3 == len(bytestring), "Wrong bytestring length" p = Integer.from_bytes(bytestring[:padded_size]) g = Integer.from_bytes(bytestring[padded_size:2 * padded_size]) y = Integer.from_bytes(bytestring[2 * padded_size:]) return ElGamal.construct((p, g, y)) def export_val(self): '''Returns a bytestring.''' padded_size = int(np.round(key.p.size_in_bits() / 8)) return self.c1.to_bytes(padded_size) + self.c2.to_bytes(padded_size) @classmethod def byte_init(cls, key, bytestring): '''Returns a Ciphertext from a bytestring containing c1 and c2''' padded_size = int(np.round(key.p.size_in_bits() / 8)) assert (len(bytestring) == 2 * padded_size) c1 = Integer.from_bytes(bytestring[:padded_size]) c2 = Integer.from_bytes(bytestring[padded_size:]) return cls(key, c1, c2)
def sendRatings(self, num_item): enc_obj = ElGamal.construct((self.p, self.g, self.pubElgamalKey)) encrypted_ratings = {} for i in range(num_item): k = number.getRandomRange(2, self.p - 1, Random.new().read) if i in self.ratings: encrypted_ratings[i] = elgEncrypt( enc_obj, pow(self.g, self.ratings[i] * 100, self.p), k) else: temp = 1 sum_rat = 0 rat_cnt = 0 for r in self.ratings: sum_rat += self.ratings[r] rat_cnt += 1 if rat_cnt == 0: user_avg = 0 else: user_avg = sum_rat / rat_cnt encrypted_ratings[i] = elgEncrypt( enc_obj, pow(self.g, int(user_avg * 100), self.p), k) return encrypted_ratings
def hub_round0b(key_template, hospital_public_shares): '''Generating the shared public key from a list of partial shares from the hospitals as bytestrings Returns a dictionary with: key_public: a new ElGamal public key time: amount of time elapsed for this function ''' start = time.perf_counter() key_y = Integer(1) for bytestring_y in hospital_public_shares: curr_y = Integer.from_bytes(bytestring_y) key_y = (curr_y * key_y) % key_template.p key_public = ElGamal.construct((key_template.p, key_template.g, key_y)) elapsed = time.perf_counter() - start answer_dict = {} answer_dict['key_public'] = key_public answer_dict['curr_y'] = key_y # answer_dict['transmit'] = key_y_bytestring answer_dict['transmit'] = serialize_ElGamalPublicKey(key_public) answer_dict['time'] = elapsed return answer_dict
def test_decryption(self): for tv in self.tve: d = self.convert_tv(tv, True) key = ElGamal.construct(d['key']) pt = key._decrypt((d['ct1'], d['ct2'])) self.assertEquals(pt, d['pt'])
def findQNR(p): r = random.randint(1, p - 1) while isQR(r, p) == 1: r = random.randint(1, p - 1) return r # Find a message that is a QR, note: half of messages are not QR def findQR(p): r = random.randint(1, p - 1) return pow(r, 2, p) # Key generation. We use 512-bit only for better performance print "Generating the key..." key = ElGamal.generate(512, Random.new().read) wrong = 0 runs = 1000 print "Running the experiment..." for i in xrange(runs): p = int(key.p) pk = int(key.y) # Select two messages plaintexts = dict() plaintexts[0] = findQNR(p) plaintexts[1] = findQR(p)
def construct_key(key_template, sec): '''Constructs an ElGamal key from a secret and a template''' key_x2 = Integer(sec) key_y2 = pow(key_template.g, key_x2, key_template.p) key = ElGamal.construct((key_template.p, key_template.g, key_y2, key_x2)) return key
def setServerPubKey(self, Y): elgamal_tuple = (self.p, self.g, Y) # consturct elgamal object from the server public key self.encryptObj = ElGamal.construct(elgamal_tuple)
def enc_test_hll(key=key, hyperloglogs=None): '''Runs a full simulation of an encrypted HLL merger. You can pass a list of hyperloglogs in. If you don't, this test will randomly simulate hyperloglogs from 100 hospitals. ''' answer_dict = {} sketch_size = 32 if hyperloglogs is None: raise ValueError else: num_hospitals = len(hyperloglogs) num_buckets = len(hyperloglogs[0]) # Preprocessing print("Preprocessing time for key sharing: ", end="") start = time.time() key_template = key hospital_private_keys = [ Integer(randint(2, int(key_template.p - 1))) for _ in range(num_hospitals) ] key_y = Integer(1) hospital_keys = [ construct_key(key_template, x) for x in hospital_private_keys ] elapsed = time.time() - start print(elapsed) answer_dict['hospital_round0_time'] = elapsed start = time.time() print("Combine to form public key: ", end="") for x in hospital_private_keys: curr_y = pow(key_template.g, x, key_template.p) key_y = (curr_y * key_y) % key_template.p key_public = ElGamal.construct((key_template.p, key_template.g, key_y)) elapsed = time.time() - start print(elapsed) answer_dict['hub_round0_time'] = elapsed print("Hospital-side computation round 1: Unroll & encrypt: ", end="") start = time.time() unrolled_hyperloglogs = [[unroll(i, sketch_size) for i in hll] for hll in hyperloglogs] encrypted_hyperloglogs = [] for k, uhll in enumerate(unrolled_hyperloglogs): encrypted_hyperloglog = [[encrypt(key_public, x) for x in il] for il in uhll] encrypted_hyperloglogs.append(encrypted_hyperloglog) elapsed = time.time() - start print(elapsed) answer_dict['hospital_round1_time'] = elapsed start = time.time() print("Server-side computation round 1.5: collapse encrypted HLL: ", end="") collapsed_enc_hll = [] for i in range(num_buckets): collapsed_enc_hll_i = [] for j in range(sketch_size): one = encrypt(key_public, 1) curr = encrypt(key_public, 1) for k in range(num_hospitals): curr = curr + encrypted_hyperloglogs[k][i][j] curr = curr.private_equality_test( one ) # If equal 1, then there were no items with that many leading 0's collapsed_enc_hll_i.append(curr) collapsed_enc_hll.append(collapsed_enc_hll_i) elapsed = time.time() - start print(elapsed) answer_dict['hub_round1.5_time'] = elapsed print("Hospital-side computation round 2: compute shared secret parts: ", end="") # Hospital-side computation round 2. Get all shared secrets try: p = myglobals.parallel_pool myglobals.hospital_keys = hospital_keys myglobals.collapsed_enc_hll = collapsed_enc_hll all_hospital_secrets_with_time = p.map( get_hospital_shared_secrets, range(len(myglobals.hospital_keys))) all_hospital_secrets = [x[0] for x in all_hospital_secrets_with_time] round2_times = [x[1] for x in all_hospital_secrets_with_time] elapsed = sum(round2_times) except AttributeError: start = time.time() all_hospital_secrets = [] for k in range(num_hospitals): secrets = [] for i in range(num_buckets): secrets_by_bucket = [] for j in range(sketch_size): secrets_by_bucket.append( shared_secret(hospital_keys[k], collapsed_enc_hll[i][j])) secrets.append(secrets_by_bucket) all_hospital_secrets.append(secrets) elapsed = time.time() - start print(elapsed) answer_dict['hospital_round2_time'] = elapsed start = time.time() print( "Server-side computation round 2.5. Combine shared secrets to decrypt: ", end="") # Server-side computation round 2.5. Combine shared secrets to decrypt combined_hll_unrolled = [] for i in range(num_buckets): m_values = [] for j in range(sketch_size): curr_secret = Integer(1) for k in range(num_hospitals): curr_secret = (curr_secret * all_hospital_secrets[k][i][j]) % key_public.p s_inv = pow( curr_secret, key_public.p - 2, key_public.p ) # modular multiplicative inverse https://stackoverflow.com/questions/4798654/modular-multiplicative-inverse-function-in-python m = (s_inv * collapsed_enc_hll[i][j].c2) % key_public.p sqrt_m = pow(m, (key_public.p + 1) // 4, key_public.p) # taking square root if sqrt_m > key_public.p // 2: sqrt_m = key_public.p - sqrt_m m_values.append(sqrt_m) combined_hll_unrolled.append(m_values) elapsed = time.time() - start print(elapsed) answer_dict['hub_round_2.5_time'] = elapsed start = time.time() # Answer if the central server actually knew the secret key if False: exact_combined_hll_unrolled = [] for i in range(num_buckets): m_values = [] for j in range(sketch_size): sqrt_m = decrypt(key, collapsed_enc_hll[i][j]) m_values.append(sqrt_m) exact_combined_hll_unrolled.append(m_values) print("Server-side computation round 2.9. Combine HLLs: ", end="") combined_hll = [] for i in range(num_buckets): try: b = combined_hll_unrolled[i].index(1) except ValueError: b = 0 combined_hll.append(b) elapsed = time.time() - start print(elapsed) answer_dict['hub_round2.9_time'] = elapsed start = time.time() return (combined_hll_unrolled, combined_hll, answer_dict)
def enc_test_counts_given(key, counts): answer_dict = {} # Preprocessing num_hospitals = len(counts) num_patients = sum(counts) key_template = key start = time.time() print("Preprocessing time for key sharing: ", end="") hospital_private_keys = [ Integer(randint(2, int(key_template.p - 1))) for _ in range(num_hospitals) ] hospital_keys = [ construct_key(key_template, x) for x in hospital_private_keys ] elapsed = time.time() - start print(elapsed) answer_dict['hospital_round0_time'] = elapsed print("Combine to form public key: ", end="") start = time.time() key_y = Integer(1) for x in hospital_private_keys: curr_y = pow(key_template.g, x, key_template.p) key_y = (curr_y * key_y) % key_template.p key_public = ElGamal.construct((key_template.p, key_template.g, key_y)) elapsed = time.time() - start print(elapsed) answer_dict['hub_round0_time'] = elapsed start = time.time() print("Hospital-side computation round 1: encrypt counts: ", end="") # Hospital-side computation round 1 assert len(counts) == num_hospitals print(counts) encrypted_counts = [] for k, count in enumerate(counts): encrypted_count = encrypt( key_public, pow(Integer(4), Integer(count), key_public.p)) encrypted_counts.append(encrypted_count) elapsed = time.time() - start print(elapsed) answer_dict['hospital_round1_time'] = elapsed start = time.time() print("Server-side computation round 1.5: collapse encrypted counts: ", end="") # Server-side computation round 1.5 curr = encrypt(key_public, 1) for k in range(num_hospitals): curr = curr + encrypted_counts[k] encrypted_sum = curr elapsed = time.time() - start print(elapsed) answer_dict['hub_round1.5_time'] = elapsed start = time.time() print("Hospital-side computation round 2: compute shared secret parts: ", end="") # Hospital-side computation round 2. Get all shared secrets all_hospital_secrets = [] for k in range(num_hospitals): secret = shared_secret(hospital_keys[k], encrypted_sum) all_hospital_secrets.append(secret) elapsed = time.time() - start print(elapsed) answer_dict['hospital_round2_time'] = elapsed start = time.time() print( "Server-side computation round 2.5. Combine shared secrets to decrypt: ", end="") # Server-side computation round 2.5. Combine shared secrets to decrypt curr_secret = Integer(1) for k in range(num_hospitals): curr_secret = (curr_secret * all_hospital_secrets[k]) % key_public.p s_inv = pow( curr_secret, key_public.p - 2, key_public.p ) # modular multiplicative inverse https://stackoverflow.com/questions/4798654/modular-multiplicative-inverse-function-in-python m = (s_inv * encrypted_sum.c2) % key_public.p decrypted_sum = m assert (decrypted_sum == pow(Integer(4), num_patients, key_public.p)) if _dl4_table is None: print("No precomputed log table. Doing discrete log problem") logged_sum = discrete_log4(key_public, decrypted_sum) else: print("Using precomputed log table") logged_sum = _dl4_table.dlog4(decrypted_sum) elapsed = time.time() - start print(elapsed) answer_dict['hub_round2.5_time'] = elapsed print("decrypted_sum: " + str(logged_sum)) start = time.time() return (logged_sum, answer_dict)
_key_g = Integer( 24206408586964102421812765517240973131319511671044202856202992075603898484808882229676430259688543524828496724940498465738345083295910778354197713986919490726627115004690129373676590479696817812956963632330252490994726984437037113519675887167311715863923322341281192755180251058938103973809860137264177781321 ) # Public key (y) _key_y = Integer( 80096741602525354944101845054039870332476839337863539479413005037477582331123699686812254092422852136355062013980002281901835350602431500121588552286563732089960299445687681063705627334844826476798554044907030853427595347879115979412442090396606519731100408891011646324225891205357430072337588847702393772336 ) # Private key (x) _key_x = Integer( 62211585486928253378495522273311524980557226618410408675140847678303278202803964175172717266795468749770948295585597912105277041671442793825256634521813434123039348444762246359790146437221632991836988836372789033182258605363475756418157919779953874088211874519141900265542574397181153219096197383524991841700 ) # constructs elgamal key from stored constants key = ElGamal.construct((_key_p, _key_g, _key_y, _key_x)) key_public = key.publickey() def serialize_ElGamalPrivateKey(key): '''export an ElGamal Public Key to a bytestring''' padded_size = int(np.round(key.p.size_in_bits() / 8)) return key.p.to_bytes(padded_size) + key.g.to_bytes( padded_size) + key.y.to_bytes(padded_size) + key.x.to_bytes( padded_size) def deserialize_ElGamalPrivateKey(bytestring): '''constructs an ElGamal Public Key from a bytestring''' padded_size = len(bytestring) // 4
key_g = Integer( 24206408586964102421812765517240973131319511671044202856202992075603898484808882229676430259688543524828496724940498465738345083295910778354197713986919490726627115004690129373676590479696817812956963632330252490994726984437037113519675887167311715863923322341281192755180251058938103973809860137264177781321 ) # Public key (y) key_y = Integer( 80096741602525354944101845054039870332476839337863539479413005037477582331123699686812254092422852136355062013980002281901835350602431500121588552286563732089960299445687681063705627334844826476798554044907030853427595347879115979412442090396606519731100408891011646324225891205357430072337588847702393772336 ) # Private key (x) key_x = Integer( 62211585486928253378495522273311524980557226618410408675140847678303278202803964175172717266795468749770948295585597912105277041671442793825256634521813434123039348444762246359790146437221632991836988836372789033182258605363475756418157919779953874088211874519141900265542574397181153219096197383524991841700 ) # constructs elgamal key from stored constants key = ElGamal.construct((key_p, key_g, key_y, key_x)) # constructs elgamal key with different private key (implying different public key) random_secret = randint(2, int(key_p - 1)) key_x2 = random_secret key_y2 = pow(key_g, key_x2, key_p) key2 = ElGamal.construct((key_p, key_g, key_y2, key_x2)) key = key2 def encrypt(key, message): """Encrypts an integer message using the provided ElGamal key Includes a copy of key in the output (so be sure to use a public key; will assert error out otherwise)