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'])
예제 #2
0
 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_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)
예제 #5
0
 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'])
예제 #6
0
 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)
예제 #7
0
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)
예제 #10
0
    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
예제 #11
0
 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)
예제 #12
0
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)
예제 #13
0
    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
예제 #14
0
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)
예제 #17
0
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
예제 #18
0
 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 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'])
예제 #20
0
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)
예제 #21
0
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)
예제 #22
0
_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
예제 #23
0
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)