""" Load up just election params Scantegrity audit Ben Adida 2009-10-31 """ import base, data, filenames partition_xml = base.file_in_dir(base.DATA_PATH, filenames.PARTITIONS, 'Partition File') election_xml = base.file_in_dir(base.DATA_PATH, filenames.ELECTION_SPEC, 'Election Spec') meeting_one_in_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_ONE_IN, 'Meeting One In') # parse partition_info = data.PartitionInfo() partition_info.parse(partition_xml) election_spec = data.ElectionSpec(partition_info) election_spec.parse(election_xml) election = data.Election(election_spec) election.parse(meeting_one_in_xml)
CODES_FILE_PATH is the path to a file which, when provided, will be where this script writes its list of confirmation codes for each ballot. """ # core imports import sys import base, data, filenames # use the meeting1 and meeting2 data structures too import meeting1, meeting2 election, committed_p_table = meeting1.election, meeting1.p_table # third meeting meeting_three_in_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_THREE_IN, 'Meeting Three In') meeting_three_out_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_THREE_OUT, 'Meeting Three Out') meeting_three_out_codes_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_THREE_OUT_CODES, 'Meeting Three Out Codes') # parse the ballot confirmation code commitments ballots = data.parse_ballot_table(meeting2.meeting_two_out_commitments_xml) # get the P table of actual votes p_table_votes = data.PTable() p_table_votes.parse(meeting_three_in_xml.find('print')) # get the opening of the ballot confirmation code commitments ballots_with_codes = data.parse_ballot_table(meeting_three_out_codes_xml) def verify(output_stream, codes_output_stream=None): # make sure none of the actual votes use ballots that were audited in Meeting2:
import tallydata # correcting the argv base.DATA_PATH QUESTION_ID = sys.argv[1] DATA_PATHS = sys.argv[2:] # for default election params base.DATA_PATH = DATA_PATHS[0] # use the meeting1 data structures from electionparams import * # import just the R tables # there could be a few given the multiple data_paths r_tables_xml = [base.file_in_dir(data_path, filenames.MEETING_THREE_OUT, 'Meeting Three Out') for data_path in DATA_PATHS] r_tables_list = [data.parse_r_tables(r_tables) for r_tables in r_tables_xml] # print "ok now tallying\n\n" # the list of partitions, each of which is a list of the max number of answers each question allows partition_map = election.partition_map_choices # we only tally per question now, so BALLOTS is just an array BALLOTS = [] # go through each partition for r_tables in r_tables_list: for p_id, r_table in r_tables.iteritems(): for row_id, row in r_table.rows.iteritems(): # split the result among questions for this partition, according to partition map
CODES_FILE_PATH is the path to a file which, when provided, will be where this script writes its list of confirmation codes for each ballot. """ # core imports import sys import base, data, filenames # based on meeting2, and meeting3 for the ballots import meeting1, meeting2, meeting3 election = meeting1.election ballots, cast_ballots = meeting3.ballots, meeting3.ballots_with_codes # spoiled ballots codes spoiled_ballots_codes_xml = base.file_in_dir(base.DATA_PATH, filenames.SPOILED_BALLOTS_CODES, 'Spoiled Ballots Codes') spoiled_ballots = data.parse_ballot_table(spoiled_ballots_codes_xml) # spoiled ballots mixnet spoiled_ballots_mixnet_xml = base.file_in_dir(base.DATA_PATH, filenames.SPOILED_BALLOTS_MIXNET, 'Spoiled Ballots Mixnet') spoiled_p_table, spoiled_partitions = data.parse_database(spoiled_ballots_mixnet_xml) def verify(output_stream, codes_output_stream=None): if codes_output_stream: BALLOTS = {} def new_code(webSerial, pid, q_id, s_id, confirmation_code): if not BALLOTS.has_key(webSerial): BALLOTS[webSerial] = {'pid': pid, 'questions': {}} if not BALLOTS[webSerial]['questions'].has_key(q_id):
data path should NOT have a trailing slash """ # core imports import sys, base64 import base, data, filenames # use the meeting1 data structures too import meeting1 # pull in certain data structures from meeting1 election, p_table, partitions = meeting1.election, meeting1.p_table, meeting1.partitions # second meeting meeting_two_in_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_TWO_IN, 'Meeting Two In') meeting_two_out_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_TWO_OUT, "Meeting Two Out") meeting_two_out_commitments_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_TWO_OUT_COMMITMENTS, "Meeting Two Out Commitments") meeting_two_random_data = base.file_in_dir(base.DATA_PATH, filenames.MEETING_TWO_RANDOM_DATA, "Random Data for Meeting Two Challenges", xml=False, correct_windows=True) # get the challenges challenge_p_table = data.PTable() challenge_p_table.parse(meeting_two_in_xml.find('challenges/print')) # get the response response_p_table, response_partitions = data.parse_database(meeting_two_out_xml) challenge_row_ids = challenge_p_table.rows.keys() def verify_open_p_and_d_tables(election, committed_p_table, committed_partitions, open_p_table, open_partitions): # check P table commitments
""" # core imports import sys import base import data import filenames # use the meeting1,2,3 data structures too import meeting1, meeting2 # use provisional ballots as well import meeting3provisional as meeting3 # fourth meeting meeting_four_in_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_FOUR_IN, 'Meeting Four In') meeting_four_out_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_FOUR_OUT, 'Meeting Four Out') meeting_four_random_data = base.file_in_dir(base.DATA_PATH, filenames.MEETING_FOUR_RANDOM_DATA, "Random Data for Meeting Four Challenges", xml=False, correct_windows=False) # from meeting1 and meeting 2 election, d_table_commitments, already_open_d_tables = meeting1.election, meeting1.partitions, meeting2.response_partitions p_table_votes = meeting3.p_table_votes # from meeting3, the D tables with intermediate decrypted votes cast_ballot_partitions = data.parse_d_tables(meeting3.meeting_three_out_xml) # challenge and response to those rows d_table_challenges = data.parse_d_tables(meeting_four_in_xml) d_table_responses = data.parse_d_tables(meeting_four_out_xml) # r tables
The meeting one verification Usage: python meeting-one.py <DATA_PATH> data path should NOT have a trailing slash """ import sys import base, data, filenames # base election params from electionparams import * # get the election data meeting_one_out_xml = base.file_in_dir(base.DATA_PATH, filenames.MEETING_ONE_OUT, "Meeting One Out") # get the p table and d tables p_table, partitions = data.parse_database(meeting_one_out_xml) # are we actually running meeting 1? def verify(output_stream): # check that there are as many ballots in the P table as claimed assert len(p_table.rows) == election.num_ballots, "P Table has the wrong number of ballots, should be %s " % election.num_ballots num_d_tables = None # loop through partitions for p_id, partition in partitions.iteritems(): this_num_d_tables = len(partition.values())
# based on meeting2, and meeting3 for the ballots which aren't needed for parsing until then, nothing in meeting4 needed import meeting1, meeting2 # use provisional ballots try: import meeting3provisional as meeting3 except: filenames.reset() import meeting3 election = meeting1.election ballots, cast_ballots = meeting3.ballots, meeting3.ballots_with_codes # contested ballots reveal contested_ballots_reply_xml = base.file_in_dir(base.DATA_PATH, filenames.CONTESTED_BALLOTS_REPLY, 'Reply to Contested Ballots') contested_ballots = data.parse_ballot_table(contested_ballots_reply_xml) def verify(output_stream, codes_output_stream=None): if codes_output_stream: codes_output_stream.write('Serial #,P-table ID') for q_id in sorted(contested_ballots.values()[0].questions.keys()): codes_output_stream.write(",question %s"%q_id) codes_output_stream.write("\n") # for each contested ballot: for contested_ballot in contested_ballots.values(): # is it a cast ballot? assert cast_ballots.has_key(contested_ballot.pid)
CODES_FILE_PATH is the path to a file which, when provided, will be where this script writes its list of confirmation codes for each ballot. """ # core imports import sys import base, data, filenames # based on meeting2, and meeting3 for the ballots import meeting1, meeting2, meeting3 election = meeting1.election ballots, cast_ballots = meeting3.ballots, meeting3.ballots_with_codes # unused ballots codes unused_ballots_codes_xml = base.file_in_dir(base.DATA_PATH, filenames.UNUSED_BALLOTS_CODES, 'Unused Ballots Codes') unused_ballots = data.parse_ballot_table(unused_ballots_codes_xml) # unused ballots mixnet unused_ballots_mixnet_xml = base.file_in_dir(base.DATA_PATH, filenames.UNUSED_BALLOTS_MIXNET, 'Unused Ballots Mixnet') unused_p_table, unused_partitions = data.parse_database(unused_ballots_mixnet_xml) def verify(output_stream, codes_output_stream=None): if codes_output_stream: BALLOTS = {} def new_code(webSerial, pid, q_id, s_id, confirmation_code): if not BALLOTS.has_key(webSerial): BALLOTS[webSerial] = {'pid': pid, 'questions': {}} if not BALLOTS[webSerial]['questions'].has_key(q_id):