def division(divident, divisor): remainder = BitVector(intVal=1, size=32) quotient = BitVector(size=32) print("divident:", divident) print("divisor: ", divisor) print("Step by step calculation:") print("Searching for the first 1 in divident") i = 0 while not divident[i]: i += 1 print("Position of first 1:", i) print("Writing remainder as first half of result register") while i != len(divident): print(remainder, quotient) print("Checking if divisor is greater than remainder") if divisor >= remainder: print("If true, expanding remainder with next divident symbol") remainder.shift_left_by_one() remainder[-1] = divident[i + 1] else: print( "If false, subtracking divisor from remainder and shift remainder to the left" ) print("and set 1 in quotient in the according divident index") remainder = subtraction(remainder, divisor) remainder.shift_left_by_one() quotient[i - 32] = 1 i += 1 print("Final result:", remainder, quotient) print("Final result in decimal: quotient:", quotient.int_val(), ", remainder:", remainder.int_val())
def multiplication(multiplicand, multiplier): carry = 0 register = BitVector(intVal=multiplier.int_val(), size=64) print("Initial register:", register) for i in range(30, -1, -1): if register[-1]: for y in range(31, -1, -1): if carry: if register[y + 1] & multiplicand[y]: register[y + 1] = 1 carry = 1 elif register[y + 1] | multiplicand[y]: register[y + 1] = 0 carry = 1 else: register[y + 1] = 1 carry = 0 else: if register[y + 1] & multiplicand[y]: register[y + 1] = 0 carry = 1 elif register[y + 1] | multiplicand[y]: register[y + 1] = 1 else: register[y + 1] = 0 print("Add multiplicand to register:", register) print("Shift register by one:", register) register.shift_right_by_one() print("Final result:", register) print("Final result in decimal:", register.int_val())
def multiplication(multiplicand, multiplier): carry = 0 register = BitVector(intVal=multiplier.int_val(), size=64) print("Початковий регістр:", register) for i in range(30, -1, -1): if register[-1]: for y in range(31, -1, -1): if carry: if register[y + 1] & multiplicand[y]: register[y + 1] = 1 carry = 1 elif register[y + 1] | multiplicand[y]: register[y + 1] = 0 carry = 1 else: register[y + 1] = 1 carry = 0 else: if register[y + 1] & multiplicand[y]: register[y + 1] = 0 carry = 1 elif register[y + 1] | multiplicand[y]: register[y + 1] = 1 else: register[y + 1] = 0 print("Додавання першого множника в регістр:", register) print("Здвиг регістру на один:", register) register.shift_right_by_one() print("Результат:", register) print("Результат у десятковому:", register.int_val())
def main(): f = BitVector(bitstring='0001111100000010000100') f[22 - 1 - 11] = 0 f_init = copy.deepcopy(f) key = 0xfaf3df3fa6698c0c frame_counter = f.int_val() a52 = A5_2(key, frame_counter) #print(a52.key) (send_key, receive_key) = a52.get_key_stream(True) f[22 - 1 - 11] = 1 f2_init = copy.deepcopy(f) frame_counter = f.int_val() a522 = A5_2(key, frame_counter) (send_key2, receive_key2) = a522.get_key_stream(True) r4 = copy.deepcopy(a52.initial_sates['r4']) solution_found = Event() perform_attack(r4, send_key, send_key2, f_init, f2_init, r4_given=True)
def check_gauss_solution(solutions, r4, k, f): """ Checks for each solution if it's valid. An A5/2 object is created and the registers are initialized with the values from the gauss solution. The generated key stream will be then compared to the key stream k. If it is the same, the solution is correct. Otherwise, the solution is not correct. :param solutions: List with solutions from the gauss algorithm :param r4: register 4 as LFSR object :param k: key stream to verify the solution :return the session key or None """ a52 = A5_2(0x0, 0x0) for solution in solutions: # r1_value, r2_value, r3_value = convert_solution_to_lfsrs(solution) # R1[15], R2[16] and R3[18] are always set to 1 in the A5/2 init # process.In order to restore the correct values, all combinations # must be checked for register_values in list(itertools.product([0, 1], repeat=3)): r1, r2, r3 = convert_solution_to_lfsrs(solution) (send_key, receive_key) = a52.get_key_stream_with_predefined_registers( str(r1.register), str(r2.register), str(r3.register), str(r4.register), generate_only_send_key=True) if send_key == k: r1.set_bit(FORCE_R1_BIT_TO_1, register_values[0]) r2.set_bit(FORCE_R2_BIT_TO_1, register_values[1]) r3.set_bit(FORCE_R3_BIT_TO_1, register_values[2]) reverse_frame_counter(r1, r2, r3, f) session_keys = retrieve_session_key(r1, r2, r3) for session_key in session_keys: session_key = BitVector(bitlist=session_key) if check_session_key(session_key.int_val(), f.int_val(), k): return session_key return None
class ImmediateConstant: """ An immediate constant. This class represents some sort of constant used as an immediate value by an instruction. Such constant can be a literal value or a symbolic one. Immediate formats can differ in size, so a size must be specified at creation time for faithful representation and correct manipulation of the binary value. :var symbol: the symbolic identifier of the constant, if any :var value: the binary representation of the value, if assigned :var int_val: the integer representation of the value, if assigned :var size: the size in bits of the containing immediate field """ _symbol: Optional[str] _value: Optional[BitVector] _size: int def __init__(self, size, symbol: str = None, value: int = None): """ Instantiate an immediate constant of the specified size and value, identified by a symbol. :param size: the size in bits of the constant :param symbol: the symbol identifying the constant, if any :param value: the integer value of the constant, if any :raise ValueError: when both symbol and value are left unspecified """ if symbol is None and value is None: raise ValueError("Constant must be symbolic or have a value") self._size = size self._symbol = symbol if value is not None: # Prepare the mask for cutting the supplied value's bit representation to the specified size mask = 0 for f in range(0, size): mask += 2**f value = value & mask self._value = BitVector(intVal=value, size=size) # Sizes must be coherent assert self._size == len(self._value) else: self._value = None @property def symbol(self) -> str: return self._symbol @property def value(self) -> BitVector: return self._value.deep_copy() @property def int_val(self) -> int: # Return the constant's integer representation, preserving its sign through an overly complicated procedure return -((~self._value).int_val() + 1) if self._value[0] == 1 else self._value.int_val() @property def size(self): return self._size def __repr__(self): return "Instruction.ImmediateConstant(size=" + repr(self._size) + ", symbol=" + repr(self._symbol) + \ ", value=" + repr(None if self._value is None else self.int_val) + ")" def __str__(self): return str(self.int_val) if self._symbol is None else self.symbol
def initiate_keygen(key_size=32, name="Alice", recipient="Bob", acceptable_error=0.5, q_logger=print): length = 3 * key_size q_logger("Begginning key initialization with {}".format(recipient)) with get_CQCConnection(name) as conn: q_logger("init Connection made") # Send bob key length q_logger("sending length") conn.sendClassical(recipient, length) q_logger("Length sent, awaiting confirmation") confirmation = int.from_bytes(conn.recvClassical(), byteorder="big") q_logger("recieved length conformation") # Get key, encode key, send to bob key, qubits, bases = create_master_key(conn, length) key_bit_vect = BitVector(intVal=key) q_logger("Key: {}".format(bin(key))) q_logger("Bases: {}".format(bin(int(bases)))) # Send all the qubits sequentially for q in qubits: conn.sendQubit(q, recipient) q_logger("sent qubits!") # receive bases used by Bob bobs_bases = BitVector(bitlist=conn.recvClassical()) q_logger("Bobs bases: {}".format(bin(bobs_bases.int_val()))) correct_bases = ~bobs_bases ^ bases correctness = correct_bases.count_bits() / length q_logger("Correct: {}".format(bin(int(correct_bases)))) q_logger(correctness) # Send bob correct bases conn.sendClassical(recipient, correct_bases[:]) key = truncate_key(key, length, correct_bases) if validate_generated_key(length, acceptable_error, key) != OK: raise PoorErrorRate( "Poor error rate: {}".format(1 - (len(key) / length))) exit(0) expected_verify, key = break_into_parts(key, key_size) verification_bits = BitVector(bitlist=conn.recvClassical()) q_logger("Comparing verification bits") if expected_verify == verification_bits: q_logger("Verification bits OK") conn.sendClassical(recipient, OK) else: q_logger("Bits Tampered") conn.sendClassical(recipient, TAMPERED) if conn.recvClassical() != OK: # raise exception pass return key