def check_input_consistency_t_values(sbb_dict, db):
    """ Check that t-values are correct for halfs that are opened. """
    for race_id in db['races']:
        # leftright maps p-list elements to 'left' or 'right'
        leftright = sbb_dict['proof:verifier_challenges']\
                    ['challenges']['leftright'][race_id] # same for all i
        race_modulus = sbb_dict['setup:races']['ballot_style_race_dict']\
                       [race_id]['race_modulus']
        # pik_dict maps race_id, k to
        #   mapping from p_list elements to p_list elts.
        # (mapping py back to px)
        pik_dict = sbb_dict['proof:input_consistency:pik_for_k_in_icl']\
                           ['pik_dict']
        for k in db['icl']:
            pik = pik_dict[race_id][k]  # {py: px}
            icom = sbb_dict['proof:input_consistency:input_openings']\
                   ['opened_commitments'][race_id]
            ocom = sbb_dict['proof:input_consistency:output_openings']\
                   ['opened_commitments'][race_id][k]
            #  icom maps p, i to {"ru":.., "u":..} or {"rv":.., "v":..}
            #  ocom maps p, i to {"ru":.., "u":..} or {"rv":.., "v":..}
            for py in db['p_list']:
                px = pik[py]
                tu_list = []
                tv_list = []
                for i in db['row_list']:
                    icompi = icom[px][i]
                    ocompi = ocom[py][i]
                    assert set(icompi.keys()) == set(ocompi.keys())
                    # t_value_dict gives {"tu":value, "tv":value}
                    t_value_dict = sbb_dict['proof:output_commitment_t_values']\
                            ['t_values'][race_id][k][px][i]
                    lr = leftright[px]        # and not py
                    assert lr == 'left' or lr == 'right'
                    if lr == 'left':
                        iuv = icompi['u']
                        ouv = ocompi['u']
                        tuv = t_value_dict['tu']
                    else:
                        iuv = icompi['v']
                        ouv = ocompi['v']
                        tuv = t_value_dict['tv']
                    assert tuv == (ouv-iuv) % race_modulus
                    tu_list.append(t_value_dict['tu'])
                    tv_list.append(t_value_dict['tv'])
                # check that tu_list and tv_list lagrange to (t, -t)
                tu_list = list(enumerate(tu_list, 1))
                tu0 = sv.lagrange(tu_list, db['rows'], db['threshold'],
                                  race_modulus)
                tv_list = list(enumerate(tv_list, 1))
                tv0 = sv.lagrange(tv_list, db['rows'], db['threshold'],
                                  race_modulus)
                assert ((tu0 + tv0) % race_modulus) == 0
    print('check_input_consistency_t_values: passed.')
Example #2
0
def check_input_consistency_t_values(sbb_dict, db):
    """ Check that t-values are correct for halfs that are opened. """
    for race_id in db['races']:
        # leftright maps p-list elements to 'left' or 'right'
        leftright = sbb_dict['proof:verifier_challenges']\
                    ['challenges']['leftright'][race_id] # same for all i
        race_modulus = sbb_dict['setup:races']['ballot_style_race_dict']\
                       [race_id]['race_modulus']
        # pik_dict maps race_id, k to
        #   mapping from p_list elements to p_list elts.
        # (mapping py back to px)
        pik_dict = sbb_dict['proof:input_consistency:pik_for_k_in_icl']\
                           ['pik_dict']
        for k in db['icl']:
            pik = pik_dict[race_id][k]  # {py: px}
            icom = sbb_dict['proof:input_consistency:input_openings']\
                   ['opened_commitments'][race_id]
            ocom = sbb_dict['proof:input_consistency:output_openings']\
                   ['opened_commitments'][race_id][k]
            #  icom maps p, i to {"ru":.., "u":..} or {"rv":.., "v":..}
            #  ocom maps p, i to {"ru":.., "u":..} or {"rv":.., "v":..}
            for py in db['p_list']:
                px = pik[py]
                tu_list = []
                tv_list = []
                for i in db['row_list']:
                    icompi = icom[px][i]
                    ocompi = ocom[py][i]
                    assert set(icompi.keys()) == set(ocompi.keys())
                    # t_value_dict gives {"tu":value, "tv":value}
                    t_value_dict = sbb_dict['proof:output_commitment_t_values']\
                            ['t_values'][race_id][k][px][i]
                    lr = leftright[px]  # and not py
                    assert lr == 'left' or lr == 'right'
                    if lr == 'left':
                        iuv = icompi['u']
                        ouv = ocompi['u']
                        tuv = t_value_dict['tu']
                    else:
                        iuv = icompi['v']
                        ouv = ocompi['v']
                        tuv = t_value_dict['tv']
                    assert tuv == (ouv - iuv) % race_modulus
                    tu_list.append(t_value_dict['tu'])
                    tv_list.append(t_value_dict['tv'])
                # check that tu_list and tv_list lagrange to (t, -t)
                tu_list = list(enumerate(tu_list, 1))
                tu0 = sv.lagrange(tu_list, db['rows'], db['threshold'],
                                  race_modulus)
                tv_list = list(enumerate(tv_list, 1))
                tv0 = sv.lagrange(tv_list, db['rows'], db['threshold'],
                                  race_modulus)
                assert ((tu0 + tv0) % race_modulus) == 0
    print('check_input_consistency_t_values: passed.')
Example #3
0
def check_opened_output_commitment_tallies(sbb_dict, db):
    """ Check that for each k, the opened output commitments lagranage
        and tally to values given in tally.
    """
    opened_coms = \
        sbb_dict['proof:outcome_check']\
                ['opened_output_commitments']
    for k in db['opl']:
        # verify tally for this pass/copy k
        tally_k = dict()
        for race_id in db['race_ids']:
            tally_k[race_id] = dict()  # choices to counts
            for choice in sbb_dict['setup:races']\
                ['ballot_style_race_dict'][race_id]['choices']:
                if choice[0] != '*':
                    tally_k[race_id][choice] = 0
            for p in db['p_list']:
                share_list = []
                for i_int, i in enumerate(db['row_list']):
                    y = opened_coms[race_id][k][p][i]['y']
                    share_list.append((i_int + 1, y))
                w = sv.lagrange(share_list, db['rows'], db['threshold'],
                                db['races'][race_id]['race_modulus'])
                # convert w back to string version of choice
                # see sv_race.choice_int2str
                choice_bytes = sv.int2bytes(w)
                choice_str = choice_bytes.decode()
                # assert self.is_valid_choice(choice_str)
                # print(race_id, k, iy, choice_str)
                cnt = tally_k[race_id].get(choice_str, 0)
                tally_k[race_id][choice_str] = cnt + 1
        assert tally_k == db['tally']
    print('check_opened_output_commitment_tallies: passed.')
def check_opened_output_commitment_tallies(sbb_dict, db):
    """ Check that for each k, the opened output commitments lagranage
        and tally to values given in tally.
    """
    opened_coms = \
        sbb_dict['proof:outcome_check']\
                ['opened_output_commitments']
    for k in db['opl']:
        # verify tally for this pass/copy k
        tally_k = dict()
        for race_id in db['race_ids']:
            tally_k[race_id] = dict()  # choices to counts
            for choice in sbb_dict['setup:races']\
                ['ballot_style_race_dict'][race_id]['choices']:
                if choice[0] != '*':
                    tally_k[race_id][choice] = 0
            for p in db['p_list']:
                share_list = []
                for i_int, i in enumerate(db['row_list']):
                    y = opened_coms[race_id][k][p][i]['y']
                    share_list.append((i_int+1, y))
                w = sv.lagrange(share_list,
                                db['rows'],
                                db['threshold'],
                                db['races'][race_id]['race_modulus'])
                # convert w back to string version of choice
                # see sv_race.choice_int2str
                choice_bytes = sv.int2bytes(w)
                choice_str = choice_bytes.decode()
                # assert self.is_valid_choice(choice_str)
                # print(race_id, k, iy, choice_str)
                cnt = tally_k[race_id].get(choice_str, 0)
                tally_k[race_id][choice_str] = cnt + 1
        assert tally_k == db['tally']
    print('check_opened_output_commitment_tallies: passed.')
def compute_tally(election):
    """ Compute tallies for this election.

    Data is from last column of mix servers.
    """
    server = election.server
    cols = server.cols
    election.tally = dict()
    for race in election.races:
        race_id = race.race_id
        for k in election.k_list:  # TODO this should be output production list
            choice_int_list = []
            for p in election.p_list:
                share_list = \
                    [(row+1, server.sdb[race_id][i][cols-1][k]['y'][p]) \
                     for row, i in enumerate(election.server.row_list)]
                choice_int = sv.lagrange(share_list, server.rows,\
                                         server.threshold, race.race_modulus)
                choice_int_list.append(choice_int)
            choice_str_list = [
                race.choice_int2str(choice_int)
                for choice_int in choice_int_list
            ]
            choice_str_list = sorted(choice_str_list)
            if k == election.k_list[
                    0]:  # TODO this should be output production list
                last_choice_str_list = choice_str_list
            else:
                assert choice_str_list == last_choice_str_list
        # now compute tally for this race
        tally = dict()
        for choice_str in race.choices:
            if not all([c == '*' for c in choice_str]):
                tally[choice_str] = 0
        for choice_str in choice_str_list:
            tally[choice_str] = tally.get(choice_str, 0) + 1
        # save it
        race.tally = tally
        election.tally[race_id] = tally
    return ("tally:results", {
        "election_id": election.election_id,
        "tally": election.tally
    })
 def test_mix(self):
     """ Test that mixing is giving reasonable results. """
     election = self.election
     rows = self.rows
     cols = self.cols
     for race in election.races:
         race_id = race.race_id
         print("Race: ", race_id)
         for k in election.k_list:
             choice_int_list = []
             for v in range(election.n_voters):
                 share_list = \
                     [(i+1, self.sdb[race_id][i][cols-1][k]['y'][v]) \
                      for i in range(rows)]
                 choice_int = sv.lagrange(share_list, election.n_voters, \
                                          self.threshold, race.M)
                 choice_int_list.append(choice_int)
             # print("Copy:", k, choice_int_list)
             choice_str_list = [race.choice_int2str(choice_int) \
                                for choice_int in choice_int_list]
             print("Copy:", k, choice_str_list)
 def test_mix(self):
     """ Test that mixing is giving reasonable results. """
     election = self.election
     rows = self.rows
     cols = self.cols
     for race in election.races:
         race_id = race.race_id
         print("Race: ", race_id)
         for k in election.k_list:
             choice_int_list = []
             for v in range(election.n_voters):
                 share_list = \
                     [(i+1, self.sdb[race_id][i][cols-1][k]['y'][v]) \
                      for i in range(rows)]
                 choice_int = sv.lagrange(share_list, election.n_voters, \
                                          self.threshold, race.M)
                 choice_int_list.append(choice_int)
             # print("Copy:", k, choice_int_list)
             choice_str_list = [race.choice_int2str(choice_int) \
                                for choice_int in choice_int_list]
             print("Copy:", k, choice_str_list)
Example #8
0
def compute_tally(election):
    """ Compute tallies for this election.

    Data is from last column of mix servers.
    """
    server = election.server
    cols = server.cols
    election.tally = dict()
    for race in election.races:
        race_id = race.race_id
        for k in election.k_list:
            choice_int_list = []
            for p in election.p_list:
                share_list = \
                    [(row+1, server.sdb[race_id][i][cols-1][k]['y'][p]) \
                     for row, i in enumerate(election.server.row_list)]
                choice_int = sv.lagrange(share_list, server.rows,\
                                         server.threshold, race.race_modulus)
                choice_int_list.append(choice_int)
            choice_str_list = [race.choice_int2str(choice_int)
                               for choice_int in choice_int_list]
            choice_str_list = sorted(choice_str_list)
            if k == election.k_list[0]:
                last_choice_str_list = choice_str_list
            else:
                assert choice_str_list == last_choice_str_list
        # now compute tally for this race
        tally = dict()
        for choice_str in race.choices:
            if not all([c == '*' for c in choice_str]):
                tally[choice_str] = 0
        for choice_str in choice_str_list:
            tally[choice_str] = tally.get(choice_str, 0) + 1
        # save it
        race.tally = tally
        election.tally[race_id] = tally
Example #9
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}