def secure_kNN_C1(Bob, C2, database_T, public_key, k, m, n): """ database_T = E(t) n = db length / number of rows m = db row width / number of attributes """ ## Part 2 Q = receive(Bob) l = [] for i, t in enumerate(database_T): d_i = secure_squared_euclidean_distance_server(C2, public_key, Q, t) l.append((i, d_i)) # Send to C2 send(C2, l) ## Part 4 # Receive delta from C2 delta = receive(C2) for j, i_j in enumerate(delta): for h in range(m): r = public_key.get_random_lt_n() gamma = database_T[i_j][h] + r send(C2, gamma) send(Bob, r)
def secure_minimum_client(server, private_key): for i in range(32): secure_multiplication_client(server, private_key) # Receive Gamma' and L' Gamma_prime = receive(server) L_prime = receive(server) # Decrypt L M = [] for i in L_prime: M.append(private_key.decrypt(i)) alpha = 0 for i in M: if 1 == (i % private_key.public_key.n): alpha = 1 break M_prime = [] for g in Gamma_prime: M_prime.append(g * alpha) # Send M' and E(alpha) send(server, M_prime) send(server, private_key.public_key.encrypt(alpha))
def secure_kNN_C2(Bob, C1, private_key, k, m, n): ## Part 2 for i in range(n): secure_squared_euclidean_distance_client(C1, private_key, m) ## Part 3 l = receive(C1) assert isinstance(l, list) assert isinstance(l[0], tuple) d = [(i, private_key.decrypt(d_i)) for (i, d_i) in l] # Calculate k minimum values sorted_d = sorted(d, key=itemgetter(1)) best_k = sorted_d[:k] delta = tuple(i for (i, d_i) in best_k) # Send delta to C2 send(C1, delta) ## Part 5 for j in range(k): for h in range(m): gamma = receive(C1) gamma_prime = private_key.decrypt(gamma) send(Bob, gamma_prime)
def secure_minimum_server(client, public_key, u_decomp, v_decomp): # Randomly choose functionality F F = choice(['u > v', 'u < v']) # Initalize H_i = public_key.encrypt(0) L = [] Gamma = [] r = [] # For each bit for u_i, v_i in zip(u_decomp, v_decomp): u_times_v = secure_multiplication_server(client, public_key, u_i, v_i) # Append random number r^ r.append(public_key.get_random_lt_n()) if F == 'u > v': W_i = u_i - u_times_v Gamma.append((v_i - u_i) + public_key.encrypt(r[-1])) else: W_i = v_i - u_times_v Gamma.append((u_i - v_i) + public_key.encrypt(r[-1])) # XOR G_i = u_i + v_i + -2 * u_times_v H_i = (H_i * public_key.get_random_lt_n()) + G_i Phi_i = H_i - 1 L.append(W_i + (Phi_i * public_key.get_random_lt_n())) Gamma_prime, gamma_permute_key = permute(Gamma) L_prime, _ = permute(L) send(client, Gamma_prime) send(client, L_prime) # Recieve M' and E(alpha) M_prime = receive(client) alpha = receive(client) # De-permute M M = un_permute(M_prime, gamma_permute_key) minimum = [] for i in range(32): lambda_i = M[i] + (alpha * (public_key.n - r[i])) if F == 'u > v': minimum.append(u_decomp[i] + lambda_i) else: minimum.append(v_decomp[i] + lambda_i) return minimum
def secure_multiplication_client(server, private_key): # Recieve a' and b' from server a_prime = receive(server) b_prime = receive(server) # Decrypt ha = private_key.decrypt(a_prime) hb = private_key.decrypt(b_prime) # Multiply h = (ha * hb) % private_key.public_key.n # Send E(h) to server send(server, h)
def secure_kNN_Bob(C1, C2, public_key, query_Q, k, m, n): # Part 1 E_q = [public_key.encrypt(q_i) for q_i in query_Q] send(C1, E_q) # Part 4/5/6 t_prime = [] for j in range(k): tp_j = [] for h in range(m): r_jh = receive(C1) γprime_jh = receive(C2) tp_j.append(γprime_jh - r_jh) t_prime.append(tuple(tp_j)) return tuple(t_prime)
def secure_bit_decomposition_client(server, private_key): bitlength_m = receive(server) for i in range(0, bitlength_m): secure_lsb_client(server, private_key) if svr_client(server, private_key) == 1: return else: return secure_bit_decomposition_client(server, private_key)
def svr_client(server, private_key): W = receive(server) if private_key.decrypt(W) == 0: γ = 1 else: γ = 0 send(server, γ) return γ
def secure_lsb_client(server, private_key): Y = receive(server) y = private_key.decrypt(Y) if not y % 2: # y is even alpha = 0 else: alpha = 1 send(server, private_key.public_key.encrypt(alpha))
def secure_lsb_server(client, public_key, T, i): """Based on Encrypted_LSB from Samanthula & Jiang.""" r = public_key.get_random_lt_n() Y = T + r send(client, Y) alpha = receive(client) if not r % 2: # r is even return alpha else: return (1 - alpha)
def svr_server(client, public_key, enc_x, x_decomp): U = 0 for i in range(0, len(x_decomp)): x_i = x_decomp[i] * (2**i) U += x_i V = U - enc_x W = V * public_key.get_random_lt_n() send(client, W) γ = receive(client) return γ
def secure_multiplication_server(client, public_key, u, v): # Pick two random numbers ra = randrange(0, public_key.n // 2) rb = randrange(0, public_key.n // 2) rarb = (ra * rb) % public_key.n a_prime = u + ra b_prime = v + rb # Send a' and b' to client send(client, a_prime) send(client, b_prime) # Recieve E(h) from client h_prime = receive(client) s = h_prime - (u * rb) s_prime = s - (v * ra) u_times_v = s_prime - rarb return u_times_v
# bind to the port serversocket.bind((host, port)) # queue up to 10 requests serversocket.listen(10) # establish a connection print("Waiting for a client connection on {}...".format(port)) client, addr = serversocket.accept() print("Got a connection!") ### Recieve Config Parameters ### # Key public_key = receive(client) print("Got public key") ########################## while True: # Recieve menu option option = receive(client) if option in ('c1', 'c2'): # job is 'bob' if option == 'c1': client.close() raise RuntimeError("C2 must be started before C1.") C2 = client port_C1C2 = receive(C2)
def secure_minimum_of_n_client(server, private_key): n = receive(server) for _ in range(n): secure_bit_decomposition_client(server, private_key) for _ in range(n - 1): secure_minimum_client(server, private_key)
# job is 'C2' send(server, 'c2') print("Secure k-Nearest Neighbor selected, you are C2.") port_C1C2 = port - 1 send(server, port_C1C2) socket_C1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket_C1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) socket_C1.bind((host, port_C1C2)) socket_C1.listen(10) print("Waiting for C1...") C1, C1_addr = socket_C1.accept() print("Heard from C1!") checkval = receive(C1) if checkval != port_C1C2: raise RuntimeError("Bad checkval from C1.") print("OK checkval from C1.") send(C1, public_key) k = receive(Bob) print("Received k from Bob.") m_n = receive(C1) assert isinstance(m_n, tuple) and len(m_n) == 2 m, n = m_n print("Sent pk to C1. Starting SkNN.") secure_kNN_C2(Bob, C1, private_key, k, m, n)