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.')
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.')
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 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
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}