Ejemplo n.º 1
0
def generate_vault(xyt_input_path, minutiae_points_amount, chaff_points_amount, poly_degree, secret, crc_length,
                   gf_exp, log_dict, echo=False):
    # extract minutiae from template
    nbis_minutiae_extractor = MinutiaeExtractor()
    minutiae_list = nbis_minutiae_extractor.extract_minutiae_from_xyt(xyt_input_path)
    if len(minutiae_list) < minutiae_points_amount:
        if echo:
            print('Not enough minutiae in template to proceed for generation of vault...')
        log_dict['too_few_minutiae_gallery'] = True
        return None

    vault = Vault()
    m2b = MinutiaConverter()

    # Cut low quality minutiae and convert all minutiae to uint and add to vault
    genuine_minutiae_list = []
    for candidate in minutiae_list:
        if len(genuine_minutiae_list) == minutiae_points_amount:
            break
        too_close = False
        for minutia in genuine_minutiae_list:
            if candidate.distance_to(minutia) <= POINTS_DISTANCE:
                too_close = True
                break
        if not too_close:
            genuine_minutiae_list.append(candidate)

    for minutia in genuine_minutiae_list:
        vault.add_minutia_rep(m2b.get_uint_from_minutia(minutia))

    # create chaff points and add to vault
    chaff_points_list = ChaffPointsGenerator.generate_chaff_points_randomly(chaff_points_amount, genuine_minutiae_list,
                                                                            vault.get_smallest_original_minutia(), m2b)
    for chaff_point in chaff_points_list:
        vault.add_chaff_point_rep(m2b.get_uint_from_minutia(chaff_point))

    # generate secret polynomial
    secret_poly_generator = PolynomialGenerator(secret, poly_degree, crc_length, gf_exp)
    if echo:
        print('Coefficients of secret polynomial: {}'.format(secret_poly_generator.coefficients))

    # evaluate polynomial at all vault minutiae points (not at chaff points)
    vault.evaluate_polynomial_on_minutiae(secret_poly_generator, echo=echo)

    # generate random evaluation for chaff points
    vault.evaluate_random_on_chaff_points(secret_poly_generator, gf_exp)

    # finalize vault (delete information on vault creation except vault_final_elements_pairs)
    vault.finalize_vault()

    return vault
Ejemplo n.º 2
0
    def unlock_vault_geom(vault: Vault, probe_minutiae, poly_degree, gf_exp, crc_length, secret_length, log_dict,
                          echo=False):
        """
        Given vault, find candidate minutiae according to probe minutiae (list of Minutia) using geometric hashing.
        Afterwards, run interpolation on candidate minutiae
        geom_table needs to exist in vault
        :returns True if match found in polynomial after interpolation, else False
        """

        def exit_false():
            """ :returns False for vault not unlocked """
            log_dict['amount_geom_table'] = len(vault_geom_table)
            log_dict['evaluated_subsets'] = -1
            log_dict['minutiae_candidates'] = 0
            log_dict['time_geom'] = time.time() - t_geom
            log_dict['geom_gallery_basis'] = None
            log_dict['geom_probe_basis'] = None
            vault.vault_original_minutiae_rep.clear()
            vault.vault_function_points_rep.clear()
            vault.vault_chaff_points_rep.clear()
            return False

        def get_geom_table_basis_threshold(probe_minutiae_gh):
            """
            Removes basis in geom_table of vault that correspond to no probe_minutiae orientation
            :param probe_minutiae_gh: list of probe minutiae as MinutiaNBIS_GH
            :return: changes vault.geom_table, no return value
            """
            geom_table = vault.geom_table.copy()
            for element_enroll in geom_table.copy():
                in_threshold = False
                for m in probe_minutiae_gh:
                    if abs(element_enroll.basis.theta - m.theta) <= Constants.BASIS_THETA_THRESHOLD:
                        # not removing element from geom_table
                        in_threshold = True
                        break
                # remove element from geom_table if there was no match
                if not in_threshold:
                    geom_table.remove(element_enroll)
            return geom_table

        assert vault.geom_table
        log_dict['thresholds'] = '({}/[{}/{}/{}/{}]/{})'.format(
            Constants.POINTS_DISTANCE,
            Constants.X_THRESHOLD, Constants.Y_THRESHOLD, Constants.THETA_THRESHOLD,
            Constants.TOTAL_THRESHOLD, Constants.BASIS_THETA_THRESHOLD)
        # start time geometric hashing
        t_geom = time.time()
        # create polynomial extractor
        poly_extractor = PolynomialExtractor(gf_exp)
        # convert probe minutia to GH form, iterate through probe_minutiae, taking random probe minutia as basis
        probe_minutiae_GH = GHTransformer.convert_list_to_MinutiaNBIS_GH(probe_minutiae)
        random.shuffle(probe_minutiae_GH)
        # remove all basis in geom_table that are not within threshold of probe_minutiae orientation
        vault_geom_table = get_geom_table_basis_threshold(probe_minutiae_GH)
        for cnt_basis, basis in enumerate(probe_minutiae_GH):
            # take random basis and try matching
            element_verification = GHTransformer.generate_verification_table_element(basis, probe_minutiae_GH.copy())
            for cnt_enroll, element_enrollment in enumerate(vault_geom_table):
                # check if basis in element_enrollment has similar orientation to current basis in probe
                if not (abs(element_verification.basis.theta - element_enrollment.basis.theta)
                        <= Constants.BASIS_THETA_THRESHOLD):
                    continue
                # clear lists in vault to be populated in decoding for each element in geom_table
                vault.vault_original_minutiae_rep.clear()
                vault.vault_function_points_rep.clear()
                vault.vault_chaff_points_rep.clear()
                assert len(element_enrollment.transformed_minutiae_list) == len(vault.vault_final_elements_pairs)
                # cnt_m_enr is representing the same indices also in vault_final_element_pairs
                match = 0
                candidates_verification = []
                candidates_enrollment = []
                candidate_minutiae_verification = element_verification.transformed_minutiae_list.copy()
                for cnt_m_enr, minutia_enrollment in enumerate(element_enrollment.transformed_minutiae_list):
                    if not candidate_minutiae_verification:
                        break
                    for minutia_verification in candidate_minutiae_verification:
                        if fuzzy_compare(minutia_enrollment, minutia_verification):
                            log_dict['geom_single_match'] += 1
                            # Only add element if not already in list
                            if not vault.vault_final_elements_pairs[
                                       cnt_m_enr].x_rep in vault.vault_original_minutiae_rep:
                                match += 1
                                # add representation (uint) to candidate minutiae
                                # first element corresponding to x value of vault tuple
                                vault.add_minutia_rep(vault.vault_final_elements_pairs[cnt_m_enr].x_rep)
                                # second element corresponding to y value of vault tuple
                                vault.add_function_point_rep(vault.vault_final_elements_pairs[cnt_m_enr].y_rep)
                                # candidate minutiae for logging purposes
                                candidates_verification.append(minutia_verification)
                                candidates_enrollment.append(minutia_enrollment)
                            assert match == len(vault.vault_original_minutiae_rep)
                        else:
                            # add to chaff points (but not relevant as minutia can not be matched in different basis)
                            chaff_candidate = vault.vault_final_elements_pairs[cnt_m_enr].x_rep
                            if chaff_candidate not in vault.vault_chaff_points_rep:
                                vault.add_chaff_point_rep(chaff_candidate)
                        log_dict['geom_iteration'] += 1

                if match >= Constants.MATCH_THRESHOLD:
                    assert match == len(vault.vault_original_minutiae_rep)
                    assert len(candidates_verification) == len(candidates_enrollment)
                    assert len(vault.vault_original_minutiae_rep) == len(vault.vault_function_points_rep)
                    assert len(vault.vault_function_points_rep) == len(candidates_enrollment)
                    # log iterations in geometric hashing, minutiae candidates. tries to interpolate and basis
                    log_dict['amount_geom_table'] += cnt_enroll
                    log_dict['minutiae_candidates'] = len(vault.vault_original_minutiae_rep)
                    log_dict['geom_match_tries'] += 1
                    log_dict['geom_gallery_basis'] = element_enrollment.basis
                    log_dict['geom_probe_basis'] = element_verification.basis

                    # time geometric hashing
                    log_dict['time_geom'] = time.time() - t_geom
                    # polynomial interpolation on candidate set function points and test CRC in extracted polynomials
                    t_interpol = time.time()
                    success = poly_extractor.interpolate_and_check_crc(vault, poly_degree, crc_length,
                                                                       secret_length, log_dict, echo=echo)
                    log_dict['time_interpolation'] += time.time() - t_interpol
                    if success:
                        # log candidate minutiae
                        if Constants.LOG_CANDIDATE_MINUTIAE:
                            log_candidates_minutia(Constants.LOG_CANDIDATES_PATH_PREFIX,
                                                   Constants.LOG_CANDIDATES_PATH_SUFFIX,
                                                   candidates_verification, candidates_enrollment,
                                                   element_verification.basis, element_enrollment.basis,
                                                   vault, number=log_dict['exp_number'])
                        return True

                # break if max threshold is reached
                if log_dict['geom_iteration'] > Constants.MAX_ITERATION_THRESHOLD:
                    print("Max iteration threshold reached!")
                    return exit_false()

        # unfortunately, no sets found
        return exit_false()