def get_constants(self) -> dict: """ get all constants as a dictionary :return: a dictionary of constants info """ constants_path = self.path_g.get_constants_file_path() return read_json_file(constants_path)
def get_description(self) -> dict: """ get the election description information as dictionary :return: a dictionary representation of the description.json """ file_path = self.path_g.get_description_file_path() return read_json_file(file_path)
def get_context(self) -> dict: """ get all context information as a dictionary :return: a dictionary of context info """ context_path = self.path_g.get_context_file_path() return read_json_file(context_path)
def get_quorum(self) -> int: """ get the minimum number of presenting guardians in this election :return: the minimum number of presenting guardians in integer """ context_file_path = self.path_g.get_context_file_path() context = read_json_file(context_file_path) return int(context.get('quorum'))
def __get_num_of_guardians_from_context(self) -> int: """ get number of guardians from the context.json :return: number of guardians n in integer """ context_file_path = self.path_g.get_context_file_path() context = read_json_file(context_file_path) return int(context.get('number_of_guardians'))
def get_location(self) -> str: """ get the location information of the election :return: location information as a string """ device_folder_path = self.path_g.get_device_folder_path() for file in glob.glob(device_folder_path + '*json'): dic = read_json_file(file) return dic.get('location')
def get_device_id(self) -> str: """ get the id of recording device :return: the device id as string """ device_folder_path = self.path_g.get_device_folder_path() for file in glob.glob(device_folder_path + '*json'): dic = read_json_file(file) return dic.get('uuid')
def get_public_key_of_a_guardian(self, index: int) -> int: """ get the public key Ki of a guardian :param index: guardian index :return: public key Ki of guardian i in integer """ file_path = self.path_g.get_guardian_coefficient_file_path(index) coefficients = read_json_file(file_path) return int(coefficients.get('coefficient_commitments')[0])
def __get_guardian_coeff_by_index(self, index: int) -> dict: """ verify the key information of guardian at a index position :param index: index of this guardian, (0 - number of guardians) :return: the corresponding key info stored in a dictionary """ if index >= self.num_of_guardians or index < 0: raise IndexError("index out of bound") coeff_file_path = self.path_g.get_guardian_coefficient_file_path(index) return json_parser.read_json_file(coeff_file_path)
def verify_all_ballots(self) -> bool: """ runs through the folder that contains ballot files once, runs encryption verification on every ballot :return: True there is no error, False otherwise """ error = self.initialize_error() count = 0 tracking_hashes = {} for ballot_file in glob.glob(self.folder_path + '*.json'): # verify all ballots, box 3 & 4 ballot_dic = json_parser.read_json_file(ballot_file) bev = BallotEncryptionVerifier(ballot_dic, self.param_g, self.limit_counter) # verify correctness contest_res = bev.verify_all_contests() if not contest_res: error = self.set_error() count += 1 # verify tracking hash # store tracking hashes in a dict prev_hash, curr_hash = bev.get_tracking_hash() tracking_hashes[curr_hash] = prev_hash # aggregate tracking hashes, box 5 tracking_res = bev.verify_tracking_hash() if not tracking_res: error = self.set_error() count += 1 if error: print( "[Box 3 & 4] Ballot verification failure, {num} ballots didn't pass check. " .format(num=count)) else: print("[Box 3 & 4] All ballot verification success. ".format( i=count)) if not self.verify_tracking_hashes(tracking_hashes): error = self.set_error() if error: print("[Box 5] Tracking hashes verification failure. ") else: print("[Box 5] Tracking hashes verification success. ") return not error
def __fill_in_dics(self): """ loop over the folder that stores all encrypted ballots once, go through every ballot to get the selection alpha/pad and beta/data :return: none """ # get to the folder ballot_folder_path = self.path_g.get_encrypted_ballot_folder_path() # loop over every ballot file for ballot_file in glob.glob(ballot_folder_path + '*json'): ballot = read_json_file(ballot_file) ballot_name = ballot.get('object_id') ballot_state = ballot.get('state') # ignore spoiled ballots if ballot_state == 'CAST': # loop over every contest contests = ballot.get('contests') for contest in contests: contest_name = contest.get('object_id') selections = contest.get('ballot_selections') contest_idx = self.order_names_dic.get(contest_name) curr_pad_dic = self.dics_by_contest[contest_idx * 2] curr_data_dic = self.dics_by_contest[contest_idx * 2 + 1] # loop over every selection for selection in selections: selection_name = selection.get('object_id') is_placeholder_selection = selection.get( 'is_placeholder_selection') # ignore placeholders if not is_placeholder_selection: pad = selection.get('ciphertext', {}).get('pad') data = selection.get('ciphertext', {}).get('data') self.__get_accum_product(curr_pad_dic, selection_name, int(pad)) self.__get_accum_product(curr_data_dic, selection_name, int(data))
def __fill_total_pad_data(self): """ loop over the tally.json file and read alpha/pad and beta/data of each non dummy selections in all contests, store these alphas and betas in the corresponding contest dictionary :return: none """ tally_path = self.path_g.get_tally_file_path() tally = read_json_file(tally_path) contests = tally.get('contests') contest_names = list(contests.keys()) for contest_name in contest_names: curr_dic_pad = {} curr_dic_data = {} contest = contests.get(contest_name) selections = contest.get('selections') selection_names = list(selections.keys()) for selection_name in selection_names: selection = selections.get(selection_name) total_pad = selection.get('message', {}).get('pad') total_data = selection.get('message', {}).get('data') curr_dic_pad[selection_name] = total_pad curr_dic_data[selection_name] = total_data self.total_pad_dic[contest_name] = curr_dic_pad self.total_data_dic[contest_name] = curr_dic_data
if not context_check: print("The context file path is invalid, try again. ") context_path = prompt_path_input( "Enter absolute or relative file path " "to the context file: ") param_g = ParameterGetter(context=context_path, constants=constants_path) constants_check = param_g.check_constants_file() context_check = param_g.check_context_file() vote_limit_c = VoteLimitCounter(param_g) try: vote_limit_c.get_contest_vote_limits() except: description_path = prompt_path_input( "Enter an absolute or relative file path to the context file: " ) baseline_v = BaselineVerifier(param_g) baseline_v.verify_all_params() vote_limit_c = VoteLimitCounter(param_g) print("Set up ready. \n") vote_path = prompt_path_input( "Enter an absolute or relative file path to your vote file:") vote = read_json_file(vote_path) print("...verifying...") ballot_v = BallotEncryptionVerifier(vote, param_g, vote_limit_c) ballot_v.verify_all_contests()
def __init__(self, path_g: FilePathGenerator, param_g: ParameterGenerator): super().__init__(param_g) self.path_g = path_g self.tally_dic = read_json_file(path_g.get_tally_file_path()) self.contests = self.tally_dic.get('contests') self.spoiled_ballots = self.tally_dic.get('spoiled_ballots')