예제 #1
0
class MasterKey(object):
    def __init__(self, master_key_hex_string="0x3cc849279ba298b587a34cabaeffc5ecb3a044bbf97c516fab7ede9d1af77cfa"):
        self.key = BitArray(master_key_hex_string)
        self.session_keys_amount = 8
        self.current_cycle_index = 0
        self.master_key_round_shift_bits = 24

    def get_round_keys(self):
        """


        :return: list of round keys
        :rtype: list[RoundKey]
        """
        if self.current_cycle_index:
            round_master_key = self.key.copy()
            round_master_key.ror(self.master_key_round_shift_bits * self.current_cycle_index)
        else:
            round_master_key = self.key.copy()
        round_keys = []
        round_key_size = round_master_key.length / self.session_keys_amount
        for key_index in range(0, self.session_keys_amount):
            round_key = round_master_key[key_index * round_key_size:key_index * round_key_size + round_key_size]
            round_keys.append(RoundKey(round_key))
        if self.current_cycle_index < 8:
            self.current_cycle_index += 1
        else:
            self.current_cycle_index = 0
        return round_keys
예제 #2
0
    def stop_packet(direction=1, soft_stop=False, ignore_direction=True):
        """
        Build a stop packet for all decoders.

        param direction sets the direction bit in the packet.
        param soft_stop indicates if the decoder bring the locomotive to stop
                        or stop delivering energy to the engine (guess in
                        the first case it may gradually decelerate it)
        param ignore_direction allows optionally ignoring the direction bit
                               for all direction sensitive functions
        """
        byte_one = BitArray('0b00000000')
        byte_two = BitArray('0b01')
        if direction:
            byte_two.append('0b1')
        else:
            byte_two.append('0b0')
        if ignore_direction:
            byte_two.append('0b1')
        else:
            byte_two.append('0b0')

        byte_two.append('0b000')

        if soft_stop:
            byte_two.append('0b0')
        else:
            byte_two.append('0b1')

        byte_three = byte_two.copy()
        return DCCGeneralPacket(byte_one, [byte_two, byte_three])
 def testCopyMethod(self):
     s = BitArray(9)
     t = s.copy()
     self.assertEqual(s, t)
     t[0] = True
     self.assertEqual(t.bin, '100000000')
     self.assertEqual(s.bin, '000000000')
예제 #4
0
    def _walk_tree(node, current: BitArray = BitArray()) -> Dict[str, BitArray]:
        """
        Walk the Huffman Tree, constructing a dictiary of their associated bit arrays
        """
        if node.data is not None:
            return {node.data: current}

        else:
            left_array: BitArray = current.copy()
            left_array.append('0b0')
            right_array: BitArray = current.copy()
            right_array.append('0b1')
            result: Dict[str, BitArray] = {}
            result.update(HuffmanTree._walk_tree(node.left, left_array))
            result.update(HuffmanTree._walk_tree(node.right, right_array))
            return result
예제 #5
0
def test_bitstring_extraction():
    secret_bytes = SECRET.encode()
    secret_bit = BitArray(bytes=secret_bytes, length=len(secret_bytes) * 8)
    print(secret_bit.bin)
    print("Length of bits original secret: %d" % len(secret_bit))

    checksum_bit = BitArray(uint=binascii.crc32(secret_bit.bytes),
                            length=CRC_LENGTH)
    print(checksum_bit.bin)
    print(len(checksum_bit))

    # join secret bitstring with CRC
    total_bit = secret_bit.copy()
    total_bit.append(checksum_bit)
    print('Length total bit: {}'.format(len(total_bit)))

    coefficients = []
    assert len(total_bit) % 13 == 0
    step = int(len(total_bit) / 13)
    for i in range(0, len(total_bit), step):
        coefficients.append(total_bit[i:i + step].uint)
    print(coefficients)
    PolynomialExtractor.check_crc_in_poly(coefficients, POLY_DEGREE,
                                          CRC_LENGTH)

    poly = [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 69, 67, 82, 69, 84, 46, 46, 46,
        201, 112, 67, 73
    ]
    print(PolynomialExtractor.check_crc_in_poly(poly, POLY_DEGREE, CRC_LENGTH))
예제 #6
0
    def encrypt_public(self, message):
        m = BitArray(message.encode("latin-1"))
        n = self.n
        h = self.h
        t = int(m.length / h)
        mb = m.bin
        low = 0
        up = h
        r = random.randint(1, n)
        xp = pow(r, 2, n)

        first = True
        for i in range(t):
            xp = pow(xp, 2, n)
            p = BitArray('0b' + bin(xp)).bin[0 - h:]
            c = BitArray('0b' + p)
            c ^= BitArray('0b' + mb[low:up])
            if first:
                first = False
                ctext = c.copy()
            else:
                ctext.append(c)
            low += h
            up += h

        return (ctext.bytes.decode("latin-1"), pow(xp, 2, n))
예제 #7
0
 def testCopyMethod(self):
     s = BitArray(9)
     t = s.copy()
     self.assertEqual(s, t)
     t[0] = True
     self.assertEqual(t.bin, '100000000')
     self.assertEqual(s.bin, '000000000')
예제 #8
0
    def stop_packet(direction=1,
                    soft_stop=False,
                    ignore_direction=True):
        """
        Build a stop packet for all decoders.

        param direction sets the direction bit in the packet.
        param soft_stop indicates if the decoder bring the locomotive to stop
                        or stop delivering energy to the engine (guess in
                        the first case it may gradually decelerate it)
        param ignore_direction allows optionally ignoring the direction bit
                               for all direction sensitive functions
        """
        byte_one = BitArray('0b00000000')
        byte_two = BitArray('0b01')
        if direction:
            byte_two.append('0b1')
        else:
            byte_two.append('0b0')
        if ignore_direction:
            byte_two.append('0b1')
        else:
            byte_two.append('0b0')

        byte_two.append('0b000')

        if soft_stop:
            byte_two.append('0b0')
        else:
            byte_two.append('0b1')

        byte_three = byte_two.copy()
        return DCCGeneralPacket(byte_one, [byte_two, byte_three])
예제 #9
0
def divide(dividend, divisor):
    # dividend ÷ divisor = quotient
    #HI = Remainder
    #LO = Quoitent
    print(dividend," / ", divisor)
    LO = BitArray(int = dividend, length = 32)#LO = Dividend
    print("quoitent = ", LO.bin)
    HI = BitArray(int = 0, length = 32)#HI = 0
    print("remainder = ", HI.bin)
    for _ in range(32):
        req = HI.copy()
        req.append(LO)
        req <<= 1
        LO = req[32:]
        print("quoitent << 1 ",LO.bin)
        HI = req[:32]
        print("remainder << 1 ",HI.bin)
        diff = HI.int - divisor
        if diff >= 0:
            print("diff > 0")
            HI = BitArray(int = diff, length = 32)
            print("remainder = ",HI.bin)
            LO.set(True, -1)#set lsb of LO as 1
            print("quoitent = ", LO.bin)
    print("remainder = ", HI.int)
    print("quoitent = ", LO.int)
    print("res = ",LO.int,"+",HI.int,"/", divisor, " = ", LO.int+HI.int/divisor)
예제 #10
0
def hamming_search(b, bit, radius, current_radius, H):
    if current_radius == 0:
        H[current_radius].append(b.copy())

    if current_radius == radius:
        return
    for i in range(bit+1, b.length):
        b2 = BitArray(b.copy())
        b2.invert(i)
        H[current_radius+1].append(b2.copy())
        hamming_search(b2, i, radius, current_radius+1, H)
예제 #11
0
    def split(self, A):
        IG_list = []
        A_count = float(A.count(True))
        p_A = self.prob(A)
        e_A = self.entropy(p_A)
        # Get decision for node
        if p_A >= 0.5:
            d = 1
        else:
            d = 0
        # Check entropy of node
        if e_A < 0.3:
            print "Node entropy is low enough:", e_A
            return None,None,d,None,None
        # Check # elements
        if A_count < self.count_thresh:
            print "Node has few elements:", A_count
            return None,None,d,None,None

        F = self.X.T
        for f in range(len(F)):
            # Sort the relevant column and keep indices
            indices = F[f].argsort()
            pairs = zip(indices, F[f][indices])
            s = len(pairs)*'0'
            B = BitArray(bin=s)
            C = A.copy()
            i = 0
            IG_prev = 0.0
            # Threshold emulator loop
            while i < len(pairs)-1:
                if A[pairs[i][0]]:
                    B[pairs[i][0]] = 1
                    C[pairs[i][0]] = 0
                    if pairs[i][1] < pairs[i+1][1]:
                        t = pairs[i+1][1]
                        # Calculate information gain for the split
                        IG_curr,s_B,s_C = self.info_gain(B,C,e_A,A_count)
                        #print IG_curr
                        if IG_curr < IG_prev:
                            break
                        else:
                            IG_prev = IG_curr
                        # Check if entropy for any branches is below thresh
                        IG_list.append((IG_curr,f,t,d,B.copy(),C.copy(),s_B,s_C))
                i += 1

        if IG_list == []:
            #print "Boring decision..."
            return None,None,d,None,None
        else:
            max_val = max(IG[0] for IG in IG_list)
            IG,f,t,d,B,C,s_B,s_C = [IG for IG in IG_list if IG[0] == max_val][0]
            return f,t,d,B,C
예제 #12
0
def hamming_search(b, bit, radius, current_radius, H):
    if current_radius == 0:
        H[current_radius].append(b.copy())

    if current_radius == radius:
        return
    for i in range(bit + 1, b.length):
        b2 = BitArray(b.copy())
        b2.invert(i)
        H[current_radius + 1].append(b2.copy())
        hamming_search(b2, i, radius, current_radius + 1, H)
def build_bitmaps_1(given, implied, nrAttributes):

    m = BitArray('0b'+'0'*2**nrAttributes)
    n = m.copy()
    n.invert()

    for j in range(nrAttributes):
        b = m.copy()
        step = 2**(j)
        a1=0
        a2=a1+step
        for i in range(0,32,step):
            b[a1:a2] = n[a1:a2]
            a1=a2+step
            a2=a1+step
        given.append(b[:])

    for j in range(nrAttributes):
        implied.append(given[j].copy())

    for j in range(nrAttributes):
        implied[j].invert()
예제 #14
0
def Hmac(K, m):
    """ Computes the HMAC.
    Args:
      K: String representation of the key.
      m: String representation of the message.
    Returns:
      The computed HMAC. """
    key = BitArray(K.encode("latin-1"))
    mess = BitArray(m.encode("latin-1"))

    #shortens key if its larger than the block size of SHA1
    if (len(key.bin) > 512):
        key = BitArray(SHA1(key))

    #pads the key to the size of a block in SHA1
    if (len(key.bin) < 512):
        temp = BitArray('0b' + '0' * (512 - len(key.bin)))
        key.append(temp)

    #the outer pad
    opad = BitArray('0x5c')
    opad *= 64
    o_key_pad = key.copy()
    o_key_pad ^= opad

    #the inner pad
    ipad = BitArray('0x36')
    ipad *= 64
    i_key_pad = key.copy()
    i_key_pad ^= ipad

    #pads the message with two hashes
    result = i_key_pad.copy()
    result.append(mess)
    result = BitArray(SHA1(result))
    temp = o_key_pad.copy()
    temp.append(result)

    return SHA1(temp).bytes.decode("latin-1")
예제 #15
0
    def split(self, A):
        gain_list = []
        A_count = float(A.count(True))
        d = self.mean(A)

        if A_count <= self.count_thresh:
            print "Node has few elements:", A_count
            return None,None,d,None,None
        mse_A = self.mse([A])
        #print "Curr mse:",mse_A

        F = self.X.T
        for f in range(len(F)):
            #print f
            # Sort the relevant column and keep indices
            indices = F[f].argsort()
            pairs = zip(indices, F[f][indices])
            s = len(pairs)*'0'
            B = BitArray(bin=s)
            C = A.copy()
            i = 0
            # Threshold emulator loop
            while i < len(pairs)-1:
                if A[pairs[i][0]]:
                    B[pairs[i][0]] = 1
                    C[pairs[i][0]] = 0
                    if pairs[i][1] < pairs[i+1][1]:
                        t = pairs[i+1][1]
                        # Calculate MSE for the split
                        mse_curr = self.mse([B,C])
                        gain_curr = mse_A - mse_curr
                        # Check if entropy for any branches is below thresh
                        gain_list.append((gain_curr,f,t,d,B.copy(),C.copy(),mse_A,mse_curr))
                i += 1

        if gain_list == []:
            print "mse_list empty"
        #    return None,None,d,None,None
        else:
            max_val = max(mse[0] for mse in gain_list)
            gain,f,t,d,B,C,mse_A,mse_curr = [mse for mse in gain_list if mse[0] == max_val][0]
            if mse_curr <= 1.0:
                return None,None,d,None,None
            else:
                print "Gain:",mse_A,mse_curr
                return f,t,d,B,C
예제 #16
0
def evaluate_expr(expr, wordsIndex):
    """Evaluate the expression using the logical 
        operations from BitArray.
        The expression must've been split in tokens.
    """
    # Init variables
    result = BitArray(wordsIndex.files_count)
    initialised = False
    currentBits = BitArray(wordsIndex.files_count)
    negate = False
    state = ''

    iterator = enumerate(expr)
    for i, token in iterator:
        if token == '!':
            negate = True
            continue
        if re.match(OPERATORS, token):
            state = token
            continue

        if token == '(':
            closing_index = i + find_closing_paranthesis(expr[i:])
            # Evaluate the expression between the parantheses
            currentBits = evaluate_expr(expr[i + 1:closing_index],
                                        wordsIndex).copy()
            # Jump with the iterator after the closing parantheses
            consume(iterator, closing_index - i)

        if is_word(token):
            if token in wordsIndex:
                currentBits = wordsIndex[token].copy()
            # Just ignore the stopwords
            elif token in STOPWORDS:
                negate = False
                currentBits = result.copy()
            else:
                # No match for the current word; Make all the bits 0
                currentBits = BitArray(wordsIndex.files_count)

        result = apply_operator(result, currentBits, negate, state)
        negate = False
        state = None

    return result
class GifDataStream:
    def __init__(self, bytez):
        self.bytez = bytearray(bytez)
        self.remainder = BitArray()

    def read_uint(self, n):
        while len(self.remainder) < n:
            self.remainder.prepend(Bits(bytearray([self.bytez.pop(0)])))
        uint = self.remainder.uint & (2**n - 1)
        self.remainder >>= n
        del self.remainder[0:n]
        return uint

    def peek_uint(self, n):
        s = self.remainder.copy()
        i = 0
        while len(s) < n:
            s.prepend(Bits(bytearray(self.bytez[i:i + 1])))
            i += 1
        bits = Bits(s)
        return bits.uint & (2**n - 1)
예제 #18
0
args = parser.parse_args()

if (len(args.command) != 12):
    print('command is wrong length')
    my_command = 'aXY1CT20F100'
else:
    my_command = args.command

in_preamble = BitArray('0b00000')
in_device1 = BitArray('0xd70000c50027da11')
in_device2 = BitArray('0x641000420027da11')
in_params = BitArray('0xf40080c1002060060000b0002249000027da11')
in_list = [in_preamble, in_device1, in_device2, in_params]

#in_list[3].reverse()
in_first = in_params.copy()

print(in_list[0].bin)
print(in_list[1].hex)

print(in_list[2].hex)
print(in_list[3].hex)
#print(in_list[3].bin)

in_list[0].clear()
in_list[1].clear()
in_list[2].clear()
in_list[3].clear()

with open(args.input, 'r') as raw_file:
    A_list1 = []
예제 #19
0
class PolynomialGenerator:
    def __init__(self, secret_bytes, degree, crc_length, gf_exp):
        """
        :param secret_bytes: secret in bytes format
        :param degree: polynomial degree as int
        :param crc_length: CRC length as int
        :param gf_exp: exponential in GF(2**gf_exp)
        """
        self.degree = degree
        self.crc_length = crc_length
        self.secret_bit = BitArray(bytes=secret_bytes, length=len(secret_bytes) * 8)
        self.gf_exp = gf_exp

        self.checksum_bit = BitArray(uint=binascii.crc32(self.secret_bit.bytes), length=self.crc_length)

        # join secret bitstring with CRC
        self.total_bit = self.secret_bit.copy()
        self.total_bit.append(self.checksum_bit)

        self.coefficients = self.extract_coefficients()
        # save polynomial in GF 2**32 form for performance reasons
        self.poly_gf_32 = GaloisConverter.convert_int_list_to_gf_2_list(self.coefficients, 32)
        # save galois field K for polynomial evaluations
        self.K = GF(2, gf_exp)

    def prune_secret(self, secret_bit):
        """ Prunes secret if secret length + CRC length is not multiple of
            polynomial degree + 1. Takes secret as BitArray
            :returns pruned secret as Bitarray """
        # check if bitstring has multiple of length of polynomial degree
        # secret is pruned if length don't match multiple of polynomial degree + 1
        remainder = (len(secret_bit) + self.crc_length) % (self.degree + 1)
        secret_len = len(secret_bit) - remainder
        if remainder == 0:
            return secret_bit
        else:
            return secret_bit[0:secret_len]

    def extract_coefficients(self):
        """ extracts coefficients of polynomial from bitstring
            :returns coefficients as list """
        # split to parts, convert to uint and add to list
        coefficients = []
        assert len(self.total_bit) % (self.degree + 1) == 0
        step = int(len(self.total_bit) / (self.degree + 1))
        for i in range(0, len(self.total_bit), step):
            # print(len(self.total_bit[i:i + step]))
            # print(self.total_bit[i:i + step].bin)
            # print(self.total_bit[i:i + step].uint)
            coefficients.append(self.total_bit[i:i + step].uint)
        return coefficients

    def evaluate_polynomial_gf_2(self, x):
        """ Evaluate polynomial of this polynomial generator at x in GF(2**m)
            :param x: int
            :param m: exponential in GF(2**m)
            :returns function result as int """
        m = self.gf_exp
        if m == 32:
            poly_gf = self.poly_gf_32
        else:
            poly_gf = GaloisConverter.convert_int_list_to_gf_2_list(self.coefficients, m)
        x_gf = GaloisConverter.convert_int_to_element_in_gf_2(x, m)
        y_gf = self.K.eval_poly(poly_gf, x_gf)
        result = GaloisConverter.convert_gf_2_element_to_int(y_gf, m)
        # Safety check
        if result > 2**m*2:
            raise ValueError('Too large number generated in polynomial GF(2**{}):{}'.format(m, result))
        return result

    def evaluate_polynomial_gf_2_array(self, array):
        """ Evaluate polynomial on list of integers
            :param array: list of integers
            :param m: exponential in GF(2**m) """
        result = []
        for x in array:
            result.append(self.evaluate_polynomial_gf_2(x))
        return result
예제 #20
0
파일: filemgr.py 프로젝트: Jeeway/bt
class FileMgr(object):
    def __init__(self, metainfo):
        self._metainfo = metainfo
        self._have = BitArray(self._metainfo.num_pieces)

        directory = metainfo.directory
        if directory != "":
            try:
                if not os.path.exists(directory):
                    os.makedirs(directory)
            except OSError as err:
                if err.errno != errno.EEXIST:
                    raise

        files = metainfo.files

        # _files is a list of files in the torrent.  Each entry is a
        # tuple containing the file descriptor, length of the file and
        # offset of the file within the torrent
        self._files = []

        offset = 0
        subdirs = []
        for path, length in files:
            dirname = directory + "/".join(path[0:-1])

            if dirname != "" and dirname not in subdirs:
                subdirs.append(dirname)
                try:
                    if not os.path.exists(dirname):
                        os.makedirs(dirname)
                except OSError as err:
                    if err.errno != errno.EEXIST:
                        raise

            if dirname == "":
                filename = path[-1]
            else:
                filename = dirname + "/" + path[-1]

            try:
                open(filename, "a").close()
                fd = open(filename, "rb+")
            except IOError:
                logger.critical("Unable to open file {}".format(filename))
                raise

            self._files.append((fd, length, offset))
            offset += length

    def _file_index(self, offset):
        for i, (fd, length, begin) in enumerate(self._files):
            if offset >= begin and offset < begin + length:
                return i

    def have(self):
        return self._have.copy()

    def write_block(self, piece_index, offset_in_piece, buf, file_index=None):
        offset_in_torrent = piece_index * self._metainfo.piece_length + offset_in_piece

        if file_index is None:
            file_index = self._file_index(offset_in_torrent)
        fd, file_length, file_offset_in_torrent = self._files[file_index]
        offset_in_file = offset_in_torrent - file_offset_in_torrent
        fd.seek(offset_in_file)
        if len(buf) <= file_length - offset_in_file:
            fd.write(buf)
            fd.flush()
        else:
            to_write = file_length - offset_in_file
            fd.write(buf[:to_write])
            fd.flush()
            self.write_block(piece_index, offset_in_piece + to_write, buf[to_write:], file_index + 1)
예제 #21
0
    def split(self, A):
        gain_list = []
        A_count = float(A.count(True))
        d = self.mean(A)

        if A_count <= self.count_thresh:
            #print "Node has few elements:", A_count
            return None,None,d,None,None
        mse_A = self.mse([A])
        #if mse_A <= 15:
        #    print "Node has small MSE:", mse_A
        #    return None,None,d,None,None
        print "Elem, MSE:",A_count,mse_A

        F = self.X.T
        for f in range(len(F)):
            #print f
            # Sort the relevant column and keep indices
            indices = F[f].argsort()
            pairs = zip(indices, F[f][indices])
            s = len(pairs)*'0'
            B = BitArray(bin=s)
            C = A.copy()
            i = 0
            gain_prev = 0.0
            # Threshold emulator loop
            while i < len(pairs)-1:
                if A[pairs[i][0]]:
                    B[pairs[i][0]] = 1
                    C[pairs[i][0]] = 0
                    if pairs[i][1] < pairs[i+1][1]:
                        t = pairs[i+1][1]
                        # Calculate MSE for the split
                        mse_curr = self.mse([B,C])
                        gain_curr = mse_A - mse_curr
                        if gain_curr < 0:
                            print gain_curr
                        #print mse_curr
                        if gain_curr < gain_prev:
                            pass
                            #break
                        else:
                            gain_prev = gain_curr
                        # Check if entropy for any branches is below thresh
                        if B.count(True) == 0 or C.count(True) == 0:
                            pass
                        else:
                            gain_list.append((gain_curr,f,t,d,B.copy(),C.copy(),mse_A,mse_curr))
                i += 1

        if gain_list == []:
            print "mse_list empty"
            return None,None,d,None,None
        else:
            max_val = max(mse[0] for mse in gain_list)
            gain,f,t,d,B,C,mse_A,mse_curr = [mse for mse in gain_list if mse[0] == max_val][0]
            if B.count(True) == 0 or C.count(True) == 0:
                print "Count of B or C = 0:",B.count(True), C.count(True)
                for elem in gain_list:
                    print elem[4].count(True), elem[5].count(True)
                print
                return None,None,d,None,None
            else:
                return f,t,d,B,C
예제 #22
0
파일: genes.py 프로젝트: GenixPL/AI-Tetris
class Genes:
    """
	This class is responsible for abstracting and taking care of genes.

	The idea behind chromosome array is that it consists of bits representing reactions to different situations on board.
		We have 1,048,576 possible situations on board (in upper two rows with tetrominoes) and 7 different tetromino
		types. We have to choose position and number of rotations of tetromino for each situation. We have 4 possible
		rotations and 7 possible tetromino shapes.
		Array will be constructed in such a way, that:
			42 bits will represent all possible reactions to given situations on board
				42b = 6b * 7
				6b = 2b for rotation + 4b for position
				7 is a number of possible tetrominoes

			and the whole array will have 44,040,192 bits = 5.25 MB
				42 * 1,048,576
				42 possible reaction to each situations
				1,048,576 situations
	"""

    # number of possible different situations in first two rows in which tetrominoes are <0,10448575>
    SITUATIONS_NUM: int = 1048576
    # number of possible tetromino rotations <0,3>
    ROTATIONS_NUM: int = 4
    # number of possible different tetrominoes <0,6>
    TETROMINOES_NUM: int = 7
    # number of possible positions for x coordinate of left tetromino's side <0,9>
    POSITIONS_NUM: int = 10

    # number of bits needed to encode possible rotations
    ROTATION_BITS_LEN: int = 2
    # number of bits needed to encode possible positions
    POSITION_BITS_LEN: int = 4
    # number of bits needed to encode possible reactions to given tetromino in given situation
    TETROMINO_BITS_LEN: int = ROTATION_BITS_LEN + POSITION_BITS_LEN
    # number of bits needed to encode possible reactions to all tetrominoes in given situation
    SITUATION_BITS_LEN: int = TETROMINO_BITS_LEN * TETROMINOES_NUM

    # length of the whole chromosome
    CHROMOSOME_LEN: int = SITUATION_BITS_LEN * SITUATIONS_NUM

    # used to init random chromosome
    MAX_INT_REPRESENTING_CHROMOSOME = (2**(SITUATIONS_NUM *
                                           SITUATION_BITS_LEN)) - 1

    #
    @classmethod
    def get_random(cls):
        """
		Creates new Gene with random chromosome.

		:return: new Gene object with random chromosome
		"""

        new = Genes()
        init = randint(0, cls.MAX_INT_REPRESENTING_CHROMOSOME)
        new.chromosomes = BitArray(uint=init, length=cls.CHROMOSOME_LEN)

        return new

    @classmethod
    def from_file(cls, file: str):
        """
		Creates new Gene with chromosome read from file.

		:param file: path to file from which chromosome will be read
		:return: new Gene object with chromosome read from file
		"""

        new = Genes()
        new.chromosomes = BitArray(filename=file)

        return new

    def __init__(self):
        """
		Creates new Gene object with chromosome composed of zeros and with proper length.
		"""

        self.chromosomes = BitArray(length=self.CHROMOSOME_LEN)

    def copy(self):
        """
		Returns new Gene object being copy of self
		:return: new Gene object
		"""

        new = Genes()
        new.chromosomes = self.chromosomes.copy()

        return new

    #
    def get_rotation(self, situation: BitArray, tetromino_num: int):
        """
		Returns number of rotations for given tetromino in given situation

		:param situation: BitArray object representing situation in two upper rows with tetrominoes
		:param tetromino_num: int representing number of shape of tetromino
		:return: int representing number of rotations for given tetromino in given situation
		"""

        reaction = self.__get_reaction(situation, tetromino_num)

        starting_point = 0
        ending_point = self.ROTATION_BITS_LEN

        return reaction[starting_point:ending_point].uint

    def get_position(self, situation: BitArray, tetromino_num: int):
        """
		Returns position for given tetromino in given situation

		:param situation: BitArray object representing situation in two upper rows with tetrominoes
		:param tetromino_num: int representing number of shape of tetromino
		:return: int representing position for given tetromino in given situation
		"""

        reaction = self.__get_reaction(situation, tetromino_num)

        starting_point = self.ROTATION_BITS_LEN
        ending_point = starting_point + self.POSITION_BITS_LEN

        return reaction[starting_point:ending_point].uint % self.POSITIONS_NUM

    def mutate(self):
        """
		Mutates chromosome by taking random number of mutations (0, max number of mutation from config) and
			mutating random rotation and other random position given number of times
		"""

        max_mutations_num = get_mutations_num()
        mutations_num = randint(0, max_mutations_num)

        for i in range(mutations_num):
            self.__mutate_rotation(
                Genes.__get_situation_from_number(
                    randint(0, self.SITUATIONS_NUM - 1)))
            self.__mutate_position(
                Genes.__get_situation_from_number(
                    randint(0, self.SITUATIONS_NUM - 1)))

    #
    @staticmethod
    def __get_situation_from_number(situation_num: int):
        """
		Creates BitArray object representing situation from int representing situation
		TODO: "Situation" should be moved to separate class

		:param situation_num: int representing situation
		:return: new BitArray object representing situation
		"""

        return BitArray(uint=situation_num, length=20)

    def __set_rotation(self, situation: BitArray, tetromino_num: int,
                       rotations_num: int):
        """
		Sets number of rotations for given tetromino in given situation.

		:param situation: situation in which tetromino's number of rotations will be set
		:param tetromino_num: number representing shape of tetromino
		:param rotations_num: number of rotations
		"""

        if rotations_num > 3:
            raise ValueError("Rotations are in range <0, 3>, not " +
                             str(rotations_num))

        first_rotation_index = self.__get_reaction_index(
            situation, tetromino_num)

        if rotations_num == 0:
            self.chromosomes[first_rotation_index] = 0
            self.chromosomes[first_rotation_index + 1] = 0
        elif rotations_num == 1:
            self.chromosomes[first_rotation_index] = 0
            self.chromosomes[first_rotation_index + 1] = 1
        elif rotations_num == 2:
            self.chromosomes[first_rotation_index] = 1
            self.chromosomes[first_rotation_index + 1] = 0
        elif rotations_num == 3:
            self.chromosomes[first_rotation_index] = 1
            self.chromosomes[first_rotation_index + 1] = 1

    def __set_position(self, situation: BitArray, tetromino_num: int,
                       position: int):
        """
		Sets position for given tetromino in given situation.

		:param situation: situation in which tetromino's position will be set
		:param tetromino_num: number representing shape of tetromino
		:param position: int representing position
		"""

        if position > 9:
            raise ValueError("Positions are in range <0, 9>, not " +
                             str(position))

        first_position_index = self.__get_reaction_index(
            situation, tetromino_num) + self.ROTATION_BITS_LEN

        if position == 0:
            self.chromosomes[first_position_index] = 0
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 0
        elif position == 1:
            self.chromosomes[first_position_index] = 1
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 0
        elif position == 2:
            self.chromosomes[first_position_index] = 0
            self.chromosomes[first_position_index + 1] = 1
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 0
        elif position == 3:
            self.chromosomes[first_position_index] = 1
            self.chromosomes[first_position_index + 1] = 1
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 0
        elif position == 4:
            self.chromosomes[first_position_index] = 0
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 1
            self.chromosomes[first_position_index + 3] = 0
        elif position == 5:
            self.chromosomes[first_position_index] = 1
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 1
            self.chromosomes[first_position_index + 3] = 0
        elif position == 6:
            self.chromosomes[first_position_index] = 0
            self.chromosomes[first_position_index + 1] = 1
            self.chromosomes[first_position_index + 2] = 1
            self.chromosomes[first_position_index + 3] = 0
        elif position == 7:
            self.chromosomes[first_position_index] = 1
            self.chromosomes[first_position_index + 1] = 1
            self.chromosomes[first_position_index + 2] = 1
            self.chromosomes[first_position_index + 3] = 0
        elif position == 8:
            self.chromosomes[first_position_index] = 0
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 1
        elif position == 9:
            self.chromosomes[first_position_index] = 1
            self.chromosomes[first_position_index + 1] = 0
            self.chromosomes[first_position_index + 2] = 0
            self.chromosomes[first_position_index + 3] = 1

    def __mutate_rotation(self, situation: BitArray):
        """
		Mutates random rotation for given situation

		:param situation: BitArray representing situation
		"""

        tetromino_to_mutate = randint(0, 6)
        prev_rotation = self.get_rotation(situation, tetromino_to_mutate)
        new_rotation = (prev_rotation - 1) % self.ROTATIONS_NUM
        self.__set_rotation(situation, tetromino_to_mutate, new_rotation)

    def __mutate_position(self, situation: BitArray):
        """
		Mutates random position for given situation

		:param situation: BitArray representing situation
		"""

        tetromino_to_mutate = randint(0, 6)
        prev_position = self.get_rotation(situation, tetromino_to_mutate)
        new_position = (prev_position - 1) % self.POSITIONS_NUM
        self.__set_position(situation, tetromino_to_mutate, new_position)

    def __get_reaction(self, situation: BitArray, tetromino_num: int):
        starting_index = self.__get_reaction_index(situation, tetromino_num)
        ending_index = starting_index + self.TETROMINO_BITS_LEN

        return self.chromosomes[starting_index:ending_index]

    def __get_reaction_index(self, situation: BitArray, tetromino_num: int):
        situation_int = situation.uint

        return (situation_int * self.SITUATION_BITS_LEN) + (
            tetromino_num * self.TETROMINO_BITS_LEN)
예제 #23
0
class Message(object):
    def __init__(self, message_bit_array=BitArray(length=256)):
        """

        :param message_bit_array: message BitArray
        :type message_bit_array: BitArray
        """
        self.message_block_amount = 8
        self.normal_message_bits_amount = 256
        self.message_bit_array = message_bit_array
        self.message = self.message_bit_array.tobytes()
        self._normalize_message()

    @classmethod
    def get_message_from_message_blocks(cls, message_blocks):
        message_bit_array = BitArray()
        for message_block in message_blocks:
            message_bit_array.append(message_block.message_block)
        return Message(message_bit_array)

    def set_message_as_string(self, message_string):
        self.message = message_string
        self.message_bit_array = BitArray(self.message_to_hex(message_string))

    def message_to_hex(self, message_string):
        return '0x' + ''.join(x.encode('hex') for x in message_string)

    def _normalize_message(self):
        if self.message_bit_array.length > self.normal_message_bits_amount:
            self._trim_message()

    def _trim_message(self):
        self.message_bit_array = self.message_bit_array[0:self.normal_message_bits_amount]

    def get_message_blocks(self):
        message_bit_array = self.message_bit_array.copy()
        message_blocks = []
        message_block_size = self.normal_message_bits_amount / self.message_block_amount

        padding_blocks_amount = (
                                    self.normal_message_bits_amount - message_bit_array.length) / message_block_size
        padding_bits_amount = (self.normal_message_bits_amount - message_bit_array.length) % message_block_size
        if padding_bits_amount != 0:
            padding_block = BitArray('0b' + ''.join('0' for x in range(0, padding_bits_amount)))
            message_bit_array.prepend(padding_block)

        for padding_block_index in range(0, padding_blocks_amount):
            message_block = BitArray('0b00000000000000000000000000000000')
            message_blocks.append(MessageBlock(message_block))

        for message_block_index in range(0, self.message_block_amount - padding_blocks_amount):
            message_block = message_bit_array[
                            message_block_index * message_block_size:message_block_index * message_block_size + message_block_size]
            message_blocks.append(MessageBlock(message_block))
        return message_blocks


    def __unicode__(self):
        return self.message


    def __str__(self):
        return self.__unicode__()
예제 #24
0
class LDevice:
    # Обертка над C API
    def __init__(self, slot):
        self._closed = True
        err = ffi.new("unsigned int*")
        device = _dll.CreateLDevice(slot, err)
        err = err[0]

        if device == ffi.NULL:
            if err == 1:
                raise LDeviceError("CreateLDevice return L_NOTSUPPORTED")
            elif err == 2:
                raise LDeviceError("CreateLDevice return L_ERROR")
            elif err == 3:
                raise LDeviceError("CreateLDevice return L_ERROR_NOBOARD")
            elif err == 4:
                raise LDeviceError("CreateLDevice return L_ERROR_INUSE")
            else:
                raise AssertionError("Unknown error number {}".format(err))

        if _dll.OpenLDevice(device) == L_ERROR:
            _dll.ReleaseLDevice(device)
            raise LDeviceError("OpenLDevice error")

        self._closed = False

        self._impl = device
        self._ttl = BitArray(uint=0, length=16)

    def close(self):
        assert not self._closed
        self._closed = True

        print("Close LDevice")
        try:
            if _dll.CloseLDevice(self._impl) == L_ERROR:
                raise LDeviceError("CloseLDevice error")
        finally:
            _dll.ReleaseLDevice(self._impl)

    def __del__(self):
        if not self._closed:
            self.close()

    def plata_test(self):
        return _dll.PlataTest(self._impl) == L_SUCCESS

    def init_start(self):
        if _dll.InitStartLDevice(self._impl) == L_ERROR:
            raise LDeviceError("InitStartLDevice error")

    def start(self):
        if _dll.StartLDevice(self._impl) == L_ERROR:
            raise LDeviceError("StartLDevice error")

    def stop(self):
        if _dll.StopLDevice(self._impl) == L_ERROR:
            raise LDeviceError("StopLDevice error")

    def load_bios(self, filename):
        assert type(filename) == str
        filename = filename.encode("ascii")
        if _dll.LoadBios(self._impl, filename) == L_ERROR:
            raise LDeviceError("LoadBios error")

    def create_WASYNC_PAR(self):
        return ffi.new("WASYNC_PAR*")

    def io_async(self, WASYNC_PAR):
        if _dll.IoAsync(self._impl, WASYNC_PAR) == L_ERROR:
            raise LDeviceError("IoAsync error")

    def get_slot_param(self):
        sp = ffi.new("SLOT_PAR*")
        if _dll.GetSlotParam(self._impl, sp) == L_ERROR:
            raise LDeviceError("GetSlotParam error")
        return sp

    def enable_correction(self, val):
        assert type(val) == bool
        if _dll.EnableCorrection(self._impl, int(val)) == L_ERROR:
            raise LDeviceError("EnableCorrection error")

    # Пользовательские функции
    @property
    def ttl(self):
        return self._ttl

    def ttl_enable(self, enabled: bool):
        sp = self.create_WASYNC_PAR()
        sp.s_Type = L_ASYNC_TTL_CFG
        sp.Mode = int(enabled)
        self.io_async(sp)

    def ttl_write(self):
        sp = self.create_WASYNC_PAR()
        sp.s_Type = L_ASYNC_TTL_OUT
        ttl = self._ttl.copy()
        ttl.reverse()
        sp.Data[0] = ttl.uint
        self.io_async(sp)

    def ttl_read(self):
        sp = self.create_WASYNC_PAR()
        sp.s_Type = L_ASYNC_TTL_INP
        self.io_async(sp)
        ret = BitArray(uint=sp.Data[0], length=16)
        ret.reverse()
        return ret

    def adc_get(self, num):
        assert (num >= 0) and (num < 16)
        sp = self.create_WASYNC_PAR()
        sp.s_Type = L_ASYNC_ADC_INP
        sp.Chn[0] = num
        self.io_async(sp)

        value = Bits(uint=sp.Data[0], length=16)
        return value.int
예제 #25
0
def main():
    file = open(sys.argv[1], "rb")
    msg = ConstBitStream(file)

    s_in = BitArray()
    aux = BitArray()
    keys = ['']
    s_out = ''

    s_in.append(msg.read(1))
    aux = s_in.copy()
    aux.invert(0)
    count = 0

    #Encontrar o tamanho do padding
    while (s_in.bin) != aux.bin:
        try:
            count += 1
            s_in.clear()
            s_in.append(msg.read(1))

        except ReadError:
            break

    padding = BitArray()
    padding.append(s_in)

    s_in = BitArray()

    #Com o tamanho encontrar o padding correspondente
    padding.append(msg.read(count - 1))

    while True:
        n_bits = ceil(log2(len(keys)))

        try:
            s_in.append(msg.read(n_bits + 1))
        except ReadError:
            break

        y = s_in[:-1]
        b = s_in[-1:]

        if Bits(y) == Bits(''):
            pos = 0
        else:
            pos = y.uint

        s_out = s_out + (str(keys[pos]) + b.bin)

        keys.append(str(keys[pos]) + str(Bits(b).bin))

        s_in = BitArray()

    output = BitArray('0b' + s_out)
    output.append(padding)

    with open(sys.argv[2], 'wb') as f_out:
        output.tofile(f_out)

    file.close()
예제 #26
0
    #generate KS
    KS = BitArray(uint=random.randint(0, 1023), length=10)

    IDA = BitArray('0b' + M1.bin[:16])
    IDB = BitArray('0b' + M1.bin[16:32])

    T = int(time.time())
    leng = len(bin(T))
    rem = leng % 8
    if (rem <= 6):
        leng += (6 - rem)
    else:
        leng += 7
    BT = BitArray(uint=T, length=leng)

    M2 = KS.copy()
    M2.append(IDB)
    M2.append(BT)

    M3 = KS.copy()
    M3.append(IDA)
    M3.append(BT)

    enM3 = multDES(M3, KB, 0)

    M2.append(enM3)
    enM2 = multDES(M2, KA, 0)

    #sending M2 to Alice
    AKDC.send(enM2.bytes)
예제 #27
0
class FileMgr(object):
    def __init__(self, metainfo):
        self._metainfo = metainfo
        self._have = BitArray(self._metainfo.num_pieces)

        directory = metainfo.directory
        if directory != '':
            try:
                if not os.path.exists(directory):
                    os.makedirs(directory)
            except OSError as err:
                if err.errno != errno.EEXIST:
                    raise

        files = metainfo.files

        # _files is a list of files in the torrent.  Each entry is a
        # tuple containing the file descriptor, length of the file and
        # offset of the file within the torrent
        self._files = []

        offset = 0
        subdirs = []
        for path, length in files:
            dirname = directory+"/".join(path[0:-1])

            if dirname != '' and dirname not in subdirs:
                subdirs.append(dirname)
                try:
                    if not os.path.exists(dirname):
                        os.makedirs(dirname)
                except OSError as err:
                    if err.errno != errno.EEXIST:
                        raise

            if dirname == '':
                filename = path[-1]
            else:
                filename = dirname+"/"+path[-1]

            try:
                open(filename, 'a').close()
                fd = open(filename, 'rb+')
            except IOError:
                logger.critical("Unable to open file {}".format(filename))
                raise

            self._files.append((fd, length, offset))
            offset += length

    def _file_index(self, offset):
        for i, (fd, length, begin) in enumerate(self._files):
            if offset >= begin and offset < begin + length:
                return i

    def have(self):
        return self._have.copy()

    def write_block(self, piece_index, offset_in_piece, buf, file_index=None):
        offset_in_torrent = (piece_index * self._metainfo.piece_length +
                             offset_in_piece)

        if not file_index:
            file_index = self._file_index(offset_in_torrent)
        fd, file_length, file_offset_in_torrent = self._files[file_index]
        offset_in_file = offset_in_torrent - file_offset_in_torrent
        fd.seek(offset_in_file)
        if len(buf) <= file_length - offset_in_file:
            fd.write(buf)
            fd.flush()
        else:
            to_write = file_length - offset_in_file
            fd.write(buf[:to_write])
            fd.flush()
            self.write_block(piece_index, offset_in_piece + to_write,
                             buf[to_write:], file_index+1)
예제 #28
0
args = parser.parse_args()

if (len(args.command) != 12):
   print('command is wrong length')
   my_command = 'aXY1CT20F100'
else:
   my_command =args.command

in_preamble = BitArray('0b00000')
in_device1 = BitArray('0xd70000c50027da11')
in_device2 = BitArray('0x641000420027da11')
in_params = BitArray('0xf40080c1002060060000b0002249000027da11')
in_list = [in_preamble,in_device1,in_device2,in_params]

#in_list[3].reverse()
in_first = in_params.copy()

print(in_list[0].bin)
print(in_list[1].hex)

print(in_list[2].hex)
print(in_list[3].hex)
#print(in_list[3].bin)

in_list[0].clear()
in_list[1].clear()
in_list[2].clear()
in_list[3].clear()

with open(args.input, 'r') as raw_file:
  A_list1 = []
예제 #29
0
class CamelliaKey(object):
    """
    @brief   In this function, we initialize the object
    @:param  length         length of the camellia key
    @:param  ckey_adress    camellia private key file address (need to be a Ox number)

    @:var   KL (key left block), KR (key right block)
    @:var   ckey (content of the file at the file adress ckey_adress)
    """
    def __init__(self, ckey_address, length):
        self.length = length
        if self.length not in [128, 192, 256]:
            raise ValueError("Invalid key length, "
                             "it must be 128, 192 or 256 bits long!")
        file = open(ckey_address, "r")
        ckey = file.read()
        file.close()
        # ckey is a BitArray Object
        ckey = BitArray(ckey)
        if self.length == 128:
            self.KL = ckey
            self.KR = BitArray(Bits(int=0, length=128))
        elif self.length == 192:
            self.KL = re_128b(ckey >> 64)
            a = (ckey & MASK64_192) << 64
            b = ~(ckey & MASK64_192)
            b.replace("0xffffffffffffffff", "0x0000000000000000")
            self.KR = re_128b(a | b)
        elif self.length == 256:
            self.KL = re_128b(ckey >> 128)
            self.KR = re_128b(ckey & MASK128)
        else:
            print("what the f**k")

    def generate_ka(self):
        """
            @brief      Generate KA
            @:return    ka
            :rtype: BitArray object
        """
        # mise en 64 bits car f_function n'autorise que les entrées de 64bits et les ^ n'est autorisée que sur des
        # bytearray de même taille
        a = self.KL ^ self.KR
        temp1 = re_64b(a >> 64)
        temp2 = re_64b(a & MASK64)
        temp2 ^= f_function(temp1, sigma[0])
        temp1 ^= f_function(temp2, sigma[1])
        temp1 ^= re_64b((self.KL >> 64))
        temp2 ^= re_64b((self.KL & MASK64))
        temp2 ^= f_function(temp1, sigma[2])
        temp1 ^= f_function(temp2, sigma[3])
        # remise en 128 bits
        temp1 = agg_128b(temp1)
        temp2 = agg_128b(temp2)
        ka = (temp1 << 64) | temp2
        return ka

    """
        @brief      Generate KB
        @:return    kb
    """

    def generate_kb(self):
        """

        :rtype: BitArray
        """
        if self.length != 128:
            ka = self.generate_ka()
            temp1 = re_64b((ka ^ self.KR) >> 64)
            temp2 = re_64b((ka ^ self.KR) & MASK64)
            temp2 ^= f_function(temp1, sigma[4])
            temp1 ^= f_function(temp2, sigma[5])
            temp1 = agg_128b(temp1)
            temp2 = agg_128b(temp2)
            kb = (temp1 << 64) | temp2
        else:
            kb = BitArray(Bits(int=0, length=128))
        return kb

    """
        @brief      Generate all the subkeys for the encryption with a Camellia Key
        @:return    a table of subkeys
    """

    def generate_subkeys(self):
        ka = self.generate_ka()
        if self.length == 128:
            k1 = ka >> 64
            k2 = ka & MASK64
            klc15 = self.KL.copy()
            klc15.rol(15)
            k3 = klc15 >> 64
            k4 = klc15 & MASK64
            kac15 = ka.copy()
            kac15.rol(15)
            k5 = kac15 >> 64
            k6 = kac15 & MASK64
            klc45 = self.KL.copy()
            klc45.rol(45)
            k7 = klc45 >> 64
            k8 = klc45 & MASK64
            kac45 = ka.copy()
            kac45.rol(45)
            k9 = kac45 >> 64
            klc60 = self.KL.copy()
            klc60.rol(60)
            k10 = klc60 & MASK64
            kac60 = ka.copy()
            kac60.rol(60)
            k11 = kac60 >> 64
            k12 = kac60 & MASK64
            klc94 = self.KL.copy()
            klc94.rol(94)
            k13 = klc94 >> 64
            k14 = klc94 & MASK64
            kac94 = ka.copy()
            kac94.rol(94)
            k15 = kac94 >> 64
            k16 = kac94 & MASK64
            klc111 = self.KL.copy()
            klc111.rol(111)
            k17 = klc111 >> 64
            k18 = klc111 & MASK64
            subk128 = [
                k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14,
                k15, k16, k17, k18
            ]
            return re_64b_array(subk128)
        else:
            kb = self.generate_kb()
            k1 = kb >> 64
            k2 = kb & MASK64
            krc15 = self.KR.copy()
            krc15.rol(15)
            k3 = krc15 >> 64
            k4 = krc15 & MASK64
            kac15 = ka.copy()
            kac15.rol(15)
            k5 = kac15 >> 64
            k6 = kac15 & MASK64
            kbc30 = kb.copy()
            kbc30.rol(30)
            k7 = kbc30 >> 64
            k8 = kbc30 & MASK64
            klc45 = self.KL.copy()
            klc45.rol(45)
            k9 = klc45 >> 64
            k10 = klc45 & MASK64
            kac45 = ka.copy()
            kac45.rol(45)
            k11 = kac45 >> 64
            k12 = kac45 & MASK64
            krc60 = self.KR.copy()
            krc60.rol(60)
            k13 = krc60 >> 64
            k14 = krc60 & MASK64
            kbc60 = kb.copy()
            kbc60.rol(60)
            k15 = kbc60 >> 64
            k16 = kbc60 & MASK64
            klc77 = self.KL.copy()
            klc77.rol(77)
            k17 = klc77 >> 64
            k18 = klc77 & MASK64
            krc94 = self.KR.copy()
            krc94.rol(94)
            k19 = krc94 >> 64
            k20 = krc94 & MASK64
            kac94 = ka.copy()
            kac94.rol(94)
            k21 = kac94 >> 64
            k22 = kac94 & MASK64
            klc111 = self.KL.copy()
            klc111.rol(111)
            k23 = klc111 >> 64
            k24 = klc111 & MASK64
            subk = [
                k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14,
                k15, k16, k17, k18, k19, k20, k21, k22, k23, k24
            ]
            return re_64b_array(subk)

    def generate_subkw(self):
        """
            @:brief     Generate_subkw aims to generate all the subkeys kw1, kw2, kw3 and kw4.
            @:return    a table of subkweys
        """
        if self.length == 128:
            k = self.generate_ka()
        else:
            k = self.generate_kb()
        kw1 = self.KL >> 64
        kw2 = self.KL & MASK64
        kc = k.copy()
        kc.rol(111)
        kw3 = kc >> 64
        kw4 = kc & MASK64
        subkweys = [kw1, kw2, kw3, kw4]
        return re_64b_array(subkweys)

    def generate_subke(self):
        """
            @:brief     Generate_subke aims to generate all the subkeys ke1, ke2, ke3, etc... this subkeys are different
            if the length of the key is 128 or if it is different
            @:return    a table of all the subkeys
        """
        ka = self.generate_ka()
        if self.length == 128:
            # make copy of ka to use rotation left
            kac = ka.copy()
            klc = self.KL.copy()
            # use rotation left, the result become the var
            kac.rol(30)
            klc.rol(77)
            ke1 = kac >> 64
            ke2 = kac & MASK64
            ke3 = klc >> 64
            ke4 = klc & MASK64
            subke128 = [ke1, ke2, ke3, ke4]
            return re_64b_array(subke128)
        else:
            krc = self.KR.copy()
            krc.rol(30)
            ke1 = krc >> 64
            ke2 = krc & MASK64
            klc = self.KL.copy()
            klc.rol(60)
            ke3 = klc >> 64
            ke4 = klc & MASK64
            kac = ka.copy()
            kac.rol(77)
            ke5 = kac >> 64
            ke6 = kac & MASK64
            subke = [ke1, ke2, ke3, ke4, ke5, ke6]
            return re_64b_array(subke)
예제 #30
0
def SHA1(m):
    """ SHA1 hash function.
    Args:
      m: The message, as a BitArray.
    Returns:
      The message hash, as a BitArray. """
    #initialising variables for use in Hash
    mt = BitArray(m)
    h0 = BitArray('0x67452301')
    h1 = BitArray('0xEFCDAB89')
    h2 = BitArray('0x98BADCFE')
    h3 = BitArray('0x10325476')
    h4 = BitArray('0xC3D2E1F0')
    
    #processing message so that it fits Hash Format
    m1 = len(mt.bin)
    m2 = m1
    if m1%8 == 0:
        m2 += 1
        mt.append(BitArray('0b1'))
    
    #more processing by adding a pad so message is divisible into 512 bit chunks
    temp_len = m2%512
    pad = 0
    if temp_len < 448:
        pad = 448-temp_len
    else:
        pad = (512-temp_len) + 448
    
    padding = BitArray('0b'+'0'*pad)
    padding.append(BitArray(uint=m1,length=64))   
    mt.append(padding)
    
    pad_len = len(mt.bin)
    
    Imin = 0
    Imax = 512
    #breaks message into 512 bit chunks and works on each one
    while Imax <= pad_len:
        
        block = BitArray('0b'+mt.bin[Imin:Imax])
        
        #splits 512 bit chunk into 16, 32 bit chunks
        w = [0]*80
        low = 0
        up = 16
        for i in range(16):
            w[i] = BitArray('0b'+block.bin[low:up])
            low +=16
            up += 16
        
        #then expands to 80 32 bit chunks
        for i in range(16,80):
            temp_BA = w[i-3].copy()
            temp_BA ^= w[i-8]
            temp_BA ^= w[i-14]
            temp_BA ^= w[i-16]
            temp_BA.rol(1) 
            w[i] = temp_BA.copy()
            
        #initialize hash values for this chunk
        a = h0.copy()
        b = h1.copy()
        c = h2.copy()
        d = h3.copy()
        e = h4.copy()
        
        for i in range(0,80):
            #the F function used
            if 0 <= i <20:
                tb = b.copy()
                tb &= c
                ntb = b.copy()
                ntb.invert()
                ntb &= d
                tb |= ntb
                fun = tb.copy()
                k = BitArray('0x5A827999')
            elif 20 <= i <40:
                tb = b.copy()
                tb ^= c
                tb ^= d
                fun = tb.copy()
                k = BitArray('0x6ED9EBA1')
            elif 40 <= i < 60:
                tb = b.copy()
                tb &= c
                ttb = b.copy()
                ttb &= d
                tc = c.copy()
                tc &= d
                tb |= ttb
                tb |= tc
                fun = tb.copy()
                k = BitArray('0x8F1BBCDC')
            elif 60 <= i < 80:
                tb = b.copy()
                tb ^= c
                tb ^= d
                fun = tb.copy()
                k = BitArray('0xCA62C1D6')            
        
            temp = a.copy()
            temp.rol(5)
            temp_val = (temp.uint + fun.uint + e.uint + k.uint + w[i].uint)% 2**32
            temp = BitArray(uint = temp_val,length = 32)
            e = d.copy()
            d = c.copy()
            c = b.copy()
            c.rol(30)
            b = a.copy()
            a = temp.copy()
            
        #updates h0,h1,h2,h3,h4 so as to cause avalanche effect
        tval = (h0.uint + a.uint)% 2**32
        h0 = BitArray(uint = tval,length = 32)        
        tval = (h1.uint + b.uint)% 2**32
        h1 = BitArray(uint = tval,length = 32) 
        tval = (h2.uint + c.uint)% 2**32
        h2 = BitArray(uint = tval,length = 32) 
        tval = (h3.uint + d.uint)% 2**32
        h3 = BitArray(uint = tval,length = 32) 
        tval = (h4.uint + e.uint)% 2**32
        h4 = BitArray(uint = tval,length = 32) 
        
        Imin += 512
        Imax += 512
    
    #combines into 160 bit hash value and returns
    hh = h0.copy()
    hh.append(h1)
    hh.append(h2)
    hh.append(h3)
    hh.append(h4)
    return hh
예제 #31
0
class Framing():
    """Classe que representa o procedimento para alinhamento de quadro no PCM30
    """
    def __init__(self, logging_level=logging.INFO):
        self.buffer_octeto = BitArray(
        )  # Buffer utilizado somente no Estado Realinhando
        self.buffer_frame = BitArray()
        self.buffer_copy = BitArray()
        self.n = 1  # número de quadros para avançar (inicia em 1)

        # Configurando Logs
        self.logger = logging.getLogger("Framming")
        logging.basicConfig(level=logging_level)

        # Definindo estado inicial
        self.logger.info("Iniciando...")
        self.state = State.REALIGNING
        self._print_state()
        self.logger.info("Procurando FAS...")

    # Método chamado pela função principal
    def handle_fsm(self, received_bit: bin):
        """Método para chamar a Máquina de estados passando os bits recebidos externamente
            ou bits presentes no buffer.

        Args:
            received_bit (bin): bit 0 <'0b0'> ou 1 <'0b1'>
        """
        self._fsm(received_bit)
        # Após retornar da FSM só volta a ler o arquivo se o buffer tiver vazio
        while len(self.buffer_copy) > 0:  # Enquanto tiver bits no buffer
            buffer_bit = self.buffer_copy.bin[0]
            del self.buffer_copy[0:1:1]
            self._fsm(self.char_to_bit(buffer_bit))

    def _fsm(self, buffer_bit):
        """Método privado que representa a máquina de estados

        Args:
            received_bit : bit recebido
        """
        # Estado REALINHANDO
        if self.state is State.REALIGNING:
            len_octeto = len(self.buffer_octeto)
            if len_octeto < 8:
                self.buffer_octeto.append(buffer_bit)
            else:
                # Deslizar octeto
                del self.buffer_octeto[0:1:1]  # Remove bit da primeira posição
                self.buffer_octeto.append(
                    buffer_bit)  # Insere novo bit na última

            self.logger.debug("Octeto: %s" % self.buffer_octeto.bin)
            if self.buffer_octeto.uint is Signal.FAS.value:  # Verifica se temos um possível PAQ
                self.logger.info("FAS confirmado, possível PAQ encontrado!")
                self.state = State.REALIGNMENT_CHECK  # Transição de Estado
                self._print_state()

        # Estado de confirmação de Realinhamento
        elif self.state is State.REALIGNMENT_CHECK:
            frame, octeto = self._go_to_frame(self.n, buffer_bit)
            if frame == 1:  # Avançou 1 quadro
                b1_pos = 1
                b1 = octeto.bin[b1_pos]  # Recuperando b1 para comparação
                self.logger.info("b1 (nfas) = %s" % b1)
                self.logger.debug("Buffer = %s" % self.buffer_frame.bin)

                if str(b1) == '1':  # comparação do b1
                    self.logger.info("NFAS confirmado!")
                    self.logger.debug("Buffer = %s" % self.buffer_frame.bin)
                    self.n = 2  # avançar para próximo quadro
                else:
                    self.logger.info("NFAS não confirmado, PAQ Inválido!")
                    self.state = State.REALIGNING  # Transição de Estado
                    self.buffer_copy.clear()
                    self.buffer_copy = self.buffer_frame.copy()
                    self.logger.debug("Buffer Copy= %s" % self.buffer_copy.bin)
                    self.buffer_frame.clear()
                    self.n = 1
                    self._print_state()
                    self.logger.info("Procurando FAS...")
            elif frame == 2:  # Avançou 2 quadros
                self.n = 1  # retornando n global para primeiro quadro
                if octeto.uint is Signal.FAS.value:  # Comparação do FAS
                    self.logger.info("FAS confirmado, PAQ Encontrado!")
                    self.logger.debug("Buffer = %s" % self.buffer_frame.bin)

                    self.state = State.ALIGNED  # Transição de Estado
                    self._print_state()
                    self._get_information()
                    #limpando buffers
                    self.buffer_copy.clear()
                    self.buffer_frame.clear()
                else:
                    self.logger.info("FAS não confirmado, PAQ Inválido!")
                    self.state = State.REALIGNING  # Transição de Estado
                    self.buffer_copy.clear()
                    self.buffer_copy = self.buffer_frame.copy()
                    self.logger.debug("Buffer Copy= %s" % self.buffer_copy.bin)
                    self.buffer_frame.clear()
                    self._print_state()
                    self.logger.info("Procurando FAS...")

        # Estado de Alinhamento
        elif self.state is State.ALIGNED:
            frame, octeto = self._go_to_frame(2,
                                              buffer_bit)  # Avançar 2 quadros
            if frame == 2:  # Avançou 2 quadros
                if octeto.uint is Signal.FAS.value:  # Comparação do FAS
                    self.logger.info("FAS confirmado, PAQ Encontrado!")
                    self._get_information()

                    self.state = State.ALIGNED  # Transição de Estado
                    self.buffer_copy.clear()
                    self.buffer_frame.clear()
                else:
                    self.logger.info("FAS não confirmado, PAQ Inválido!")
                    self.state = State.LOSS_ALIGNMENT_CHECK  # Transição de Estado
                    self._print_state()
                    self.logger.info("Verificando perda do Alinhamento...")
                    self.logger.info("Procurando FAS...")
                    self.n = 4

        # Estado de confirmação de perda do Alinhamento
        elif self.state is State.LOSS_ALIGNMENT_CHECK:
            frame, octeto = self._go_to_frame(self.n,
                                              buffer_bit)  # Avançar 2 quadros
            if octeto:  # Avançou quadros
                if octeto.uint is Signal.FAS.value:  # Comparação do FAS
                    self.logger.info("FAS confirmado, PAQ Encontrado!")
                    self.logger.info("Alinhamento recuperado!")

                    self.state = State.ALIGNED  # Transição de Estado
                    self._print_state()
                    self._get_information()
                    self.n = 1
                    # limpando buffers
                    self.buffer_copy.clear()
                    self.buffer_frame.clear()
                else:
                    if frame == 4:  # Avançou 4 quadros
                        self.logger.info("FAS não confirmado, PAQ Inválido!")
                        self.state = State.LOSS_ALIGNMENT_CHECK  # Transição de Estado
                        self.logger.info("Procurando FAS...")
                        self.n = 6

                    elif frame == 6:  # Avançou 6 quadros
                        self.logger.info("FAS não confirmado, PAQ Inválido!")
                        self.logger.info("Perda do alinhamento confirmada!")

                        self.state = State.REALIGNING  # Transição de Estado
                        self.buffer_copy.clear()
                        self.buffer_frame.clear()
                        self._print_state()
                        self.logger.info("Procurando FAS...")
                        self.n = 1

    @staticmethod
    def char_to_bit(char_bit: str) -> bin:
        """Função para converter um caractere em um bit

        Args:
            char_bit (str): caractere recebido para conversão

        Returns:
            bin: bit convertido
        """
        if str(char_bit) == "0":
            return '0b0'
        elif str(char_bit) == "1":
            return '0b1'
        else:
            print("Error char = %s" % char_bit)

    def _go_to_frame(self, n_frame: int, buffer_bit: bin) -> [int, BitArray]:
        """Método privado responsável por avançar quadros

        Args:
            n_frame (int): número de quadros para avançar
            buffer_bit (bin): bit para adicionar ao buffer

        Returns:
            int,BitArray: int --> número de quadros avançados
                          BitArray --> octeto com NFAS ou FAS para comparação
        """
        self.buffer_frame.append(
            buffer_bit)  # Avançar bits até completar quadro
        len_frame = len(self.buffer_frame)
        if len_frame == (n_frame * 256):  # Avançou n quadros

            if n_frame > 1:
                self.logger.info("Avançando 2 Quadros...")
            else:
                self.logger.info("Avançando 1 Quadro...")

            start_pos = len_frame - 8  # (256 - 8)
            nfas_or_fas = self.buffer_frame[
                start_pos:]  # recuperando NFAS ou FAS
            if n_frame == 1:
                self.logger.info("NFAS = %s" % nfas_or_fas.bin)
            else:
                self.logger.info("FAS = %s" % nfas_or_fas.bin)

            self.logger.debug("Buffer = %s" % self.buffer_frame.bin)

            return n_frame, nfas_or_fas
        return 0, None

    def _get_information(self):
        """Método privado responsável por imprimir na tela o conteúdo entre PAQs
        """
        self.logger.info("Recuperando Informação...")

        end_pos_info = len(self.buffer_frame) - 8  #(512 - 8)
        information = self.buffer_frame[:
                                        end_pos_info].bin  # remover informação sem PAQ

        text = "Informação entre PAQs\n"
        text += "----------------------------------------\n"
        text += "%s\n----------------------------------------" % information

        self.logger.info(text)

        self.logger.debug("Buffer = %s" % self.buffer_frame.bin)

    def _print_state(self):
        """Método para imprimir os estados atuais durante a execução da Máquina
        """
        self.logger.info("========================================")
        self.logger.info("Estado = %s" % self.state.name)
        self.logger.info("========================================")