Ejemplo n.º 1
0
 def setUp(self):
     self.tp = ThresholdParameters(3, 5)
     self.cp = CurveParameters()
     self.pk, self.shares = central.create_public_key_and_shares_centralized(self.cp, self.tp)
     self.message = 'Some secret message'
     self.em = central.encrypt_message(self.message, self.pk)
     self.reconstruct_shares = [self.shares[i] for i in [0, 2, 4]]  # choose 3 of 5 key shares
     self.partial_decryptions = [participant.compute_partial_decryption(self.em, share) for share in self.reconstruct_shares]
Ejemplo n.º 2
0
    def parameterizable_re_encryption_process_test(self, new_t: int, new_n: int):
        new_tp = ThresholdParameters(new_t, new_n)
        new_pk, new_shares = central.create_public_key_and_shares_centralized(self.cp, new_tp)

        assert new_pk != self.pk, "Public keys for new and old access structure are the same"

        # Without loss of generality we assume the lists to be ordered in a way, that remaining participants
        # are placed at the beginning of the list.
        # Choose t_max shares randomly from first min_n old and new shares as the shares of one distinct participant.
        max_t = max(self.tp.t, new_tp.t)
        min_n = min(self.tp.n, new_tp.n)
        t_old_shares = random.sample(self.shares[:min_n], k=max_t)
        t_old_shares_x = [share.x for share in t_old_shares]
        t_new_shares = random.sample(new_shares[:min_n], k=max_t)
        t_new_shares_x = [share.x for share in t_new_shares]

        partial_re_encrypt_keys = []
        for i, (s_old, s_new) in enumerate(zip(t_old_shares, t_new_shares)):
            old_lambda = central.lagrange_coefficient_for_key_share_indices(t_old_shares_x, t_old_shares_x[i], self.cp)
            new_lambda = central.lagrange_coefficient_for_key_share_indices(t_new_shares_x, t_new_shares_x[i], self.cp)
            partial_key = participant.compute_partial_re_encryption_key(s_old, old_lambda, s_new, new_lambda)
            partial_re_encrypt_keys.append(partial_key)

        re_encrypt_key = central.combine_partial_re_encryption_keys(partial_re_encrypt_keys,
                                                                    self.pk,
                                                                    new_pk,
                                                                    self.tp,
                                                                    new_tp)
        re_em = central.re_encrypt_message(self.em, re_encrypt_key)

        self.assertNotEqual(self.em, re_em)

        # successful decryption with t shares
        new_reconstruct_shares = random.sample(new_shares, new_tp.t)
        new_partial_decryptions = [participant.compute_partial_decryption(re_em, share) for share in new_reconstruct_shares]

        decrypted_message = central.decrypt_message(new_partial_decryptions, re_em, new_tp)
        self.assertEqual(self.message, decrypted_message)

        # failing decryption with t - 1 shares
        with self.assertRaises(ThresholdCryptoError) as dec_exception_context:
            less_reconstruct_shares = random.sample(new_shares, new_tp.t - 1)
            new_partial_decryptions = [participant.compute_partial_decryption(re_em, share) for share in less_reconstruct_shares]
            central._decrypt_message(new_partial_decryptions, re_em)

        self.assertIn("Message decryption failed", str(dec_exception_context.exception))
Ejemplo n.º 3
0
    def test_key_encryption_decryption_without_enough_shares(self):
        r = number.random_in_range(2, self.cp.order)
        testkey_element = r * self.cp.P
        kP, c = central._encrypt_key_point(testkey_element, self.pk.Q, self.cp)
        em = EncryptedMessage(kP, c, b'')
        reconstruct_shares = [self.shares[i] for i in [0, 4]]  # choose 2 of 5 key shares
        partial_decryptions = [participant.compute_partial_decryption(em, share) for share in reconstruct_shares]
        rec_testkey_element = central._combine_shares(partial_decryptions, em, self.cp)

        self.assertNotEqual(testkey_element, rec_testkey_element)
Ejemplo n.º 4
0
    def test_complete_process_without_enough_shares(self):
        curve_params = CurveParameters()
        thresh_params = ThresholdParameters(3, 5)

        pub_key, key_shares = central.create_public_key_and_shares_centralized(curve_params, thresh_params)

        message = 'Some secret message to be encrypted!'
        encrypted_message = central.encrypt_message(message, pub_key)

        reconstruct_shares = [key_shares[i] for i in [3, 4]]  # choose 2 of 5 key shares
        partial_decryptions = [participant.compute_partial_decryption(encrypted_message, share) for share in reconstruct_shares]

        with self.assertRaises(ThresholdCryptoError):
            central.decrypt_message(partial_decryptions, encrypted_message, thresh_params)
Ejemplo n.º 5
0
    def test_distributed_key_generation(self):
        participant_ids = list(range(1, self.tp.n + 1))
        participants = [participant.Participant(id, participant_ids, self.cp, self.tp) for id in participant_ids]

        # via broadcast
        for pi in participants:
            for pj in participants:
                if pj != pi:
                    closed_commitment = pj.closed_commmitment()
                    pi.receive_closed_commitment(closed_commitment)

        # via broadcast
        for pi in participants:
            for pj in participants:
                if pj != pi:
                    open_commitment = pj.open_commitment()
                    pi.receive_open_commitment(open_commitment)

        public_key = participants[0].compute_public_key()
        for pk in [p.compute_public_key() for p in participants[1:]]:
            self.assertEqual(public_key, pk)

        # via broadcast
        for pi in participants:
            for pj in participants:
                if pj != pi:
                    F_ij = pj.F_ij_value()
                    pi.receive_F_ij_value(F_ij)

        # SECRETLY from i to j
        for pi in participants:
            for pj in participants:
                if pj != pi:
                    s_ij = pj.s_ij_value_for_participant(pi.id)
                    pi.receive_sij(s_ij)

        shares = [p.compute_share() for p in participants]

        # test encryption/decryption

        em = central.encrypt_message(self.message, public_key)

        pdms = [participant.compute_partial_decryption(em, ks) for ks in shares[:self.tp.t]]
        dm = central.decrypt_message(pdms, em, self.tp)

        self.assertEqual(dm, self.message)