예제 #1
0
파일: pfr.py 프로젝트: saper/spsdk
    def _export_register(self, register_name: str, compute_inverses: bool) -> bytes:
        """Generate binary output for single register."""
        register = BitArray(length=32)
        user_config = self.user_config.get(register_name, dict())
        inverse_present = False
        for field in self._get_bitfields(register_name, exclude_computed=False):
            name = field.attrib["name"]
            offset = parse_int(field.attrib["offset"])
            width = parse_int(field.attrib["width"])
            # chcek whether there's a need to calculate inverse values
            inverse_present |= name == "INVERSE_VALUE"

            # The configuration allows to configure the whole register with single value
            if isinstance(user_config, str):
                temp_value = user_config
            else:
                temp_value = user_config.get(name) or field.attrib["reset_value"]
            value = parse_int(temp_value)
            # due to endianess we fill the bits from the end, therefore there's '-' in position
            # pos = 0 means offset = 0, means end of the BitArray
            register.overwrite(bs=BitArray(f"uint:{width}={value}"), pos=-(offset + width))
        if compute_inverses and inverse_present:
            # NOTE: For now we'll assume the INVERSES are 16b long and inverts bits[15:0]
            # should this change in the future a data model change is necessary
            # NOTE: invert method changes bits in-place, thus we need to call it on separate object
            # calling invert() after slicing doesn't work for BitArray
            b_lower = register[16:]
            b_lower.invert()
            register.overwrite(b_lower, 0)
        # swapping bytes from big endian into little
        register.byteswap()
        return register.bytes
예제 #2
0
    def validate_checksum_xrb(cls, address: str) -> bool:
        """Given an xrb/nano/ban address validate the checksum. Return true if valid, false otherwise"""
        if len(address) == 64 and address[:4] == 'ban_':
            # Populate 32-char account index
            account_map = "13456789abcdefghijkmnopqrstuwxyz"
            account_lookup = {}
            for i in range(0, 32):
                account_lookup[account_map[i]] = BitArray(uint=i, length=5)

            # Extract key from address (everything after prefix)
            acrop_key = address[4:-8]
            # Extract checksum from address
            acrop_check = address[-8:]

            # Convert base-32 (5-bit) values to byte string by appending each 5-bit value to the bitstring, essentially bitshifting << 5 and then adding the 5-bit value.
            number_l = BitArray()
            for x in range(0, len(acrop_key)):
                number_l.append(account_lookup[acrop_key[x]])
            number_l = number_l[
                4:]  # reduce from 260 to 256 bit (upper 4 bits are never used as account is a uint256)

            check_l = BitArray()
            for x in range(0, len(acrop_check)):
                if acrop_check[x] not in account_lookup:
                    return False
                check_l.append(account_lookup[acrop_check[x]])
            check_l.byteswap()  # reverse byte order to match hashing format

            # verify checksum
            h = blake2b(digest_size=5)
            h.update(number_l.bytes)
            return h.hexdigest() == check_l.hex

        return False
예제 #3
0
파일: pfr.py 프로젝트: saper/spsdk
 def _parse_register(self, register_name: str, data: bytes) -> Union[str, dict]:
     """Parse individual register, returns wither one 32b value or dict of bitfields."""
     register = {}
     bits = BitArray(data)
     # data is stored in little endian, but processed in big endian
     bits.byteswap()
     for field in self._get_bitfields(register_name, exclude_computed=False):
         width = parse_int(field.attrib["width"])
         # exit early if we found a single 32b field
         if width == 32:
             return format_value(bits.uint, width)
         name = field.attrib["name"]
         offset = parse_int(field.attrib["offset"])
         # OK, what the hell is that slicing about?!
         # offset is marked from the end of the bitarray not the begging like in a list
         # e.g.: ba = BitArray('0b00001100'), we want to extract bitfields of width=2 and offset=2 ('11')
         # again offset=2 means 2 bits from the end
         # BitArray supports negative indexing like an regular python list does: last bit has index -1
         # that means we want to extract bits with indecies -4,-3 => [-4:-2]
         # HOWEVER: if we would want to extract 2 bits in the end (offset=0)
         # we would need to use [-offset:] slice or [-offset:None]
         slice_end = None if offset == 0 else -offset
         filed_bits = bits[-(offset + width): slice_end]
         register[name] = format_value(filed_bits.uint, width)
     return register
예제 #4
0
    def getBinBitArray(self, val, endian, numBase, binFormat):
        # [0b|0x|0o]1234
        try:
            val = str(val)
            binSize = numBase.value["mod"]*len(val)
            bArr = BitArray(numBase.value["prefix"]+val)

            if endian == Endian.LITTLE:
                bArr.byteswap()

            binData = bArr.bin

            if binFormat == BinFormat.C2 or binFormat == BinFormat.C1:
                bArr = BitArray(NumBase.BIN.value["prefix"] + binData[0] * (self.mem.value["size"] - binSize) + binData)
            elif binFormat == BinFormat.MS:
                sign = binData[0]
                binSize += 1
                bArr = BitArray(bin=binData[1:])

                binData = bArr.bin

                bArr = BitArray(NumBase.BIN.value["prefix"] + sign + binData[0] * (self.mem.value["size"] - binSize) + binData)

            if endian == Endian.LITTLE:
                bArr.byteswap()

            return bArr
        except CreationError as e:
            raise ConvertionException(str(e))
예제 #5
0
def xvcShift(TMS, TDI):

    numBits = TMS.len

    print("TMS: ", TMS)
    print("TDI: ", TDI)

    ## Pad to nearest byte alignment
    TMS += BitArray((8 - numBits) % 8)
    TDI += BitArray((8 - numBits) % 8)

    ## Make "little-endian" essentially where bit 0 of first byte is
    ## the first bit out.
    TMS.reverse()
    TMS.byteswap()
    TDI.reverse()
    TDI.byteswap()

    msg = numBits.to_bytes(4, byteorder='little') + TMS.bytes + TDI.bytes
    resp = xvcdSend('shift:', msg, TMS.len // 8)
    TDO = BitArray(resp)
    TDO.byteswap()
    TDO.reverse()
    TDO = TDO[0:numBits]

    #print("< 0x{} == ".format(resp.hex()), TDO)
    print("< 0x{}".format(resp.hex()))
    print("TDO: ", TDO)
    print()

    return TDO
예제 #6
0
파일: pyrai.py 프로젝트: icarusglider/PyRai
def xrb_account(address):
    # Given a string containing an XRB address, confirm validity and provide resulting hex address
    if len(address) == 64 and (address[:4] == 'xrb_'):
        account_map = "13456789abcdefghijkmnopqrstuwxyz"  # each index = binary value, account_lookup[0] == '1'
        account_lookup = {}
        for i in range(
                0, 32
        ):  # populate lookup index with prebuilt bitarrays ready to append
            account_lookup[account_map[i]] = BitArray(uint=i, length=5)

        acrop_key = address[
            4:
            -8]  # we want everything after 'xrb_' but before the 8-char checksum
        acrop_check = address[-8:]  # extract checksum

        # convert base-32 (5-bit) values to byte string by appending each 5-bit value to the bitstring, essentially bitshifting << 5 and then adding the 5-bit value.
        number_l = BitArray()
        for x in range(0, len(acrop_key)):
            number_l.append(account_lookup[acrop_key[x]])
        number_l = number_l[
            4:]  # reduce from 260 to 256 bit (upper 4 bits are never used as account is a uint256)

        check_l = BitArray()
        for x in range(0, len(acrop_check)):
            check_l.append(account_lookup[acrop_check[x]])
        check_l.byteswap()  # reverse byte order to match hashing format

        result = number_l.hex.upper()

        # verify checksum
        h = blake2b(digest_size=5)
        h.update(number_l.bytes)
        if (h.hexdigest() == check_l.hex): return result
        return False
    return False
예제 #7
0
 def emit_int_16_bits(self, int_string):
     parsed_int = self.parse_int(int_string)
     if parsed_int < 32768:
         b = BitArray(int=parsed_int, length=16)
     else:
         b = BitArray(uint=parsed_int, length=16)
     b.byteswap()
     return b.bin
예제 #8
0
 def emit_int_32_bits(self, int_string):
     parsed_int = self.parse_int(int_string)
     if parsed_int < 2147483648:
         b = BitArray(int=parsed_int, length=32)
     else:
         b = BitArray(uint=parsed_int, length=32)
     b.byteswap()
     return b.bin
def write_serial(data, header):
    #Process header
    #Open serial port
    portName = header["port"]
    baudrate = header["baudrate"]
    waitTime = 0.1
    response = {"msg": "", "err": False, "data": ""}
    try:
        ser = serial.Serial(portName, baudrate, timeout=waitTime)
        #ser.open()
    except serial.SerialException:
        # print("Unable to open",portName,". Exiting...")
        response["msg"] = "Unable to open %s." % portName
        response["err"] = True
        return response

    #Flush buffer
    ser.flushInput()
    ser.flushOutput()

    #Write data
    x = ser.write(data)

    if header["mode"] == "read":
        #Read data
        time.sleep(waitTime)
        try:
            tmp = ser.read(4)
            if not tmp:
                print("No data received")
                response[
                    "msg"] = "Waited for data, but no response from %s." % portName
                response["err"] = True
                response["data"] = ""
            else:
                tmp2 = BitArray(tmp)
                tmp2.byteswap()
                response["data"] = [tmp2.hex]
        except Exception:
            print(
                "main: error: exception for\n",
                "{}".format(traceback.format_exc()),
            )
            response["msg"] = "Unable to read from %s." % portName
            # response["msg"] = "Exception when reading:\n" + f"{traceback.format_exc()}"
            response["err"] = True

    #Close serial port
    ser.close()
    return response
예제 #10
0
파일: ccl.py 프로젝트: whoi-acomms/pyacomms
    def from_data(cls, databytes):

        values = dict.fromkeys(MdatStateMessage.fields)

        # accept either the full frame payload or just the data after the CCL type identifier
        if (len(databytes) > 31):
            databytes = databytes[1:]

        d = BitStream(bytes=databytes)

        values['mode'] = 'MDAT_STATE'

        lat_bits = BitArray(d.read('bits:24'))
        values['latitude'] = decode_latlon(lat_bits)

        lon_bits = BitArray(d.read('bits:24'))
        values['longitude'] = decode_latlon(lon_bits)

        values['fix_age'] = d.read('uint:8') * 4
        values['time_date'] = decode_time_date(d.read('bits:24'))
        values['heading'] = d.read('uint:8') * (360.0 / 255.0)

        mission_mode_depth_bits = d.read('bits:16')
        (values['mission_mode'], values['depth']) = decode_mission_mode_and_depth(mission_mode_depth_bits)
        values['faults_bits'] = d.read('bits:40')
        values['mission_leg'] = d.read('uint:8')
        values['estimated_velocity'] = d.read('uint:8') / 25.0
        values['objective_index'] = d.read('uint:8')
        values['power_watts'] = d.read('uint:8') * 4.0

        goal_lat_bits = BitArray(d.read('bits:24'))
        values['goal_latitude'] = decode_latlon(goal_lat_bits)
        goal_lon_bits = BitArray(d.read('bits:24'))
        values['goal_longitude'] = decode_latlon(goal_lon_bits)

        values['battery_percent'] = d.read('uint:8')

        gfi_pitch_oil_encoded = BitArray(d.read('bits:16'))
        gfi_pitch_oil_encoded.byteswap()
        values['gfi_percent'] = gfi_pitch_oil_encoded[11:].uint * 100.0 / 31.0
        values['oil'] = gfi_pitch_oil_encoded[6:11].uint * 100.0 / 31.0
        values['pitch'] = gfi_pitch_oil_encoded[0:6].int * 180.0 / 63.0

        # Make a message
        mdat_state = cls(values)

        return mdat_state
예제 #11
0
def hex_to_account(hex_acc: str) -> (str, str):
    """
    Given a string containing a hex address, encode to public address.
    :return string public account address as xrb_(...)
    :param hex_acc: string encoded address
    # TODO consider nano_(...) addresses
    """

    # format with checksum
    # each index = binary value, account_lookup['00001'] == '3'
    account_map = "13456789abcdefghijkmnopqrstuwxyz"
    account_lookup = {}
    # populate lookup index for binary string to base-32 string character
    for i in range(32):
        account_lookup[BitArray(uint=i, length=5).bin] = account_map[i]
    # hex string > binary
    account = BitArray(hex=hex_acc)

    # get checksum
    h = blake2b(digest_size=5)
    h.update(account.bytes)
    checksum = BitArray(hex=h.hexdigest())

    # encode checksum
    # swap bytes for compatibility with original implementation
    checksum.byteswap()
    encode_check = ''
    for x in range(0, int(len(checksum.bin) / 5)):
        # each 5-bit sequence = a base-32 character from account_map
        encode_check += account_lookup[checksum.bin[x * 5:x * 5 + 5]]

    # encode account
    encode_account = ''
    while len(account.bin) < 260:
        # pad our binary value so it is 260 bits long before conversion
        # (first value can only be 00000 '1' or 00001 '3')
        account = '0b0' + account
    for x in range(0, int(len(account.bin) / 5)):
        # each 5-bit sequence = a base-32 character from account_map
        encode_account += account_lookup[account.bin[x * 5:x * 5 + 5]]

    # build the full address
    return 'xrb_{}{}'.format(encode_account, encode_check)
예제 #12
0
    def encrypt(self, msg):
        all_chiper = []

        for i in range(len(msg)):
            hex_plain = hex(ord(msg[i]))

            keystream = self.keystream(8)
            keystream = '0b' + ''.join(str(i) for i in keystream[::-1])
            keystream = BitArray(keystream)
            keystream.byteswap()

            plain = BitArray(hex_plain)
            plain.byteswap()

            cipher = [
                x ^ y for x, y in zip(map(int, list(plain)),
                                      map(int, list(keystream)))
            ]
            all_chiper += cipher

            cipher = '0b' + ''.join(str(i) for i in cipher)
            cipher = BitArray(cipher)
            cipher.byteswap()

            print '{: ^15}{: ^15}{: ^15}{: ^15}{:^15}'.format(
                hex_plain, plain.bin, keystream.bin, cipher.bin,
                '0x' + cipher.hex.upper())

        return all_chiper
예제 #13
0
def encode(data: bytes):
    root = build_tree(data)

    translation_list = build_character_translation(root, [])
    # print(f'translation list {translation_list}')
    translation = merge_dictionaries(translation_list)
    # print(f'translation {translation}')
    translated = list(itertools.chain(*[translation.get(byte) for byte in data]))
    # print(f'l translated {len(translated)}')
    additional_bytes = len(translated) % 8
    # print(f'additional bytes {additional_bytes}')
    x = BitArray(translated) + BitArray([0] * (8 - additional_bytes))
    x.reverse()
    x.byteswap()
    # print (f'x {x.bin}')
    encoded_bytes = x.tobytes()
    # print(f'encoded bytes: {encoded_bytes}')
    root.additional_bytes = additional_bytes
    
    serialised_tree = DefaultEncoder().encode(root)
    output = bytes(serialised_tree, 'ascii') + encoded_bytes
    return output
예제 #14
0
def account_xrb(account):
    # Given a string containing a hex address, encode to public address format with checksum
    account_map = "13456789abcdefghijkmnopqrstuwxyz"  # each index = binary value, account_lookup['00001'] == '3'
    account_lookup = {}
    for i in range(
            0, 32
    ):  # populate lookup index for binary string to base-32 string character
        account_lookup[BitArray(uint=i, length=5).bin] = account_map[i]

    account = BitArray(hex=account)  # hex string > binary

    # get checksum
    h = blake2b(digest_size=5)
    h.update(account.bytes)
    checksum = BitArray(hex=h.hexdigest())

    # encode checksum
    checksum.byteswap(
    )  # swap bytes for compatibility with original implementation
    encode_check = ''
    for x in range(0, int(len(checksum.bin) / 5)):
        encode_check += account_lookup[checksum.bin[
            x * 5:x * 5 +
            5]]  # each 5-bit sequence = a base-32 character from account_map

    # encode account
    encode_account = ''
    while len(
            account.bin
    ) < 260:  # pad our binary value so it is 260 bits long before conversion (first value can only be 00000 '1' or 00001 '3')
        account = '0b0' + account
    for x in range(0, int(len(account.bin) / 5)):
        encode_account += account_lookup[account.bin[
            x * 5:x * 5 +
            5]]  # each 5-bit sequence = a base-32 character from account_map

    return 'xrb_' + encode_account + encode_check  # build final address string
예제 #15
0
def main():
    print "Test vectors -- set 1"
    print "====================="
    
    KEY = BitArray("0x80000000000000000000")
    print "Key : ", KEY.hex
    KEY.byteswap()
    KEY = map(int, KEY.bin)

    IV = BitArray("0x00000000000000000000")
    print "IV : ", IV.hex
    IV.byteswap()
    IV = map(int, IV.bin)

    trivium = Trivium(KEY, IV)
    generete_keystream = trivium.keystream(128)
    
    hex_keystream = '0b' + ''.join(str(i) for i in generete_keystream[::-1])
    hex_keystream = BitArray(hex_keystream)
    hex_keystream.byteswap()
    print "Keystream : ", hex_keystream.hex.upper()

    assert hex_keystream.hex.upper() == '38EB86FF730D7A9CAF8DF13A4420540D'
    print "OK"
예제 #16
0
def test_byteswap():
    ba = BitArray(f"uint:32={0x1234_5678}")
    ba.byteswap()
    assert ba.hex == '78563412'
예제 #17
0
class Trivium:
    def __init__(self, key, iv):

        self.key = plain_text_to_hexa(key)
        self.iv = plain_text_to_hexa(iv)

        self.key = BitArray(self.key)
        self.key.byteswap()
        self.key = map(int, self.key.bin)

        self.iv = BitArray(self.iv)
        self.iv.byteswap()
        self.iv = map(int, self.iv.bin)
        self.state = None

        # Initialize state
        # (s1; s2; : : : ; s93) (K1; : : : ; K80; 0; : : : ; 0)
        init_state = list(self.key)
        init_state += list(repeat(0, 13))

        # (s94; s95; : : : ; s177) (IV1; : : : ; IV80; 0; : : : ; 0)
        init_state += self.iv
        init_state += list(repeat(0, 4))

        # (s178; s279; : : : ; s288) (0; : : : ; 0; 1; 1; 1)
        init_state += list(repeat(0, 108))
        init_state += [1, 1, 1]
        if (len(init_state) < 300):
            for i in range(len(init_state), 300):
                init_state += [0]

        self.state = deque(init_state)

        # Do 4 Full cycle clock
        for i in range(4 * 288):
            self.gen_keystream()

    def gen_keystream(self):
        t_1 = self.state[65] ^ self.state[92]
        t_2 = self.state[161] ^ self.state[176]
        t_3 = self.state[242] ^ self.state[287]

        z = t_1 ^ t_2 ^ t_3

        t_1 = t_1 ^ self.state[90] & self.state[91] ^ self.state[170]
        t_2 = t_2 ^ self.state[174] & self.state[175] ^ self.state[263]
        t_3 = t_3 ^ self.state[285] & self.state[286] ^ self.state[68]

        self.state.rotate()

        self.state[0] = t_3
        self.state[93] = t_1
        self.state[177] = t_2
        return z

    def keystream(self, msglen):
        # Generete keystream
        counter = 0
        keystream = []

        while counter < msglen:
            keystream.append(self.gen_keystream())
            counter += 1

        return keystream

    def encrypt(self, msg, b64):
        result = ""
        if b64:
            msg = base64.b64decode(msg).hex()
            result = ""
            for i in range(0, len(msg), 2):
                hex_plain = "0x" + msg[i] + msg[i + 1]
                result += chr(int(str(self.general(hex_plain)), 16))
            return result
        else:
            for i in range(len(msg)):
                hex_plain = hex(ord(msg[i]))
                result += self.general(hex_plain)
            return codecs.encode(codecs.decode(str(result)[2:], 'hex'),
                                 'base64').decode().replace("\n", "")

    def general(self, hex_plain):
        keystream = self.keystream(8)
        keystream = '0b' + ''.join(str(i) for i in keystream[::-1])
        keystream = BitArray(keystream)
        plain = BitArray(hex_plain)
        cipher = [
            x ^ y
            for x, y in zip(map(int, list(plain)), map(int, list(keystream)))
        ]
        cipher = '0b' + ''.join(str(i) for i in cipher)
        return BitArray(cipher)
예제 #18
0
    def encrypt(self, msg):
        keystream = self.keystream_bytes(len(msg))

        cipher = [x ^ y for x, y in zip(msg, keystream)]

        return cipher

    def decrypt(self, msg):
        keystream = self.keystream_bytes(len(msg))

        plain = [x ^ y for x, y in zip(msg, keystream)]

        return plain


key = "0x80000000000000000000"
# Initiate grain
KEY = BitArray(key)
#print "Key : ", KEY.hex
KEY.byteswap()
KEY = map(int, KEY.bin)

iv = "0x0000000000000000"
IV = BitArray(iv)
#print "IV : ", IV.hex
IV.byteswap()
IV = map(int, IV.bin)
g = Grain(KEY, IV)
print str(g.keystream_bytes(1)[0]).format("02x")
예제 #19
0
def main():
    """
    KEY = BitArray("0x80000000000000000000")
    print "Key : ", KEY.hex
    KEY.byteswap()
    KEY = map(int, KEY.bin)

    IV = BitArray("0x00000000000000000000")
    print "IV : ", IV.hex
    IV.byteswap()
    IV = map(int, IV.bin)

    trivium = Trivium(KEY, IV)
    keystream = trivium.keystream(128)

    hex_keystream = '0b' + ''.join(str(i) for i in keystream[::-1])
    hex_keystream = BitArray(hex_keystream)
    hex_keystream.byteswap()
    print "Keystream : ", hex_keystream.hex.upper()
    """
    parser = argparse.ArgumentParser(
        description='Decryption or encryption using Trivium stream cipher.',
        epilog=
        "trivium.py -m e -k 0x80000000000000000000 -iv 0x00000000000000000000 ABCD"
    )
    parser.add_argument(
        '-m',
        '--mode',
        type=str,
        choices=['e', 'd'],
        help='Choose mode, e for encryption or d for decryption')
    parser.add_argument('-k, --key',
                        action='store',
                        dest='key',
                        type=str,
                        help='An 80 bit key e.g.: 0x0000000000000000')
    parser.add_argument(
        '-iv',
        action='store',
        dest='iv',
        type=str,
        help='An 80 bit initialization vector e.g.: 0x0000000000000000')
    parser.add_argument('M', help='Cipher text or plain text')

    args = parser.parse_args()

    # Initialize Trivium
    KEY = BitArray(args.key)
    print '{:<15}{:<2}{:<10}'.format('KEY', '=', KEY.hex)
    KEY.byteswap()
    KEY = map(int, KEY.bin)

    IV = BitArray(args.iv)
    print '{:<15}{:<2}{:<10}'.format('IV', '=', IV.hex)
    IV.byteswap()
    IV = map(int, IV.bin)

    trivium = Trivium(KEY, IV)

    # Encryption mode
    if args.mode == 'e':
        print '{:<15}{:<2}{:<10}\n'.format('PLAIN TEXT', '=', args.M)
        print '{: ^15}{: ^15}{: ^15}{: ^15}{: ^15}'.format(
            'INPUT', 'PLAIN TEXT', 'KEYSTREAM', 'CIPHER TEXT', 'OUTPUT')
        print '{:->75}'.format(' ')

        cipher = trivium.encrypt(args.M)
        cipher = '0b' + ''.join(str(i) for i in cipher)
        cipher = BitArray(cipher)
    else:
        print '{:<15}{:<2}{:<10}\n'.format('CIPHER TEXT', '=', args.M)
        print '{: ^15}{: ^15}{: ^15}{: ^15}{: ^15}'.format(
            'INPUT', 'CIPHER TEXT', 'KEYSTREAM', 'PLAIN TEXT', 'OUTPUT')
        print '{:->75}'.format(' ')
        print 'Not yet implemented'
        pass
예제 #20
0
 def calc_label_x86_imm_32_bits(self, source_instruction_address, label_address):
     b = BitArray(int=label_address, length=32)
     b.byteswap()
     return b.bin
예제 #21
0
def test_byteswap():
    """Test of BitArray - Byte swap."""
    bit_array = BitArray(f"uint:32={0x1234_5678}")
    bit_array.byteswap()
    assert bit_array.hex == "78563412"
예제 #22
0
 def calc_label_x86_rel_32_bit_cond_branch(self, source_instruction_address, label_address):
     rel = label_address - source_instruction_address - 6
     b = BitArray(int=rel, length=32)
     b.byteswap()
     return b.bin
예제 #23
0
 def testByteSwap(self):
     a = BitArray('0xff00ff00ff00')
     n = a.byteswap(2, end=32, repeat=True)
     self.assertEqual(n, 2)
     self.assertEqual(a, '0xff0000ff00ff')