Пример #1
0
def psu_reconstruct_single_mutual_mask(client_index_drop, client_index_live, union_s_shares_drop, union_live_spk, \
                                       UNION_DHKE, union_security_para_dict):
    """
    Assistant function for reconstructing mutual masks in parallel. (Single process)
    """
    # Load parameters for PRNG
    seed_len = union_security_para_dict['seed_len']
    security_strength = union_security_para_dict['security_strength']
    modulo_r_len = union_security_para_dict['modulo_r_len']
    item_count = union_security_para_dict[
        'item_count']  # length of perturbed Bloom filter (x)

    union_drop_ssk = SecretSharer.recover_secret(union_s_shares_drop)

    # Derive seed for mutual mask, i.e., agreed key, (u, v via Diffie-Hellman Agreement)
    s_uv = UNION_DHKE.agree(union_drop_ssk, union_live_spk)
    s_uv_modulo = s_uv % (2**seed_len)
    s_uv_entropy = int2bytes(s_uv_modulo, seed_len / 8)
    union_DRGB_s = HMAC_DRBG(s_uv_entropy, security_strength)
    union_s_mask = prng(union_DRGB_s, modulo_r_len, security_strength,
                        item_count)
    sgn = np.sign(client_index_live - client_index_drop)
    union_sgn_s_mask = sgn * union_s_mask
    union_sgn_s_mask = union_sgn_s_mask.astype('int64')
    return union_sgn_s_mask
Пример #2
0
def server_side_psu_reconstruct_self_mask(UNION_SERVER_STORAGE,
                                          UNION_ROUND_STORAGE,
                                          union_security_para_dict):
    """
    Reconstruct the random seed b and thus self mask for each live client in U2 using the shares from U3.
    """
    union_all_b_shares = []
    for client_index in UNION_ROUND_STORAGE['U3']:
        union_all_b_shares.append(
            UNION_SERVER_STORAGE[client_index]['live_b_shares'])
    union_b_shares_dict = {
        k: [d.get(k) for d in union_all_b_shares]
        for k in set().union(*union_all_b_shares)  # U2
    }
    # Reconstruct and add up each self mask by PRNG expanding using the seed b
    # Load parameters for PRNG
    seed_len = union_security_para_dict['seed_len']
    security_strength = union_security_para_dict['security_strength']
    modulo_r_len = union_security_para_dict['modulo_r_len']
    item_count = union_security_para_dict[
        'item_count']  # length of perturbed Bloom filter (x)
    # Store sum result
    union_b_mask_sum = np.zeros(item_count, dtype='int64')

    # NOT U3!!!!!!! SHOULD BE U2, those clients who send masked input y
    for client_index in UNION_ROUND_STORAGE['U2']:
        union_b = SecretSharer.recover_secret(
            union_b_shares_dict[client_index])
        union_b_entropy = int2bytes(union_b, seed_len / 8)
        union_DRBG_b = HMAC_DRBG(union_b_entropy, security_strength)
        union_b_mask = prng(union_DRBG_b, modulo_r_len, security_strength,
                            item_count)
        union_b_mask_sum += union_b_mask
    return union_b_mask_sum
def psu_reconstruct_single_self_mask(union_b_shares, union_security_para_dict):
    """
    Assistant function for reconstructing self masks in parallel. (Single process)
    """
    # Load parameters for PRNG
    seed_len = union_security_para_dict['seed_len']
    security_strength = union_security_para_dict['security_strength']
    modulo_r_len = union_security_para_dict['modulo_r_len']
    item_count = union_security_para_dict['item_count']  # length of perturbed Bloom filter (x)

    union_b = SecretSharer.recover_secret(union_b_shares)
    union_b_entropy = int2bytes(union_b, seed_len / 8)
    union_DRBG_b = HMAC_DRBG(union_b_entropy, security_strength)
    union_b_mask = prng(union_DRBG_b, modulo_r_len, security_strength, item_count)
    union_b_mask = union_b_mask.astype('int64')
    return union_b_mask
Пример #4
0
def server_side_psu_reconstruct_mutual_mask(UNION_SERVER_STORAGE,
                                            UNION_ROUND_STORAGE,
                                            union_security_para_dict,
                                            UNION_DHKE):
    """
    Reconstruct the secret key ssk and thus mutual mask for each dropped client in U1\U2 using the shares from U3.
    """
    item_count = union_security_para_dict[
        'item_count']  # length of perturbed Bloom filter (x)
    # Store sum result
    union_s_mask_sum = np.zeros(item_count, dtype='int64')
    if len(UNION_ROUND_STORAGE['U1\U2']
           ) == 0:  # Deal with special case no client drops in U2
        return union_s_mask_sum

    union_all_s_shares = []
    for client_index in UNION_ROUND_STORAGE['U3']:
        union_all_s_shares.append(
            UNION_SERVER_STORAGE[client_index]['drop_s_shares'])
    union_s_shares_dict = {
        k: [d.get(k) for d in union_all_s_shares]
        for k in set().union(*union_all_s_shares)  # U1\U2
    }
    # Reconstruct and add up each mutual mask (pair of each dropped client in U1/U2 with each live client in U2)
    # by PRNG expanding using the secret key ssk
    # Load parameters for PRNG
    seed_len = union_security_para_dict['seed_len']
    security_strength = union_security_para_dict['security_strength']
    modulo_r_len = union_security_para_dict['modulo_r_len']

    for client_index_drop in UNION_ROUND_STORAGE['U1\U2']:
        union_drop_ssk = SecretSharer.recover_secret(
            union_s_shares_dict[client_index_drop])
        # NOT U3!!!!!!! SHOULD BE U2, those clients who send masked input y.
        for client_index_live in UNION_ROUND_STORAGE['U2']:
            union_live_spk = UNION_SERVER_STORAGE[client_index_live]['spk']
            # Derive seed for mutual mask, i.e., agreed key, (u, v via Diffie-Hellman Agreement)
            s_uv = UNION_DHKE.agree(union_drop_ssk, union_live_spk)
            s_uv_modulo = s_uv % (2**seed_len)
            s_uv_entropy = int2bytes(s_uv_modulo, seed_len / 8)
            union_DRGB_s = HMAC_DRBG(s_uv_entropy, security_strength)
            union_s_mask = prng(union_DRGB_s, modulo_r_len, security_strength,
                                item_count)
            sgn = np.sign(client_index_live - client_index_drop)
            union_s_mask_sum += sgn * union_s_mask
    return union_s_mask_sum
Пример #5
0
def round3():

    U3 = SERVER_VALUES['U3']
    n3 = len(U3)
    print("|U3| the number of clients sending shared masks:", n3)
    if n3 < SERVER_VALUES['t']:
        print_failure(
            'Did not receive masks and shares from enough clients. Abort.',
            'Server')
        sio.emit(
            'abort', 'not enough clients'
        )  # Broadcast to everyone that the server aborts --> client should disconnect
        sio.sleep(1)
        os._exit(-1)  # sio.stop() # FIXME

    # The "dropped out clients" are all the clients sid that were present in the set U2 but not in U3
    dropped_out_clients = list(set(SERVER_VALUES['U2']) - set(U3))
    SERVER_VALUES['dropped_out_clients_round_3'] = dropped_out_clients

    Z = 0

    print("NB DROPPED OUT CLIENTS =",
          len(SERVER_VALUES['dropped_out_clients_round_2']))
    if SERVER_VALUES['dropped_out_clients_round_2'] != []:

        # Retrieve the shares of "ssk" of dropped out clients from all alive clients
        all_ssk_shares = []
        for client_sid in U3:
            all_ssk_shares.append(
                SERVER_STORAGE[client_sid]['ssk_shares_dropped'])

        ssk_shares_for_sid = {
            k: [d.get(k) for d in all_ssk_shares]
            for k in set().union(*all_ssk_shares)
        }

        # Reconstruct ssk from its shares
        ssk_for_sid = {}
        for client_sid in SERVER_VALUES['dropped_out_clients_round_2']:
            ssk = SecretSharer.recover_secret(ssk_shares_for_sid[client_sid])
            ssk_for_sid[client_sid] = ssk

        # Reconstruct all blinding values (s_masks) for all pairs of alive users with the dropped out users
        all_masks = np.zeros(NB_CLASSES)
        for dropped_client_sid in SERVER_VALUES['dropped_out_clients_round_2']:
            for alive_client_sid in U3:
                s_for_sid = DHKE.agree(ssk_for_sid[dropped_client_sid],
                                       SERVER_STORAGE[alive_client_sid]['spk'])
                np.random.seed(s_for_sid % 2**32)
                s_mask_for_sid = np.random.uniform(-UNIFORM_S_BOUNDS,
                                                   UNIFORM_S_BOUNDS,
                                                   NB_CLASSES)
                sgn = np.sign(
                    int(alive_client_sid, 16) - int(dropped_client_sid, 16))
                all_masks += sgn * s_mask_for_sid

        Z -= all_masks

    # Retrieve the shares of "b" from all alive clients
    all_b_shares = []
    for client_sid in U3:
        all_b_shares.append(SERVER_STORAGE[client_sid]['b_shares_alive'])

    b_shares_for_sid = {
        k: [d.get(k) for d in all_b_shares]
        for k in set().union(*all_b_shares)
    }

    # Reconstruct "b" from its shares
    b_for_sid = {}
    for client_sid in U3:
        b = SecretSharer.recover_secret(b_shares_for_sid[client_sid])
        b_for_sid[client_sid] = b

    # Remove b from the y that we received from clients, and aggregate the whole
    for client_sid in U3:
        b = b_for_sid[client_sid]
        np.random.seed(b)
        b_mask = np.random.uniform(-UNIFORM_B_BOUNDS, UNIFORM_B_BOUNDS,
                                   NB_CLASSES)
        Z += (SERVER_STORAGE[client_sid]['y'] - b_mask)

    print('Server succesfully aggregate the result and the lenth is ',
          len(list(Z)))

    # For Decentralized PATE, the label would be the argmax of this vote vector
    #print('LABEL:', np.argmax(Z))

    SERVER_VALUES['serverround3totalsize'] = total_size({
        "aggregation": list(Z),
        'U3': U3
    })

    sio.emit('ROUND_4', {"aggregation": list(Z), 'U3': U3})  #tianjia in 10.11

    # Go back to function call (ret) and exit in function timer_round3() above
    sio.start_background_task(timer_round_4)
Пример #6
0
def round3():

    U3 = SERVER_VALUES['U3']
    n3 = len(U3)
    if n3 < SERVER_VALUES['t']:
        print_failure(
            'Did not receive masks and shares from enough clients. Abort.',
            'Server')
        sio.emit(
            'abort', 'not enough clients'
        )  # Broadcast to everyone that the server aborts --> client should disconnect
        sio.sleep(1)
        os._exit(-1)  # sio.stop() # FIXME

    # The "dropped out clients" are all the clients sid that were present in the set U2 but not in U3
    dropped_out_clients = list(set(SERVER_VALUES['U2']) - set(U3))
    SERVER_VALUES['dropped_out_clients_round_3'] = dropped_out_clients

    Z = 0

    print("NB DROPPED OUT CLIENTS =",
          len(SERVER_VALUES['dropped_out_clients_round_2']))

    if SERVER_VALUES['dropped_out_clients_round_2'] != []:

        # Retrieve the shares of "ssk" of dropped out clients from all alive clients
        all_ssk_shares = []
        for client_sid in U3:
            all_ssk_shares.append(
                SERVER_STORAGE[client_sid]['ssk_shares_dropped'])

        ssk_shares_for_sid = {
            k: [d.get(k) for d in all_ssk_shares]
            for k in set().union(*all_ssk_shares)
        }

        # Reconstruct ssk from its shares
        ssk_for_sid = {}
        for client_sid in SERVER_VALUES['dropped_out_clients_round_2']:
            ssk = SecretSharer.recover_secret(ssk_shares_for_sid[client_sid])
            ssk_for_sid[client_sid] = ssk

        # Reconstruct all blinding values (s_masks) for all pairs of alive users with the dropped out users
        all_masks = np.zeros(NB_CLASSES)
        for dropped_client_sid in SERVER_VALUES['dropped_out_clients_round_2']:
            for alive_client_sid in U3:
                s_for_sid = DHKE.agree(ssk_for_sid[dropped_client_sid],
                                       SERVER_STORAGE[alive_client_sid]['spk'])
                np.random.seed(s_for_sid % 2**32)
                s_mask_for_sid = np.random.uniform(-UNIFORM_S_BOUNDS,
                                                   UNIFORM_S_BOUNDS,
                                                   NB_CLASSES)
                sgn = np.sign(
                    int(alive_client_sid, 16) - int(dropped_client_sid, 16))
                all_masks += sgn * s_mask_for_sid

        Z -= all_masks

    # Retrieve the shares of "b" from all alive clients
    all_b_shares = []
    for client_sid in U3:
        all_b_shares.append(SERVER_STORAGE[client_sid]['b_shares_alive'])

    b_shares_for_sid = {
        k: [d.get(k) for d in all_b_shares]
        for k in set().union(*all_b_shares)
    }

    # Reconstruct "b" from its shares
    b_for_sid = {}
    for client_sid in U3:
        b = SecretSharer.recover_secret(b_shares_for_sid[client_sid])
        b_for_sid[client_sid] = b

    # Remove b from the y that we received from clients, and aggregate the whole
    for client_sid in U3:
        b = b_for_sid[client_sid]
        np.random.seed(b)
        b_mask = np.random.uniform(-UNIFORM_B_BOUNDS, UNIFORM_B_BOUNDS,
                                   NB_CLASSES)
        Z += (SERVER_STORAGE[client_sid]['y'] - b_mask)

    # More noise that neccesary (t), remove that extra noise
    if 'extra_noises' in SERVER_VALUES:
        extra_noises = np.array(SERVER_VALUES['extra_noises'])
        extra_noises_sum = np.sum(extra_noises, axis=0)

        Z -= extra_noises_sum

    # Z is now the approriately noised array, containing the aggregation of private
    # vectors of the still alive clients
    # print('Z = ', Z)
    print('[*]', time.time(), 'Done')

    # For Decentralized PATE, the label would be the argmax of this vote vector
    #print('LABEL:', np.argmax(Z))

    sio.emit('complete', 'Reconstructed output z!')