def rand_shares_calculation(field_size, shareholders, thresholds, conjunctive):
    computed_shares = []
    degree_of_function = thresholds[-1] - 1
    secret = np.random.randint(0, field_size)
    if conjunctive:
        random_function = generate_function(degree_of_function, secret, field_size)
    else:
        random_function = generate_function(degree_of_function, np.random.randint(0, field_size), field_size)
        random_function[-1][0] = secret
    # print("Function: ", random_function)
    derivatives = calc_derivative_vector(random_function, degree_of_function, field_size)
    for (i, j) in shareholders:
        computed_shares.append(calc_function(derivatives[j], i, field_size))
    return computed_shares, secret
Example #2
0
def create_shares_for_messages(setup, m_1, m_2, hierarchical=True):
    messages = {}
    computed_shares = []
    functions = []
    if hierarchical:
        for message in [m_1, m_2]:
            field_size = read_field_size(setup)
            data, _, thresholds = read_data(setup)
            shareholder_ids = [tuple(x) for x in data.values]
            person_ids, vector_of_shares = shareholder_share_list_to_lists(
                shareholder_ids)
            # put those lists into lexicographic order
            shareholders, _ = sort_coordinates(person_ids, vector_of_shares)
            r = len(shareholders)
            degree_of_function = thresholds[-1] - 1

            random_function = generate_function(degree_of_function, message,
                                                field_size)
            functions.append(random_function)
            derivatives = calc_derivative_vector(random_function,
                                                 degree_of_function,
                                                 field_size)
            for (i, j) in shareholders:
                computed_shares.append(
                    calc_function(derivatives[j], i, field_size))
        for i, (i, j) in enumerate(shareholders):
            messages[(i, j)] = (computed_shares[i - 1],
                                computed_shares[i + r - 1])
        return messages, message, functions
    else:
        for message in [m_1, m_2]:
            field_size = read_field_size(setup, False)
            shareholders = read_shares(setup, double=True)
            shareholder_ids = list(shareholder[0]
                                   for shareholder in shareholders)
            # put those lists into lexicographic order
            r = len(shareholder_ids)
            degree_of_function = int(setup.split(",")[0]) - 1

            random_function = generate_function(degree_of_function, message,
                                                field_size)
            functions.append(random_function)
            for i in shareholder_ids:
                computed_shares.append(
                    calc_function(random_function, i, field_size))
        for id in shareholder_ids:
            messages[id] = (computed_shares[id - 1],
                            computed_shares[id + r - 1])
        return messages, message, [[[0, 0]], [[0, 0]]]
def call_and_apply_rand_shares(k, field_size, r, shareholders):
    all_new_shares_alpha = np.zeros((r, r))
    all_new_shares_beta = np.zeros((r, r))
    all_new_shares_r_i = np.zeros((r, r))
    all_new_shares_r_i_star = np.zeros((r, r))

    alpha_shares = {}
    beta_shares = {}
    r_i_shares = {}
    r_i_star_shares = {}
    secret_alphas = [None] * r
    secret_betas = [None] * r
    secret_r_is = [None] * r
    for i in range(r):
        secret_alphas[i] = np.random.randint(0, field_size)
        secret_betas[i] = np.random.randint(0, field_size)
        secret_r_is[i] = np.random.randint(0, field_size)
    secret_alpha = sum(secret_alphas) % field_size
    secret_beta = sum(secret_betas) % field_size

    for i, shareholder in enumerate(shareholders):
        random_function_alpha = generate_function(k-1, secret_alphas[i], field_size)
        random_function_beta = generate_function(k-1, secret_betas[i], field_size)
        random_function_r_i = generate_function(k-1, secret_r_is[i], field_size)
        random_function_r_i_star = generate_function(2*(k-1), secret_r_is[i], field_size)

        all_new_shares_alpha[i] = rand_shares_calculation(field_size, shareholders, random_function_alpha)
        all_new_shares_beta[i] = rand_shares_calculation(field_size, shareholders, random_function_beta)
        all_new_shares_r_i[i] = rand_shares_calculation(field_size, shareholders, random_function_r_i)
        all_new_shares_r_i_star[i] = rand_shares_calculation(field_size, shareholders, random_function_r_i_star)
    # print("ALPHA", all_new_shares_alpha)
    # print("BETA", all_new_shares_beta)

    summed_alpha_shares = rand_shares_summation(all_new_shares_alpha, field_size, r)
    summed_beta_shares = rand_shares_summation(all_new_shares_beta, field_size, r)
    summed_r_i_shares = rand_shares_summation(all_new_shares_r_i, field_size, r)
    summed_r_i_star_shares = rand_shares_summation(all_new_shares_r_i_star, field_size, r)
    # print("-->", summed_alpha_shares, summed_beta_shares, summed_r_i_shares, summed_r_i_star_shares)
    for idx, (i, _) in enumerate(shareholders):
        alpha_shares[i] = summed_alpha_shares[idx]
        beta_shares[i] = summed_beta_shares[idx]
        r_i_shares[i] = summed_r_i_shares[idx]
        r_i_star_shares[i] = summed_r_i_star_shares[idx]
    # print(secret_alphas, random_function_alpha, "\n", secret_betas, random_function_beta)

    return alpha_shares, beta_shares, r_i_shares, r_i_star_shares, secret_alpha, secret_beta
def create_random_renew_functions(degree_of_function, field_size, print_statements, shareholders):
    if print_statements:
        print("Creating random functions with degree {} and free coefficient 0 for old shareholders."
              .format(degree_of_function))
    # new dict to store all shareholder: function pairs
    function_dict = {}
    for old_shareholder in shareholders:
        function_dict[old_shareholder] = generate_function(degree_of_function, 0, field_size)
    # print the functions to screen
    if print_statements:
        for sh in function_dict:
            print(sh, ": ", end='')
            print_function(function_dict[sh])
        print("Calculating values for new shareholders from functions")
    return function_dict
def create_random_reset_functions(field_size, k_prime, print_statements, shareholder_shares):
    if print_statements:
        print("Creating random functions with degree {} and free coefficient share_value for old shareholders."
              .format(k_prime - 1))
    # new dict to store all shareholder: function pairs
    function_dict = {}
    for old_shareholder in shareholder_shares:
        function_dict[old_shareholder] = \
            generate_function(k_prime - 1, shareholder_shares[old_shareholder], field_size)
    # print the functions to screen
    if print_statements:
        for sh in function_dict:
            print(sh, ": ", end='')
            print_function(function_dict[sh])
        print("Calculating values for new shareholders from functions")
    return function_dict
Example #6
0
def compute_birkhoff_coefficients_and_polynomials(
        degree_of_function, determinant_of_original_matrix, field_size,
        function_dict, matrix, person_ids, print_statements, vector_of_shares):
    for i, share in enumerate(vector_of_shares):
        # calculate birkhoff interpolation coefficient
        birkhoff_coefficient = (int(share) * (-1)**i * divide(
            (determinant(get_minor(matrix, i, 0), field_size)) % field_size,
            determinant_of_original_matrix, field_size)) % field_size
        # generate a function with the coefficient as scalar
        function_dict[person_ids[i]] = generate_function(
            degree_of_function, birkhoff_coefficient, field_size)
        if print_statements or debug:
            print("Birkhoff Coefficient a_{}_0:".format(i + 1),
                  birkhoff_coefficient, "=", share, "*(-1)**", i, "*",
                  (determinant(get_minor(matrix, i, 0), field_size)) %
                  field_size, '/', determinant_of_original_matrix)
def share(setup, message, field_size=997, name="", print_statements=True):
    file_path = os.path.join(data_path, setup, 'level_stats.csv')
    # make sure number is in finite field
    if message > field_size:
        old_message = message
        message = message % field_size
        print(
            "Due to the size of the finite field ({}), the secret was changed to {} ({} % {}).\n"
            .format(field_size, message, old_message, field_size))
    list_of_people_per_level, thresholds, conjunctive = \
        get_data_and_catch_exceptions(setup, field_size, file_path, message)
    print(list_of_people_per_level, thresholds, conjunctive)
    # for conjunctive setup, get the maximum degree of the function to generate
    degree_of_function = thresholds[-1] - 1
    # generate random coefficients c for 0 < c <= prime and a function of those
    if conjunctive:
        if print_statements:
            print("Calculating shares for conjunctive setup")
        coefficients = generate_function(degree_of_function, message,
                                         field_size)
    else:
        coefficients = generate_function(degree_of_function,
                                         np.random.randint(0, field_size),
                                         field_size)
        print(coefficients)
        coefficients[-1][0] = message
        print(coefficients)
        if print_statements:
            print("Calculating shares for disjunctive setup")
    original_function = copy.deepcopy(coefficients)
    print("The randomly generated function is  \t{}".format(
        print_function(coefficients, False)))
    # calculate the shares for each shareholder
    share_dict = calculate_shares(coefficients, field_size,
                                  list_of_people_per_level, print_statements,
                                  thresholds, conjunctive)
    if print_statements:
        # print the dict to the screen
        print("New shares are: {}".format(share_dict))
    # write Shares to 'shares.csv' and save it in the setups directory
    try:
        if name:
            write_shares(
                field_size,
                os.path.join(data_path, setup, "shares_{}.csv".format(name)),
                share_dict)
            print(
                "Shares are saved to folder 'DATA/{}/shares_{}.csv'. Please don't edit the csv file manually."
                .format(setup, name))
        else:
            write_shares(field_size,
                         os.path.join(data_path, setup, "shares.csv"),
                         share_dict)
            print(
                "Shares are saved to folder 'DATA/{}/shares.csv'. Please don't edit the csv file manually."
                .format(setup))
    # error handling
    except PermissionError as e:
        print(
            "Can't write to '{}', maybe try to close the file and try again. \n {}"
            .format(file_path, repr(e)))
        raise
    return original_function, share_dict
def renew(setup, old_shares, reset_version_number=None, print_statements=True):
    # if old shares == {'shares': 'all'} use all shares from the setup; special case for convenience
    if old_shares == {'shares': 'all'}:
        old_shares = get_all_shares_from_setup(setup, reset_version_number)
    new_shares = list(old_shares.keys())
    # get all necessary data, i.e. the maximum degree of the functions and the size of the finite field
    data, degree_of_function, field_size, number_of_old_shares, thresholds = get_all_data_renew(
        old_shares, reset_version_number, setup)
    # check if the old shares can reconstruct the correct secret and if all given shareholders actually exist
    try:
        rec_result, rec_function, _, _, _ = reconstruct(setup,
                                                        number_of_old_shares,
                                                        random_subset=False,
                                                        subset=old_shares,
                                                        print_statements=False)
    except TypeError:
        print(
            "Could not reconstruct from old shares, thus no authorised subset is given."
        )
        raise
    # convert dict of subset to list
    shares = dict_to_list(old_shares)
    # troubleshooting
    check_and_print_validity(data, field_size, new_shares, print_statements,
                             rec_function, rec_result, shares)
    # start renew by creating random functions of degree thresholds[-1] - 1, with 0 as the free coefficient
    if print_statements:
        print(
            "Creating random functions with degree {} and free coefficient 0 for old shareholders."
            .format(degree_of_function))
    # new dict to store all shareholder: function pairs
    function_dict = {}
    for old_shareholder in old_shares:
        function_dict[old_shareholder] = generate_function(
            degree_of_function, 0, field_size)
    # print the functions to screen
    if print_statements:
        for sh in function_dict:
            print(sh, ": ", end='')
            print_function(function_dict[sh])
        print("Calculating values for new shareholders from functions")
    # create a matrix to store the values calculated in the renew
    partial_shares = np.zeros((number_of_old_shares + 1, len(new_shares)))
    # sanity check, should never cause problems
    assert (len(partial_shares) == len(partial_shares[0]) + 1), 'Wrong format of the matrix of partial results ' \
                                                                'for the new share values.'
    # write the old share values to the first row of the matrix
    write_old_share_values(old_shares, partial_shares)
    # calculate the other values with the formula from the paper
    # ( f^(j)_(k)(i) for all new shareholders (i,j) for all k)
    compute_and_add_results(field_size, function_dict, new_shares,
                            partial_shares, thresholds)
    # calculate the sums of all column values in the matrix
    sums = sum_over_subshares(field_size, new_shares, partial_shares,
                              print_statements)
    # save the newly calculated values in a new shareholder:share dict
    resulting_shares = {}
    for i in range(len(sums)):
        resulting_shares[new_shares[i]] = int(sums[i])
    # check if the new shares produce the same result in the reconstruction as the old ones
    new_result, new_function, _, _, _ = reconstruct(setup,
                                                    random_subset=False,
                                                    subset=resulting_shares,
                                                    print_statements=False)
    # if not, raise an error
    if not (new_result == rec_result):
        raise ValueError("New Shares don't produce the same result ({}) "
                         "as old shares ({}).".format(new_result, rec_result))
    elif print_statements:
        # print all calculated information to the screen
        print_renew_results(new_function, new_result, rec_function,
                            resulting_shares)
    # create new .csv file to store the information
    file_path = create_renew_file(field_size, resulting_shares, setup)
    if print_statements:
        print("New Shares are saved to {}".format(file_path))
    return resulting_shares, new_result