def compute_output_commitments(election): """ Make commitments to all output values and save them in sdbp. For each race, for each of n_reps copies (indexed by k), for each row (indexed by i) for each of the n vote shares (call them y) compute two commitments (cu and cv) to split-value rep (u,v) of y. using randomization values ru and rv. """ cols = election.server.cols full_output = dict() for race in election.races: race_modulus = race.race_modulus race_id = race.race_id full_output[race_id] = dict() for k in election.k_list: full_output[race_id][k] = dict() for py in election.p_list: full_output[race_id][k][py] = dict() for i in election.server.row_list: rand_name = \ election.server.sdb[race_id][i][cols-1]['rand_name'] sdbp = election.server.sdb[race_id][i][cols - 1][k] y = sdbp['y'][py] (u, v) = sv.get_sv_pair(y, 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) sdbp['u'][py] = u sdbp['v'][py] = v sdbp['ru'][py] = ru sdbp['rv'][py] = rv sdbp['cu'][py] = cu sdbp['cv'][py] = cv ballot = { 'y': y, 'u': u, 'v': v, 'ru': ru, 'rv': rv, 'cu': cu, 'cv': cv } full_output[race_id][k][py][i] = ballot election.full_output = full_output
def compute_output_commitments(election): """ Make commitments to all output values and save them in sdbp. For each race, for each of n_reps copies (indexed by k), for each row (indexed by i) for each of the n vote shares (call them y) compute two commitments (cu and cv) to split-value rep (u,v) of y. using randomization values ru and rv. """ cols = election.server.cols full_output = dict() for race in election.races: race_modulus = race.race_modulus race_id = race.race_id full_output[race_id] = dict() for k in election.k_list: full_output[race_id][k] = dict() for py in election.p_list: full_output[race_id][k][py] = dict() for i in election.server.row_list: rand_name = \ election.server.sdb[race_id][i][cols-1]['rand_name'] sdbp = election.server.sdb[race_id][i][cols-1][k] y = sdbp['y'][py] (u, v) = sv.get_sv_pair(y, 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) sdbp['u'][py] = u sdbp['v'][py] = v sdbp['ru'][py] = ru sdbp['rv'][py] = rv sdbp['cu'][py] = cu sdbp['cv'][py] = cv ballot = {'y': y, 'u': u, 'v': v, 'ru': ru, 'rv': rv, 'cu': cu, 'cv': cv} full_output[race_id][k][py][i] = ballot election.full_output = full_output
def check_receipts(sbb_dict, db): """ Check that receipts are consistent with cast vote commitments. """ receipt_ballot_ids = set(db['receipts'].keys()) cast_vote_dict = sbb_dict['casting:votes']['cast_vote_dict'] for race_id in cast_vote_dict: for p in cast_vote_dict[race_id]: d = dict() for i in cast_vote_dict[race_id][p]: ballot_id = cast_vote_dict[race_id][p][i]['ballot_id'] cu = cast_vote_dict[race_id][p][i]['cu'] cv = cast_vote_dict[race_id][p][i]['cv'] d[i] = {'cu': cu, 'cv': cv} cv_receipt_data = [ballot_id, d] cv_receipt_data_str = sv.dumps(cv_receipt_data) cv_hash = sv.bytes2base64(sv.secure_hash(cv_receipt_data_str)) assert cv_hash == db['receipts'][ballot_id]['hash'] receipt_ballot_ids.remove(ballot_id) assert len(receipt_ballot_ids) == 0 print("check_receipts: passed.")
def compute_output_commitments(election, row_index, col_index): """ Make commitments to all output values and save them in sdbp. For each race, for each of n_reps copies (indexed by k), for each row (indexed by i) for each of the n vote shares (call them y) compute two commitments (cu and cv) to split-value rep (u,v) of y. using randomization values ru and rv. """ cols = election.server.cols full_output = dict() for race in election.races: race_modulus = race.race_modulus race_id = race.race_id full_output[race_id] = dict() for k in election.k_list: full_output[race_id][k] = dict() for py in election.p_list: full_output[race_id][k][py] = dict() if col_index == cols - 1: # TODO move this logic to ServerMix handler i = row_index rand_name = \ election.server.sdb[race_id][i][cols-1]['rand_name'] sv.init_randomness_source( rand_name) # TODO optional remove later sdbp = election.server.sdb[race_id][i][cols - 1][k] y = sdbp['y'][py] (u, v) = sv.get_sv_pair(y, 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) sdbp['u'][py] = u sdbp['v'][py] = v sdbp['ru'][py] = ru sdbp['rv'][py] = rv sdbp['cu'][py] = cu sdbp['cv'][py] = cv ballot = { 'y': y, 'u': u, 'v': v, 'ru': ru, 'rv': rv, 'cu': cu, 'cv': cv } full_output[race_id][k][py][i] = ballot election.full_output = full_output coms = dict() # same as full_output, but only giving non-secret values (i.e. cu, cv) for race in election.races: race_id = race.race_id coms[race_id] = dict() for k in election.k_list: coms[race_id][k] = dict() for py in election.p_list: coms[race_id][k][py] = dict() '''for i in election.server.row_list: # TODO remove this for loop -> shared memory coms[race_id][k][py][i] = \ {'cu': full_output[race_id][k][py][i]['cu'], 'cv': full_output[race_id][k][py][i]['cv']}''' coms[race_id][k][py] = dict() if col_index == cols - 1: # TODO move this logic to ServerMix handler i = row_index coms[race_id][k][py][i] = \ {'cu': full_output[race_id][k][py][i]['cu'], 'cv': full_output[race_id][k][py][i]['cv']} election.output_commitments = coms return ("proof:output_commitments", {"commitments": coms})
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}