def run(self): try: client_number = self.input_queue.get(timeout=self.timeout) if self.is_message_valid(client_number, intended_length=1): beta = self.create_private_key() own_number = mod_pow(self.g, beta, self.p) self.K = mod_pow(client_number, beta, self.p) cipher = Cipher(self.K) self.output_queue.put( (own_number, self.prepare_encrypted_message(first_number=client_number, second_number=own_number, cipher=cipher)), timeout=self.timeout) client_message = self.input_queue.get(timeout=self.timeout) if self.is_message_valid(client_message, intended_length=1): if self.is_encrypted_message_valid( client_number=client_number, server_number=own_number, encrypted_message=client_message, cipher=cipher, partner_id=self.client_id): self.finished_successfully = True return except: pass self.finished_successfully = False
def run(self): try: alpha = self.create_private_key() own_number = mod_pow(self.g, alpha, self.p) self.output_queue.put(own_number, timeout=self.timeout) message_from_server = self.input_queue.get(timeout=self.timeout) if self.is_message_valid(message_from_server, intended_length=2): server_number, encrypted_message = message_from_server self.K = mod_pow(server_number, alpha, self.p) cipher = Cipher(self.K) if self.is_encrypted_message_valid( client_number=own_number, server_number=server_number, encrypted_message=encrypted_message, cipher=cipher, partner_id=self.server_id): self.output_queue.put(self.prepare_encrypted_message( own_number, server_number, cipher), timeout=self.timeout) self.finished_successfully = True return except: pass self.finished_successfully = False
class Client(AbstractEntity): def __init__(self, server_input_queue, server_output_queue, name, h_0, K, key, secret): super(Client, self).__init__() self.server_input_queue = server_input_queue self.server_output_queue = server_output_queue self.name = name self.h_0 = h_0 self.K = K self.key = key self.secret = secret self.successfully_finished = None self.index = 1 def run(self): try: self.server_input_queue.put(self.name + ': Hi!') self.worker_input_queue, self.worker_output_queue = self.server_output_queue.get(timeout=self.timeout) self.worker_input_queue.put((self.name, self.prepare_encrypted_message())) server_response = self.worker_output_queue.get(timeout=self.timeout) if self.cipher.decrypt(server_response) == self.ok_signal: self.index += 1 self.worker_input_queue.put(self.prepare_encrypted_polynomial_coordinates()) server_confirmation = self.worker_output_queue.get(timeout=self.timeout) if self.is_message_valid(server_confirmation): if self.cipher.decrypt(server_confirmation) == self.ok_signal: self.successfully_finished = True return except: pass self.successfully_finished = False def prepare_encrypted_message(self): message = '{0}:{1}:{2}'.format(self.name, self.index, hash_n_times(self.h_0, self.K - self.index)) self.cipher = Cipher(self.key) return self.cipher.encrypt(message) def prepare_encrypted_polynomial_coordinates(self): message = '{0}:{1}'.format(self.secret[0], self.secret[1]) return self.cipher.encrypt(message)
class ServerWorker(AbstractEntity): def __init__(self, p, passwords, keys, parent): super(ServerWorker, self).__init__() self.input_queue = Queue() self.output_queue = Queue() self.p = p self.passwords = passwords self.keys = keys self.parent = parent def run(self): try: client_message = self.input_queue.get(timeout=self.timeout) if self.is_message_valid(client_message, intended_length=2): client_id, client_encrypted = client_message if self.parent.can_login(client_id): client_decrypted = self.decrypt_message(client_id, client_encrypted) inner_id, inner_index, client_hash = client_decrypted.split(':') if self.is_decrypted_message_valid(client_id, id=inner_id, index=inner_index, hash=client_hash): self.update_data(client_id, inner_index, client_hash) self.output_queue.put(self.create_encrypted_ok_message()) self.parent.login(client_id) encrypted_confirmation = self.input_queue.get(timeout=self.timeout) self.parent.confirm(client_id, self.decrypt_confirmation(encrypted_confirmation)) response = self.parent.workers_queue.get(timeout=self.timeout) if response == self.ok_signal: self.output_queue.put(self.create_encrypted_ok_message()) return except: pass self.output_queue.put(self.error_signal) def is_hashed_secret_valid(self, client_id, client_hash): try: client_secret = self.passwords.get(client_id)[0] return hash_function(client_hash) == client_secret except KeyError: pass return False def create_encrypted_ok_message(self): return self.cipher.encrypt(self.ok_signal) def decrypt_message(self, client_id, client_encrypted): self.cipher = Cipher(self.keys.get(client_id)) return self.cipher.decrypt(client_encrypted) def is_decrypted_message_valid(self, client_id, id, index, hash): try: return (id == client_id and self.passwords.get(client_id)[2] == int(index) and self.passwords.get(client_id)[1] >= int(index) and self.is_hashed_secret_valid(client_id, hash)) except: pass return False def decrypt_confirmation(self, encrypted_confirmation): return [int(coordinate) for coordinate in self.cipher.decrypt(encrypted_confirmation).split(':')] def update_data(self, client_id, inner_index, client_hash): k_value = self.passwords.get(client_id)[1] self.passwords[client_id] = (client_hash, k_value, int(inner_index) + 1)
def decrypt_message(self, client_id, client_encrypted): self.cipher = Cipher(self.keys.get(client_id)) return self.cipher.decrypt(client_encrypted)
def prepare_encrypted_message(self): message = '{0}:{1}:{2}'.format(self.name, self.index, hash_n_times(self.h_0, self.K - self.index)) self.cipher = Cipher(self.key) return self.cipher.encrypt(message)