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])
Beispiel #9
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')