Пример #1
0
def server_ack(OK, msg):
    if OK:
        pass
        #print_success(msg, CLIENT_VALUES['my_sid'])
    else:
        print_failure(msg, CLIENT_VALUES['my_sid'])
        sio.disconnect()
Пример #2
0
def handle_encrypted_messages(encrypted_messages):
    sending_client_sid = request.sid

    # Check in which round the FSM is
    if SERVER_VALUES['ROUND'] != 1:
        print_failure('Too late to send list of encrypted messages.',
                      sending_client_sid)
        return False, 'Too late to send your list encrypted messages.'  # If False, make this node drop (sio.disconnect()) in the client callback

    # TODO: Verify assumptions about this list and about sending_client_sid
    # Add the list of encrypted messages from this client SID to the Server Storage
    ##########################################
    SERVER_STORAGE[sending_client_sid]['list_enc_msg'] = encrypted_messages
    #############################################

    # Logging message
    #print_success('Received list of encrypted messages.', sending_client_sid)

    # Add this client SID in the list of active clients at round 1
    SERVER_VALUES['U1'].append(sending_client_sid)

    # No clients from last round have dropped out, and this is the last client we're receiving the list of encrypted messages from
    if set(SERVER_VALUES['U1']) == set(SERVER_VALUES['U0']):
        SERVER_VALUES['BENCHMARK_TIME_ROUND_1_COMM'] = time.time(
        ) - SERVER_VALUES['starting_time_round_1']
        print('Received all encrypted msgs',
              SERVER_VALUES['BENCHMARK_TIME_ROUND_1_COMM'])

    # Acknowledgement message (to the client) that everything went fine
    return True, 'List of encrypted messages succesfully received by server.'
Пример #3
0
def handle_shares(shares):
    sending_client_sid = request.sid

    # Check in which round the FSM is
    if SERVER_VALUES['ROUND'] != 3:
        print_failure('Too late to send final shares.', sending_client_sid)
        return False, 'Too late to send your mask and shares.'  # If False, make this node drop (sio.disconnect()) in the client callback

    # TODO: Verify assumptions about this y (format etc...)
    # Add the shares from this client SID to the Server Storage
    ####################################################################################
    SERVER_STORAGE[sending_client_sid]['b_shares_alive'] = shares[
        'b_shares_alive']
    SERVER_STORAGE[sending_client_sid]['ssk_shares_dropped'] = shares[
        'ssk_shares_dropped']

    ####################################################################################

    # Logging message
    #print_success('Received share of mask "b" for alive clients and share of key "ssk" for dropped out clients.', request.sid)

    # Add this client SID in the list of active clients at round 3
    SERVER_VALUES['U3'].append(sending_client_sid)

    # No clients from last round have dropped out, and this is the last client we're receiving the masked input y from

    if set(SERVER_VALUES['U3']) == set(SERVER_VALUES['U2']):
        SERVER_VALUES['BENCHMARK_TIME_ROUND_3_COMM'] = time.time(
        ) - SERVER_VALUES['starting_time_round_3']
        print('Received all shares/masks',
              SERVER_VALUES['BENCHMARK_TIME_ROUND_3_COMM'])

    return True, 'Shares succesfully received by server.'
Пример #4
0
def round2():

    U2 = SERVER_VALUES['U2']
    n2 = len(U2)
    if n2 < SERVER_VALUES['t']:
        print_failure(
            'Did not receive masked input "y" 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 U1 but not in U2
    dropped_out_clients = list(set(SERVER_VALUES['U1']) - set(U2))
    SERVER_VALUES['dropped_out_clients_round_2'] = dropped_out_clients

    #print()
    #print_info('Advertise list of alive and dropped out clients from the previous round to all still alive clients.', 'Server')
    #print()

    sio.emit('ROUND_3', {'dropped_out': dropped_out_clients, 'alive': U2})

    sio.start_background_task(timer_round_3)
Пример #5
0
def round0():

    U0 = SERVER_VALUES['U0']
    n0 = len(U0)
    if n0 < 2:  # At least 3 clients (n=3, t=2)
        print_failure(
            'Did not receive public keys 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

    SERVER_VALUES['n0'] = n0
    SERVER_VALUES['t'] = int(n0 / 2) + 1

    list_pubkeys = {
    }  # Copy here the cpk and spk keys for each client, don't send the WHOLE server storage dict
    for client_sid in U0:
        list_pubkeys[client_sid] = {}
        list_pubkeys[client_sid]['cpk'] = SERVER_STORAGE[client_sid]['cpk']
        list_pubkeys[client_sid]['spk'] = SERVER_STORAGE[client_sid]['spk']

    #print()
    #print_info('Broadcasting list of pubkeys to clients.', 'Server')
    #print()

    sio.emit(
        'ROUND_1',
        list_pubkeys)  # No callback because it's a broadcast message (room=/)

    sio.start_background_task(timer_round_1)
Пример #6
0
def handle_y(y):
    sending_client_sid = request.sid

    # Check in which round the FSM is
    if SERVER_VALUES['ROUND'] != 2:
        print_failure('Too late to send masked input "y".', sending_client_sid)
        return False, 'Too late to send your masked input "y".'  # If False, make this node drop (sio.disconnect()) in the client callback

    # TODO: Verify assumptions about this y (format etc...)
    # Add the masked input y from this client SID to the Server Storage
    ############################################################
    SERVER_STORAGE[sending_client_sid]['y'] = y
    ############################################################

    # Logging message
    #print_success('Received masked input "y".', request.sid)

    # Add this client SID in the list of active clients at round 2
    SERVER_VALUES['U2'].append(sending_client_sid)

    # No clients from last round have dropped out, and this is the last client we're receiving the masked input y from
    if set(SERVER_VALUES['U2']) == set(SERVER_VALUES['U1']):
        SERVER_VALUES['BENCHMARK_TIME_ROUND_2_COMM'] = time.time(
        ) - SERVER_VALUES['starting_time_round_2']
        print('Received all inputs y',
              SERVER_VALUES['BENCHMARK_TIME_ROUND_2_COMM'])

    # Acknowledgement message (to the client) that everything went fine
    return True, 'Masked input "y" succesfully received by server.'
Пример #7
0
    def classify(self, exercise, key, X, verbose=False):

        try:
            prediction = self.classifiers[exercise][key].predict(X)
            if verbose:
                ut.print_success(key + ': reps classified')
            return prediction

        except Exception as e:
            print e
            ut.print_failure(key + ': reps not classified')
            return None
Пример #8
0
	def classify(self, exercise, key, X, verbose=False):
		
		try:
			prediction = self.classifiers[exercise][key].predict(X)
			if verbose:
				ut.print_success(key + ': reps classified')
			return prediction
			
		except Exception as e:
			print e
			ut.print_failure(key + ': reps not classified')
			return None
Пример #9
0
def round1():
    U1 = SERVER_VALUES['U1']
    n1 = len(U1)
    #print(U1)
    print("|U1| the number of clients sending enc mesage:", n1)
    #print(SERVER_VALUES['t'])
    if n1 < SERVER_VALUES['t']:
        print_failure(
            'Did not receive encrypted messages 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 U0 but not in U1
    dropped_out_clients = list(set(SERVER_VALUES['U0']) - set(U1))
    SERVER_VALUES['dropped_out_clients_round_1'] = dropped_out_clients

    # Instead of having a dictionary of messages FROM a given client SID, we want to construct
    # a dictionary of messages TO a given client SID.
    list_enc_msg_FROM = {}
    for client_sid in U1:
        list_enc_msg_FROM[client_sid] = SERVER_STORAGE[client_sid][
            'list_enc_msg']

    # This is here that we reverse the "FROM key TO value" dict to a "FROM value TO key" dict
    # e.g: {1: {2:a, 3:b, 4:c}, 3: {1:d,2:e,4:f}, 4: {1:g,2:h,3:i}}  -->  {1: {3:d, 4:g}, 3:{1:b, 4:i}, 4: {1:c,3:f} }
    list_enc_msg_TO = {}
    for from_client_sid, enc_msg_from_client_sid in list_enc_msg_FROM.items():
        for to_client_sid, enc_msg_to_client_sid in enc_msg_from_client_sid.items(
        ):
            # print(from_client_sid + ' --> ' + to_client_sdropoutid + ' : ' + str(enc_msg_to_client_sid))
            list_enc_msg_TO.setdefault(
                to_client_sid, {})[from_client_sid] = enc_msg_to_client_sid

    #print_info('Forwarding lists of encrypted messages to all clients.', 'Server')

    sessionID = SERVER_VALUES['sessionID']
    #print("sessionID------->",sessionID)

    serverround1totalsize = 0
    for client_sid in U1:
        round1servertoclientmessages = {
            "SID": sessionID,
            "enc_msgs": list_enc_msg_TO[client_sid]
        }
        serverround1totalsize += total_size(round1servertoclientmessages)
        sio.emit('ROUND_2', round1servertoclientmessages, room=client_sid)
    SERVER_VALUES['serverround1totalsize'] = serverround1totalsize  #单播 逐个相加
    sio.start_background_task(timer_round_2)
Пример #10
0
    def classify(self, exercise, key, X, verbose=True):
        try:

            # temp =cf.train_squat_classifiers(exercise)
            # prediction=temp[key].predict(X)
            prediction = self.classifiers[exercise][key].predict(X)
            if verbose:
                ut.print_success(key + ': classified')
            return prediction

        except Exception as e:
            print(e)
            ut.print_failure(key + ': not classified')
            return None
Пример #11
0
def round2():

    U2 = SERVER_VALUES['U2']
    n2 = len(U2)
    print("|U2| the number of clients sending inputs y:", n2)
    if n2 < SERVER_VALUES['t']:
        print_failure(
            'Did not receive masked input "y" 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 U1 but not in U2
    dropped_out_clients = list(set(SERVER_VALUES['U1']) - set(U2))
    SERVER_VALUES['dropped_out_clients_round_2'] = dropped_out_clients

    #print()
    #print_info('Advertise list of alive and dropped out clients from the previous round to all still alive clients.', 'Server')
    #print()

    round2servertoclientmessages = []
    for client_sid in U2:
        round2clienttoservermessages = SERVER_STORAGE[client_sid][
            'round2clienttoservermessages']
        round2servertoclientmessages.append(round2clienttoservermessages)

    SERVER_VALUES['serverround2totalsize'] = total_size({
        'dropped_out':
        dropped_out_clients,
        'alive':
        U2,
        'round2servertoclientmessages':
        round2servertoclientmessages
    })
    sio.emit(
        'ROUND_3', {
            'dropped_out': dropped_out_clients,
            'alive': U2,
            'round2servertoclientmessages': round2servertoclientmessages
        })

    sio.start_background_task(timer_round_3)
Пример #12
0
def handle_y(round2clienttoservermessages):
    sending_client_sid = request.sid

    #store the messages received from clients
    SERVER_STORAGE[sending_client_sid][
        'round2clienttoservermessages'] = round2clienttoservermessages

    # Check in which round the FSM is
    if SERVER_VALUES['ROUND'] != 2:
        print_failure('Too late to send masked input "y".', sending_client_sid)
        return False, 'Too late to send your masked input "y".'  # If False, make this node drop (sio.disconnect()) in the client callback

    # TODO: Verify assumptions about this y (format etc...)
    # Add the masked input y from this client SID to the Server Storage
    ############################################################
    SERVER_STORAGE[sending_client_sid]['y'] = round2clienttoservermessages[
        "mask_x"]
    ############################################################

    # Logging message
    #print_success('Received masked input "y".', request.sid)

    # Add this client SID in the list of active clients at round 2
    SERVER_VALUES['U2'].append(sending_client_sid)

    # No clients from last round have dropped out, and this is the last client we're receiving the masked input y from
    #10.15 when note the communication cost of round 2 when clients dropping out,
    #we should let the condition len(SERVER_VALUES['U2']) == constant ,where constant = N *( 1 - drop_out)
    #modify for drouout
    #if set(SERVER_VALUES['U2']) == set(SERVER_VALUES['U1']):
    if len(SERVER_VALUES['U2']) == int(
            len(SERVER_VALUES['U1']) * (1 - dropout)):
        SERVER_VALUES['BENCHMARK_TIME_ROUND_2_COMM'] = time.time(
        ) - SERVER_VALUES['starting_time_round_2']
        print('Received all inputs y',
              SERVER_VALUES['BENCHMARK_TIME_ROUND_2_COMM'])

    # Acknowledgement message (to the client) that everything went fine
    return True, 'Masked input "y" succesfully received by server.'
Пример #13
0
def handle_pubkeys(data):
    sending_client_sid = request.sid  #io客户端的sid, socketio用此唯一标识客户端.

    # Check in which round the FSM is
    if SERVER_VALUES['ROUND'] != 0:
        print_failure('Too late to send public keys.', sending_client_sid)
        return False, 'Too late to send your public keys.'  # If False, make this node drop (sio.disconnect()) in the client callback

    # Add public key cpk to Server Storage for this client SID
    try:
        SERVER_STORAGE.setdefault(sending_client_sid, {})['cpk'] = data['cpk']
    except:
        print_failure('Missing key cpk in client'
                      's messsage.', sending_client_sid)
        return False, 'Missing key cpk in your message.'

    # Add public key spk to Server Storage for this client SID
    try:
        SERVER_STORAGE.setdefault(sending_client_sid, {})['spk'] = data['spk']
    except:
        print_failure('Missing key spk in client'
                      's messsage.', sending_client_sid)
        return False, 'Missing key spk in your message.'

    # Logging message
    #print_success('Received public keys.', sending_client_sid)

    # Add this client SID in the list of active clients at round 0
    SERVER_VALUES['U0'].append(sending_client_sid)

    # No clients have dropped out so far, and this is the last client we're receiving the public keys from
    if len(set(SERVER_VALUES['U0'])) == INIT_NB_CLIENTS:
        SERVER_VALUES['BENCHMARK_TIME_ROUND_0_COMM'] = time.time(
        ) - SERVER_VALUES['starting_time_round_0']
        print('Received all pubkeys',
              SERVER_VALUES['BENCHMARK_TIME_ROUND_0_COMM'])

    # Acknowledgement message (to the client) that everything went fine
    return True, 'Public keys succesfully received by server.'
Пример #14
0
def round2(enc_msgs):

    for client_sid, enc_msg in enc_msgs.items():

        # Decrypt the encrypted message and parse it
        enc_key_for_sid = CLIENT_STORAGE[client_sid]['enc_key']
        msg = AESCipher(str(enc_key_for_sid)).decrypt(enc_msg)

        msg_parts = msg.split(' || ')

        protocol_id = msg_parts[0]  # TODO: What's the use? #TODO: Timestamp?
        from_client_sid = msg_parts[1]
        my_sid = msg_parts[2]
        share_ssk_for_sid = msg_parts[3]
        share_a_for_sid = msg_parts[4]
        share_b_for_sid = msg_parts[5]

        # Store has been received for client_sid
        CLIENT_STORAGE[from_client_sid]['share_ssk'] = share_ssk_for_sid
        CLIENT_STORAGE[from_client_sid]['share_a'] = share_a_for_sid
        CLIENT_STORAGE[from_client_sid]['share_b'] = share_b_for_sid

        # Sanity check
        if client_sid != from_client_sid or my_sid != CLIENT_VALUES['my_sid']:
            print_failure('Received wrong message!', CLIENT_VALUES['my_sid'])
            sio.disconnect()

        # Derive secret shared mask seed s_for_sid (Diffie-Hellman Agreement)
        s_for_sid = DHKE.agree(CLIENT_VALUES['my_ssk'],
                               CLIENT_STORAGE[client_sid]
                               ['spk'])  #; print('s_for_sid =', s_for_sid)

        # Derive s_mask from above seed
        np.random.seed(
            s_for_sid %
            2**32)  # TODO: Higher entropy than 2**32??? (max value to .seed())
        s_mask_for_sid = np.random.uniform(
            -UNIFORM_S_BOUNDS, UNIFORM_S_BOUNDS, NB_CLASSES
        )  #; print('s_for_sid =', s_for_sid )# TODO: Which values??

        # Store also that
        CLIENT_STORAGE[client_sid]['s'] = s_for_sid
        CLIENT_STORAGE[client_sid]['s_mask'] = s_mask_for_sid

    # Construct masked input:
    # First the noisy input (the one that the server will aggregate)
    noisy_x = CLIENT_VALUES['x'] + CLIENT_VALUES['a_noise']

    # Then, add the individual mask
    yy = noisy_x + CLIENT_VALUES['b_mask']

    all_masks = np.zeros(NB_CLASSES)
    for client_sid in CLIENT_STORAGE.keys():
        if client_sid == CLIENT_VALUES['my_sid']:
            continue  # Skip my own SID
        if not 's_mask' in CLIENT_STORAGE[client_sid].keys():
            print_failure("No shared mask for client", client_sid)
            continue  # We do not have shared mask from this client SID
        sgn = np.sign(
            int(CLIENT_VALUES['my_sid'], 16) -
            int(client_sid, 16))  # Substract the masks of greater client SIDs,
        all_masks += sgn * CLIENT_STORAGE[client_sid][
            's_mask']  # or add those of smaller client SIDs

    # Here is the final output "y" to send to server
    y = yy + all_masks

    #print_info('Sending masked input "y" to server...', CLIENT_VALUES['my_sid'])
    sio.emit(
        'INPUT_Y', list(y), callback=server_ack
    )  # Send "y" as a python list because numpy arrays are not JSON-serializable
Пример #15
0
pt = PersonalTrainer({'squat': 'NeckY', 'pushup': 'NeckY'})

try:
    #pt.load_reps('squat',os.path.join('../data/data_sets','multipleClass4.p'))
    pt.load_reps('pushup',
                 os.path.join('../data/data_sets', 'pushupDataSet109.p'))
    #     pt.load_reps(os.path.join('../data/data_sets','pushupDataSet109.p'))
    ut.print_success('Training data loaded')
    try:
        #pt.set_classifiers('squat',classification_ftopt.train_squat_classifiers(pt))
        pt.set_classifiers('pushup',
                           classification_ftopt.train_pushup_classifiers(pt))
        #         pt.set_classifiers(classification.train_pushup_classifiers(pt))
        ut.print_success('Classifiers trained')
    except Exception as e:
        ut.print_failure('Could not train classifiers' + str(e))
except Exception as e:
    ut.print_failure('Could not load training data:' + str(e))

# #Store Classifiers

# In[ ]:

#
# classifiers = pt.get_classifiers('squat')
# pickle.dump(classifiers,open('squat_classifiers_ftopt.p','wb'))

classifiers = pt.get_classifiers('pushup')
pickle.dump(classifiers, open('pushup_classifiers_ftopt.p', 'wb'))

# In[ ]:
Пример #16
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)
Пример #17
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!')
Пример #18
0
def abort(reason):
    print()
    print_failure(reason, 'Server')
    sio.disconnect()
Пример #19
0
def round1(pubkeys):
    start = time.time()
    # Store the keys received from the server, in the dictionary CLIENT_STORAGE, for each client_sid
    for client_sid, pubkeys_for_client_sid in pubkeys.items():
        if client_sid == CLIENT_VALUES['my_sid']:
            continue # Does not need to store my own keys (already stored in CLIENT_VALUES)
        try:
            CLIENT_STORAGE.setdefault(client_sid, {})['cpk'] = pubkeys_for_client_sid['cpk']#当查找的键值 key 不存在的时候,setdefault()函数会返回默认值并更新字典,添加键值
            CLIENT_STORAGE.setdefault(client_sid, {})['spk'] = pubkeys_for_client_sid['spk']
        except KeyError:
            print_failure('Missing key cpk or spk in server''s messsage.', client_sid)
            sio.disconnect()

    # Compute n, the number of active clients (me, included)
    n = len(CLIENT_STORAGE.keys()) + 1                                                           #; print('n =', n)

    # Compute t, the minimum number of clients we need for the aggregation
    t = int(n/2) + 1                                                                             #; print('t =', t)

    

    # Draw random seed b, and make a mask out of it
    b = secrets.randbits(32)                                                                    #; print('b =', b)
    np.random.seed(b)
    b_mask = np.random.uniform(-UNIFORM_B_BOUNDS, UNIFORM_B_BOUNDS, NB_CLASSES)                 #; print('b_mask =', b_mask) # TODO: HOW TO CHOOSE THOSE VALUES???

    # Create t-out-of-n shares for seed b
    shares_b = SecretSharer.split_secret(b, t, n)                                               #; print('shares_b =', shares_b)

    # Create t-out-of-n shares for my private key my_ssk (as an hex_string)
    shares_my_ssk = SecretSharer.split_secret(CLIENT_VALUES['my_ssk'], t, n)                    #; print('shares_my_ssk =', shares_my_ssk)


    # Store all the previously generated values, in client's dictionary
    CLIENT_VALUES['n'] = n; CLIENT_VALUES['t'] = t

    
    CLIENT_VALUES['b'] = b; CLIENT_VALUES['b_mask'] = b_mask

    #CLIENT_VALUES['shares_a'] = shares_a
    CLIENT_VALUES['shares_b'] = shares_b
    CLIENT_VALUES['shares_my_ssk'] = shares_my_ssk

    # Store my share of b in isolation:
    my_share_b = shares_b[0]
    shares_b = list( set(shares_b) - set([my_share_b]) )
    CLIENT_VALUES['my_share_b'] = my_share_b

    list_encrypted_messages = {}
    for ID, client_sid in enumerate(CLIENT_STORAGE.keys()):

        if client_sid == CLIENT_VALUES['my_sid']:
            continue # Skip my own sid # FIXME: Actually, I am NOT part of CLIENT_STORAGE.keys()

        # Derive encryption key enc_key_for_sid (via Diffie-Hellman Agreement)
        enc_key_for_sid = DHKE.agree(CLIENT_VALUES['my_csk'], CLIENT_STORAGE[client_sid]['cpk'])             #; print('enc_key_for_sid =', enc_key_for_sid)

        # Client "client_sid" will be sent this message:
        msg = 'ProtoV1.0' + ' || ' + str(CLIENT_VALUES['my_sid']) + ' || ' + str(client_sid) + ' || ' + str(shares_my_ssk[ID]) + ' || ' + str(shares_b[ID])

        # Encrypt the message with the pre-derived shared encryption key
        enc_msg = PrpCrypt(str(enc_key_for_sid)).encrypt(msg)

        # Store the encrypted messages in a dictionary (keyed by client_sid) that will be sent to the server
        list_encrypted_messages[client_sid] = enc_msg


        CLIENT_STORAGE[client_sid]['enc_key'] = enc_key_for_sid
        CLIENT_STORAGE[client_sid]['msg'] = msg
        CLIENT_STORAGE[client_sid]['enc_msg'] = enc_msg

       

     #Generate Rn*************************************
    Rn = random.randint(1,1000)
    CLIENT_VALUES["Rn"] = Rn

    round1clienttoservermessages = {"Rn":Rn, "enc_msg":list_encrypted_messages}
    
    end = time.time()
    timeofround1 = end - start
    
    CLIENT_VALUES['timeofround1'] = timeofround1

    clientround1totalsize = total_size(round1clienttoservermessages)
    CLIENT_VALUES['clientround1totalsize'] = clientround1totalsize

    print("timeofround1:",timeofround1,"clientround1totalsize:",clientround1totalsize)

    sio.emit('ENC_MSGS', round1clienttoservermessages, callback=server_ack)
    # drop out in round 1 set(U1) - set(U0)

    if WILL_CRASH:
        sio.sleep(1)
        os._exit(0)
Пример #20
0
def round1(pubkeys):

    # Store the keys received from the server, in the dictionary CLIENT_STORAGE, for each client_sid
    for client_sid, pubkeys_for_client_sid in pubkeys.items():
        if client_sid == CLIENT_VALUES['my_sid']:
            continue  # Does not need to store my own keys (already stored in CLIENT_VALUES)
        try:
            CLIENT_STORAGE.setdefault(
                client_sid, {})['cpk'] = pubkeys_for_client_sid['cpk']
            CLIENT_STORAGE.setdefault(
                client_sid, {})['spk'] = pubkeys_for_client_sid['spk']
        except KeyError:
            print_failure('Missing key cpk or spk in server'
                          's messsage.', request.sid)
            sio.disconnect()

    # Compute n, the number of active clients (me, included)
    n = len(CLIENT_STORAGE.keys()) + 1  #; print('n =', n)

    # Compute t, the minimum number of clients we need for the aggregation
    t = int(n / 2) + 1  #; print('t =', t)

    # Draw random seed a, and make a gaussian noise mask out of it
    a = secrets.randbits(32)  #; print('a =', a) # TODO: Chose higher entropy
    np.random.seed(a)
    a_noise_vector = np.random.normal(
        0,
        float(SIGMA) / np.sqrt(t),
        NB_CLASSES)  #; print('a_noise_vector =', a_noise_vector)

    # Draw random seed b, and make a mask out of it
    b = secrets.randbits(32)  #; print('b =', b)
    np.random.seed(b)
    b_mask = np.random.uniform(
        -UNIFORM_B_BOUNDS, UNIFORM_B_BOUNDS, NB_CLASSES
    )  #; print('b_mask =', b_mask) # TODO: HOW TO CHOOSE THOSE VALUES???

    # Create t-out-of-n shares for seed a
    shares_a = SecretSharer.split_secret(a, t,
                                         n)  #; print('shares_a =', shares_a)

    # Create t-out-of-n shares for seed b
    shares_b = SecretSharer.split_secret(b, t,
                                         n)  #; print('shares_b =', shares_b)

    # Create t-out-of-n shares for my private key my_ssk (as an hex_string)
    shares_my_ssk = SecretSharer.split_secret(
        CLIENT_VALUES['my_ssk'], t,
        n)  #; print('shares_my_ssk =', shares_my_ssk)

    # Store all the previously generated values, in client's dictionary
    CLIENT_VALUES['n'] = n
    CLIENT_VALUES['t'] = t

    CLIENT_VALUES['a'] = a
    CLIENT_VALUES['a_noise'] = a_noise_vector
    CLIENT_VALUES['b'] = b
    CLIENT_VALUES['b_mask'] = b_mask

    CLIENT_VALUES['shares_a'] = shares_a
    CLIENT_VALUES['shares_b'] = shares_b
    CLIENT_VALUES['shares_my_ssk'] = shares_my_ssk

    # Store my share of b in isolation:
    my_share_b = shares_b[0]
    shares_b = list(set(shares_b) - set([my_share_b]))
    CLIENT_VALUES['my_share_b'] = my_share_b

    list_encrypted_messages = {}
    for ID, client_sid in enumerate(CLIENT_STORAGE.keys()):

        if client_sid == CLIENT_VALUES['my_sid']:
            continue  # Skip my own sid # FIXME: Actually, I am NOT part of CLIENT_STORAGE.keys()

        # Derive encryption key enc_key_for_sid (via Diffie-Hellman Agreement)
        enc_key_for_sid = DHKE.agree(
            CLIENT_VALUES['my_csk'], CLIENT_STORAGE[client_sid]
            ['cpk'])  #; print('enc_key_for_sid =', enc_key_for_sid)

        # Client "client_sid" will be sent this message:
        msg = 'ProtoV1.0' + ' || ' + str(
            CLIENT_VALUES['my_sid']) + ' || ' + str(client_sid) + ' || ' + str(
                shares_my_ssk[ID]) + ' || ' + str(shares_a[ID]) + ' || ' + str(
                    shares_b[ID])

        # Encrypt the message with the pre-derived shared encryption key
        enc_msg = AESCipher(str(enc_key_for_sid)).encrypt(msg)

        # Store the encrypted messages in a dictionary (keyed by client_sid) that will be sent to the server
        list_encrypted_messages[client_sid] = enc_msg

        CLIENT_STORAGE[client_sid]['enc_key'] = enc_key_for_sid
        CLIENT_STORAGE[client_sid]['msg'] = msg
        CLIENT_STORAGE[client_sid]['enc_msg'] = enc_msg

    #print_info('Sending list of encrypted messages to server...', CLIENT_VALUES['my_sid'])
    sio.emit('ENC_MSGS', list_encrypted_messages, callback=server_ack)

    if WILL_CRASH:
        sio.sleep(1)
        os._exit(0)
Пример #21
0
def round2(round1servertoclientmessages):
    #print("round1servertoclientmessages:",round1servertoclientmessages) success 10.10
    
    for client_sid, enc_msg in round1servertoclientmessages["enc_msgs"].items():

        # Decrypt the encrypted message and parse it
        enc_key_for_sid = CLIENT_STORAGE[client_sid]['enc_key']
        msg = PrpCrypt(str(enc_key_for_sid)).decrypt(enc_msg)

        msg_parts = msg.split(' || ')

        protocol_id = msg_parts[0] # TODO: What's the use? #TODO: Timestamp?
        from_client_sid = msg_parts[1]
        my_sid = msg_parts[2]
        share_ssk_for_sid = msg_parts[3]
        share_b_for_sid = msg_parts[4]

        # Store has been received for client_sid
        CLIENT_STORAGE[from_client_sid]['share_ssk'] = share_ssk_for_sid
        #CLIENT_STORAGE[from_client_sid]['share_a'] = share_a_for_sid
        CLIENT_STORAGE[from_client_sid]['share_b'] = share_b_for_sid

        # Sanity check
        if client_sid != from_client_sid or my_sid != CLIENT_VALUES['my_sid']:
            print_failure('Received wrong message!', CLIENT_VALUES['my_sid'])
            sio.disconnect()

        # Derive secret shared mask seed s_for_sid (Diffie-Hellman Agreement)
        s_for_sid = DHKE.agree(CLIENT_VALUES['my_ssk'], CLIENT_STORAGE[client_sid]['spk'])         #; print('s_for_sid =', s_for_sid)

        # Derive s_mask from above seed
        np.random.seed(s_for_sid % 2**32) # TODO: Higher entropy than 2**32??? (max value to .seed())
        s_mask_for_sid = np.random.uniform(-UNIFORM_S_BOUNDS, UNIFORM_S_BOUNDS, NB_CLASSES)                                  #; print('s_for_sid =', s_for_sid )# TODO: Which values??

        # Store also that
        CLIENT_STORAGE[client_sid]['s'] = s_for_sid
        CLIENT_STORAGE[client_sid]['s_mask'] = s_mask_for_sid


    # Construct masked input:
    yy = CLIENT_VALUES['x'] + CLIENT_VALUES['b_mask']

    #the second masked in our paper
    all_masks = np.zeros(NB_CLASSES)
    for client_sid in CLIENT_STORAGE.keys():
        if client_sid == CLIENT_VALUES['my_sid']:
            continue # Skip my own SID
        if not 's_mask' in CLIENT_STORAGE[client_sid].keys():
            print_failure("No shared mask for client", client_sid)
            continue # We do not have shared mask from this client SID
        sgn = np.sign(int(CLIENT_VALUES['my_sid'], 16) - int(client_sid, 16))  # Substract the masks of greater client SIDs,
        all_masks += sgn * CLIENT_STORAGE[client_sid]['s_mask']                # or add those of smaller client SIDs

    # Here is the final output "y" to send to server
    y = yy + all_masks

    '''
    Identity-Based Aggregate Signatures
    ->round0 & round 2 
    data:10.10
    '''
    '''individual signing step 2'''
    start = time.time()
    #extract sessionID from the message received from the server
    sessionID = round1servertoclientmessages['SID']
    #print("client receive SID",sessionID)
    
    #store the sessionID

    CLIENT_VALUES["sessionID"] = sessionID

    #calculate w by sessionID
    sha1 = hashlib.sha1()
    sha1.update(str(sessionID).encode("utf-8"))#str(sessionID) list ->string
    w = str(sha1.hexdigest())
    #w = "w" test first  
    #print("w->",w)

    P_n0 = CLIENT_VALUES['P_n0']
    P_n1 = CLIENT_VALUES['P_n1']
    sP_n0 = CLIENT_VALUES['sP_n0']
    sP_n1 = CLIENT_VALUES['sP_n1']

    Un = CLIENT_VALUES['my_sid']
    k_n = CLIENT_VALUES['k_n']
    Kn = CLIENT_VALUES['Kn']

    #VElGamal encryption
    x_n = []
    for i in range(NB_CLASSES):
        x_n.append(int(CLIENT_VALUES['x'][i]*1e6))

    #print("x_n",x_n)

    Cn = veg.enc(x_n,k_n)

    #construct Mn
    Mn= str(Kn)+str(Cn)+str(sessionID)
    sigma_n = ibas.InSign(w,Mn,Un,sP_n0,sP_n1)
    #print("Individual signature:", sigma_n)
    c_n = Element.from_hash(pairing, Zr, Un + Mn + w)

    #print("c_n",c_n,type(c_n))
    #print("P_n0",P_n0,type(P_n0))
    #print("P_n1",P_n1,type(P_n1))

    strsigma_n = [sigma_n[0],str(sigma_n[1]),str(sigma_n[2])] #shoud be convert to pypbc.Element.G2
    strc_n = str(c_n)#in fact it should by reconstruct though little computation cost
    strP_n0 = str(P_n0)
    strP_n1 = str(P_n1)

    round2clienttoservermessages = {"mask_x":list(y),"sigma_n":strsigma_n,"Cn":Cn,"Kn":Kn,"c_n":strc_n,"P_n0":strP_n0,"P_n1":strP_n1,'w':w}

    #print_info('Sending masked input "y" to server...', CLIENT_VALUES['my_sid'])
    end = time.time()
    timeofround2 = end - start
    CLIENT_VALUES['timeofround2'] = timeofround2
    clientround2totalsize = total_size(round2clienttoservermessages)
    CLIENT_VALUES['clientround2totalsize'] = clientround2totalsize

    print("timeofround2:",timeofround2,"clientround2totalsize:",clientround2totalsize)
    sio.emit('INPUT_Y', round2clienttoservermessages, callback=server_ack) # Send "y" as a python list because numpy arrays are not JSON-serializable