예제 #1
0
 def mix_phase_generate_obfuscation_values(self, row_index, col_index):
     assert row_index == 'a'
     election = self.election
     # generate obfuscation values used in each column
     # in practice, these could be generated by row 0 server
     # and sent securely to the others in the same column.
     for race in election.races:
         race_id = race.race_id
         j = col_index
         rand_name = self.sdb[race_id]['a'][j]['rand_name']
         for k in election.k_list:
             fuzz_dict = dict()      # fuzz_dict[i][pnn]
             for i in self.row_list:
                 fuzz_dict[i] = dict()
             for v in election.p_list:
                 share_list = sv.share(0,
                                       self.rows,
                                       self.threshold,
                                       rand_name,
                                       race.race_modulus)
                 for row, i in enumerate(self.row_list):
                     fuzz_dict[i][v] = share_list[row][1]
             for i in self.row_list:
                 # note that fuzz_dict[i] is dict of size n
                 self.sdb[race_id][i][j][k]['fuzz_dict'] = fuzz_dict[i]
     dict_update_to_share = dict()
     for race_id in election.race_ids:
         dict_update_to_share[race_id] = dict()
         for i in self.row_list:
             dict_update_to_share[race_id][i] = dict()
             j = col_index
             assert type(j)==int
             dict_update_to_share[race_id][i][j] = dict()
             for k in election.k_list:
                 dict_update_to_share[race_id][i][j][k] = dict()
                 dict_update_to_share[race_id][i][j][k]['fuzz_dict'] = self.sdb[race_id][i][j][k]['fuzz_dict']
     return dict_update_to_share
예제 #2
0
    def cast_vote(self, race):
        """ Cast random vote for this voter for this race in simulated election.

        Of course, in a real election, choices come from voter via tablet.
        """

        election = self.election
        cvs = election.cast_votes
        race_id = race.race_id
        race_modulus = race.race_modulus
        rand_name = self.rand_name
        px = self.px

        # cast random vote (for this simulation, it's random)
        choice_str = race.random_choice()  # returns a string
        choice_int = race.choice_str2int(choice_str)  # convert to integer

        # ballot_id is random hex string of desired length
        ballot_id_len = election.ballot_id_len
        ballot_id = sv.bytes2hex(sv.get_random_from_source(rand_name))
        ballot_id = ballot_id[:ballot_id_len]
        assert len(ballot_id) == election.ballot_id_len

        # secret-share choice
        n = election.server.rows
        t = election.server.threshold
        share_list = sv.share(choice_int, n, t, rand_name, race_modulus)

        # double-check that shares reconstruct to desired choice
        assert choice_int == sv.lagrange(share_list, n, t, race_modulus)
        # double-check that shares are have indices 1, 2, ..., n
        assert all([share_list[i][0] == i + 1 for i in range(n)])
        # then strip off indices, since they are equal to row number + 1
        share_list = [share[1] for share in share_list]

        # save ballots on election data structure
        for row, x in enumerate(share_list):
            (u, v) = sv.get_sv_pair(x, rand_name, race_modulus)
            ru = sv.bytes2base64(sv.get_random_from_source(rand_name))
            rv = sv.bytes2base64(sv.get_random_from_source(rand_name))
            cu = sv.com(u, ru)
            cv = sv.com(v, rv)
            i = election.server.row_list[row]
            vote = {
                "ballot_id": ballot_id,
                "x": x,
                "u": u,
                "v": v,
                "ru": ru,
                "rv": rv,
                "cu": cu,
                "cv": cv
            }
            cvs[race_id][px][i] = vote

        # compute voter receipt as hash of her ballot_id and commitments
        # note that voter gets a receipt for each race she votes in
        receipt_data = [ballot_id]
        d = dict()
        for i in election.server.row_list:
            cu = cvs[race_id][px][i]['cu']
            cv = cvs[race_id][px][i]['cv']
            d[i] = {'cu': cu, 'cv': cv}
        receipt_data.append(d)
        receipt_data_str = sv.dumps(receipt_data)
        receipt_hash = sv.bytes2base64(sv.secure_hash(receipt_data_str))
        self.receipts[ballot_id] = {'race_id': race_id, 'hash': receipt_hash}
예제 #3
0
 def mix(self):
     """ Mix votes.  Information flows left to right. """
     election = self.election
     # replicate input to become first-column x inputs for each race & pass
     for race_id in election.race_ids:
         for k in election.k_list:
             for i in self.row_list:
                 x = self.sdb[race_id][i][0]['x']   # dict of n x's
                 self.sdb[race_id][i][0][k]['x'] = x.copy()
     # generate permutations (and inverses) used in each column
     # in practice, these could be generated by row 0 server
     # and sent securely to the others in the same column.
     for race_id in election.race_ids:
         for j in range(self.cols):
             rand_name = self.sdb[race_id]['a'][j]['rand_name']
             for k in election.k_list:
                 pi = sv.random_permutation(election.p_list, rand_name)
                 pi_inv = sv.inverse_permutation(pi)
                 for i in self.row_list:
                     self.sdb[race_id][i][j][k]['pi'] = pi
                     self.sdb[race_id][i][j][k]['pi_inv'] = pi_inv
     # generate obfuscation values used in each column
     # in practice, these could be generated by row 0 server
     # and sent securely to the others in the same column.
     for race in election.races:
         race_id = race.race_id
         for j in range(self.cols):
             rand_name = self.sdb[race_id]['a'][j]['rand_name']
             for k in election.k_list:
                 fuzz_dict = dict()      # fuzz_dict[i][pnn]
                 for i in self.row_list:
                     fuzz_dict[i] = dict()
                 for v in election.p_list:
                     share_list = sv.share(0,
                                           self.rows,
                                           self.threshold,
                                           rand_name,
                                           race.race_modulus)
                     for row, i in enumerate(self.row_list):
                         fuzz_dict[i][v] = share_list[row][1]
                 for i in self.row_list:
                     # note that fuzz_dict[i] is dict of size n
                     self.sdb[race_id][i][j][k]['fuzz_dict'] = fuzz_dict[i]
     # process columns left-to-right, mixing as you go
     for race in self.election.races:
         race_id = race.race_id
         race_modulus = race.race_modulus
         for j in range(self.cols):
             for k in election.k_list:
                 for i in self.row_list:
                     # shuffle first
                     pi = self.sdb[race_id][i][j][k]['pi'] # length n
                     # note that pi is independent of i
                     x = self.sdb[race_id][i][j][k]['x']   # length n
                     xp = sv.apply_permutation(pi, x)      # length n
                     # then obfuscate by adding "fuzz"
                     fuzz_dict = self.sdb[race_id][i][j][k]['fuzz_dict']
                     xpo = dict()
                     for v in election.p_list:
                         xpo[v] = (xp[v] + fuzz_dict[v]) % race_modulus
                     y = xpo
                     self.sdb[race_id][i][j][k]['y'] = y
                     # this column's y's become next column's x's.
                     # in practice would be sent via secure channels
                     if j < self.cols - 1:
                         self.sdb[race_id][i][j+1][k]['x'] = y
예제 #4
0
 def mix(self):
     """ Mix votes.  Information flows left to right. """
     election = self.election
     # replicate input to become first-column x inputs for each race & pass
     for race_id in election.race_ids:
         for k in election.k_list:
             for i in self.row_list:
                 x = self.sdb[race_id][i][0]['x']  # dict of n x's
                 self.sdb[race_id][i][0][k]['x'] = x.copy()
     # generate permutations (and inverses) used in each column
     # in practice, these could be generated by row 0 server
     # and sent securely to the others in the same column.
     for race_id in election.race_ids:
         for j in range(self.cols):
             rand_name = self.sdb[race_id]['a'][j]['rand_name']
             for k in election.k_list:
                 pi = sv.random_permutation(election.p_list, rand_name)
                 pi_inv = sv.inverse_permutation(pi)
                 for i in self.row_list:
                     self.sdb[race_id][i][j][k]['pi'] = pi
                     self.sdb[race_id][i][j][k]['pi_inv'] = pi_inv
     # generate obfuscation values used in each column
     # in practice, these could be generated by row 0 server
     # and sent securely to the others in the same column.
     for race in election.races:
         race_id = race.race_id
         for j in range(self.cols):
             rand_name = self.sdb[race_id]['a'][j]['rand_name']
             for k in election.k_list:
                 fuzz_dict = dict()  # fuzz_dict[i][pnn]
                 for i in self.row_list:
                     fuzz_dict[i] = dict()
                 for v in election.p_list:
                     share_list = sv.share(0, self.rows, self.threshold,
                                           rand_name, race.race_modulus)
                     for row, i in enumerate(self.row_list):
                         fuzz_dict[i][v] = share_list[row][1]
                 for i in self.row_list:
                     # note that fuzz_dict[i] is dict of size n
                     self.sdb[race_id][i][j][k]['fuzz_dict'] = fuzz_dict[i]
     # process columns left-to-right, mixing as you go
     for race in self.election.races:
         race_id = race.race_id
         race_modulus = race.race_modulus
         for j in range(self.cols):
             for k in election.k_list:
                 for i in self.row_list:
                     # shuffle first
                     pi = self.sdb[race_id][i][j][k]['pi']  # length n
                     # note that pi is independent of i
                     x = self.sdb[race_id][i][j][k]['x']  # length n
                     xp = sv.apply_permutation(pi, x)  # length n
                     # then obfuscate by adding "fuzz"
                     fuzz_dict = self.sdb[race_id][i][j][k]['fuzz_dict']
                     xpo = dict()
                     for v in election.p_list:
                         xpo[v] = (xp[v] + fuzz_dict[v]) % race_modulus
                     y = xpo
                     self.sdb[race_id][i][j][k]['y'] = y
                     # this column's y's become next column's x's.
                     # in practice would be sent via secure channels
                     if j < self.cols - 1:
                         self.sdb[race_id][i][j + 1][k]['x'] = y