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
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
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