def send(self, filename, receiver='Bob'): with CQCConnection(self.name) as self.cqc: self.cqc.closeClassicalServer() self.receiver = receiver self.receiver_pkey = auth.get_public_key(receiver) f = open(filename, 'rb') message = f.read() f.close() self.n = len(message) * 8 self.N = math.ceil((4 + self.correctness_param) * self.n) + 25 communication.send_message( self.cqc, self.receiver, self.skey, json.dumps({ 'n': self.n, 'security_param': self.security_param, 'correctness_param': self.correctness_param, 'filename': filename })) self._send_qubits() self._perform_basis_sift() can_continue = self._perform_error_estimation() if not can_continue: print('Not enough min entropy :(') return self._perform_error_correction() self._perform_privacy_amplification() cyphertext = self._encrypt(message) communication.send_binary_list(self.cqc, self.receiver, self.skey, cyphertext)
def _perform_error_estimation(self): print('Performing error estimation...', end='\r') error_estimation_indices = [] key_part = [] for i in range(0, self.n): r = random.randint(0, len(self.sifted_key) - 1) while r in error_estimation_indices: r = random.randint(0, len(self.sifted_key) - 1) error_estimation_indices.append(r) key_part.append(self.sifted_key[r]) communication.send_message(self.cqc, self.receiver, self.skey, error_estimation_indices) communication.send_binary_list(self.cqc, self.receiver, self.skey, key_part) receiver_key_part = communication.receive_binary_list( self.cqc, self.receiver_pkey) num_errors = 0.0 for i in range(0, len(key_part)): if receiver_key_part[i] != key_part[i]: num_errors += 1.0 self.error_estimation = num_errors / len(key_part) print('Performing error estimation... Done!') print('Error rate = {}'.format(self.error_estimation)) error_estimation_indices.sort() self.sifted_key = utils.remove_indices(self.sifted_key, error_estimation_indices) remaining_bits = len(self.sifted_key) min_entropy = remaining_bits * (1 - utils.h(self.error_estimation)) max_key = min_entropy - 2 * utils.log(1 / self.security_param, 2) - 1 return self.n <= max_key
def _perform_error_estimation(self): # print('Performing error estimation...', end='\r') error_estimation_indices = communication.receive_list(self.cqc, self.sender_pkey) sender_key_part = communication.receive_binary_list(self.cqc, self.sender_pkey) num_errors = 0.0 key_part = [] for i in range(0, len(error_estimation_indices)): key_part.append(self.sifted_key[error_estimation_indices[i]]) if sender_key_part[i] != key_part[i]: num_errors += 1.0 communication.send_binary_list(self.cqc, self.sender, self.skey, key_part) self.error_estimation = num_errors / len(key_part) # print('B Performing error estimation... Done!') # print('B Error rate = {}'.format(self.error_estimation)) error_estimation_indices.sort() self.sifted_key = utils.remove_indices(self.sifted_key, error_estimation_indices) remaining_bits = len(self.sifted_key) min_entropy = remaining_bits * (1 - utils.h(self.error_estimation)) max_key = min_entropy - 2 * utils.log(1/self.security_param, 2) - 1 return self.n <= max_key
def _perform_basis_sift(self): # print("Performing Basis sift...", end='\r') receiver_basis = communication.receive_binary_list(self.cqc, self.sender_pkey) communication.send_binary_list(self.cqc, self.sender, self.skey, self.basis_list) diff_basis = [] for i in range(0, len(receiver_basis)): if receiver_basis[i] != self.basis_list[i]: diff_basis.append(i) self.sifted_key = utils.remove_indices(self.raw_key, diff_basis) self.sifted_basis = utils.remove_indices(self.basis_list, diff_basis)
def run_algorithm(self): n = math.ceil(0.73 / self.party.error_estimation) iterations = [[]] # 1st iteration for i in range(0, len(self.party.sifted_key), n): iterations[0].append( list(range(i, min(i + n, len(self.party.sifted_key) - 1)))) parities = utils.calculate_parities(self.party.sifted_key, iterations[0]) communication.send_binary_list(self.party.cqc, self.party.receiver, self.party.skey, parities) msg = communication.receive_message(self.party.cqc, self.party.receiver_pkey) while msg != 'ALL DONE': block_num = int(msg) self._binary(iterations[0][block_num]) msg = communication.receive_message(self.party.cqc, self.party.receiver_pkey) # nth iteration for iter_num in range(1, 4): n = 2 * n iterations.append([]) # Choose function fi [1...n] -> [1...n/ki], send and save in iterations[iter_num] temp_indices = list(range(0, len(self.party.sifted_key))) random.shuffle(temp_indices) communication.send_message(self.party.cqc, self.party.receiver, self.party.skey, temp_indices) for i in range(0, len(self.party.sifted_key), n): iterations[iter_num].append( temp_indices[i:min(i + n, len(self.party.sifted_key) - 1)]) parities = utils.calculate_parities(self.party.sifted_key, iterations[iter_num]) communication.send_binary_list(self.party.cqc, self.party.receiver, self.party.skey, parities) msg = communication.receive_message(self.party.cqc, self.party.receiver_pkey) while msg != 'ALL DONE': iter_num, block_num = json.loads(msg) self._binary(iterations[iter_num][block_num]) msg = communication.receive_message(self.party.cqc, self.party.receiver_pkey) print(self.party.sifted_key)
def _perform_privacy_amplification(self): seed_col, seed_row = self._generate_seed() communication.send_binary_list(self.cqc, self.receiver, self.skey, seed_col + seed_row) self.final_key = matmul(toeplitz(seed_col, seed_row), self.sifted_key)