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_of_n_server(client, public_key, d, bitlength=32): num = n = len(d) outer = math.ceil(math.log2(n)) send(client, n) d_prime = [ secure_bit_decomposition_server(client, public_key, di, bitlength) for di in d ] for i in range(1, outer + 1): inner = num // 2 for j in range(1, inner + 1): # set L,R as defined in Samanthula,Jiang if i == 1: L, R = 2 * j - 1, 2 * j else: L, R = 2 * i * (j - 1) + 1, 2 * i * j - 1 # adjust L,R for indexing L, R = L - 1, R - 1 lhs = d_prime[L] rhs = d_prime[R] d_prime[L] = secure_minimum_server(client, public_key, lhs, rhs) d_prime[R] = None num = math.ceil(num / 2) return d_prime[0]
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_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_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 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 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_bit_decomposition_server(client, public_key, enc_x, bitlength_m): l_inv2 = paillier.EncodedNumber.encode(public_key, invert(2, public_key.n)) T = enc_x + 0 x_decomp = [] send(client, bitlength_m) for i in range(0, bitlength_m): x_decomp.append(secure_lsb_server(client, public_key, T, i)) Z = T - x_decomp[i] T = Z * l_inv2 if svr_server(client, public_key, enc_x, x_decomp) == 1: return list(reversed(x_decomp)) else: return secure_bit_decomposition_server(client, public_key, enc_x, bitlength_m)
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_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_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
port_C1 = port + 1 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_C1)) socket_C1.listen(10) print("Start C1 with options '{} -o c1'; I'll wait".format(port_C1)) C1, addr = socket_C1.accept() print("Heard from C1!") pk_C1 = receive(C1) assert pk_C1 is None option_C1 = receive(C1) if option_C1 != 'c1': raise RuntimeError("C1 MUST select C1; got {!r}".format(option_C1)) send(C1, port_C1C2) print("Please enter the query tuple Q: ", end='') Q = tuple(map(int, input().split())) print("Please enter k, the number of records: ", end='') k = int(input()) send(C1, k) send(C2, k) m_n = receive(C1) assert isinstance(m_n, tuple) and len(m_n) == 2 m, n = m_n if len(Q) != m:
public_key, private_key = generate_keypair() ### Initalize Connection Process ### # create a socket object server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if port < 1024 or 65535 < port: raise RuntimeError("Bad port, should be in [49153, 65534]") # connection to hostname on the port. server.connect((host, port)) ##################################### ### Send Config Paramaters ### # Send Public Key send(server, public_key) ############################## ### Start Menu ### while True: option = ARGS.option or print_menu() if 'c' in option.lower(): Bob = server if '2' in option: # job is 'C2' send(server, 'c2') print("Secure k-Nearest Neighbor selected, you are C2.") port_C1C2 = port - 1