コード例 #1
0
    def test_afi_0_without_prefixlen(self):
        '''
        Test en/decoding of empty AFI addresses
        '''
        afi_address_hex = '0000'
        bitstream = ConstBitStream(hex=afi_address_hex)

        address = afi.read_afi_address_from_bitstream(bitstream)

        self.assertIsNone(address, 'wrong address')
        self.assertEqual(bitstream.pos, bitstream.len,
                         'unprocessed bits remaining in bitstream')

        new_bitstream = afi.get_bitstream_for_afi_address(address)

        self.assertEqual(new_bitstream.tobytes(), bitstream.tobytes())
コード例 #2
0
    def test_afi_1_with_prefixlen(self):
        '''
        Test decoding of AFI 1 (IPv4) prefixes
        '''
        afi_address_hex = '0001c0000200'
        bitstream = ConstBitStream(hex=afi_address_hex)

        address = afi.read_afi_address_from_bitstream(bitstream, 24)

        self.assertEqual(address, IPv4Network(u'192.0.2.0/24'))
        self.assertEqual(bitstream.pos, bitstream.len,
                         'unprocessed bits remaining in bitstream')

        new_bitstream = afi.get_bitstream_for_afi_address(address)

        self.assertEqual(new_bitstream.tobytes(), bitstream.tobytes())
コード例 #3
0
    def test_afi_2_with_prefixlen(self):
        '''
        Test decoding of AFI 2 (IPv6) prefixes
        '''
        afi_address_hex = '000220010db80102abcd0000000000000000'
        bitstream = ConstBitStream(hex=afi_address_hex)

        address = afi.read_afi_address_from_bitstream(bitstream, 64)

        self.assertEqual(address, IPv6Network(u'2001:db8:102:abcd::/64'))
        self.assertEqual(bitstream.pos, bitstream.len,
                         'unprocessed bits remaining in bitstream')

        new_bitstream = afi.get_bitstream_for_afi_address(address)

        self.assertEqual(new_bitstream.tobytes(), bitstream.tobytes())
コード例 #4
0
    def test_afi_0_with_prefixlen_0(self):
        '''
        Although a prefix length of 0 is allowed (since that is how many
        implementations transmit it on the wire)
        '''
        afi_address_hex = '0000'
        bitstream = ConstBitStream(hex=afi_address_hex)

        address = afi.read_afi_address_from_bitstream(bitstream, 0)

        self.assertIsNone(address, 'wrong address')
        self.assertEqual(bitstream.pos, bitstream.len,
                         'unprocessed bits remaining in bitstream')

        new_bitstream = afi.get_bitstream_for_afi_address(address)

        self.assertEqual(new_bitstream.tobytes(), bitstream.tobytes())
コード例 #5
0
def generateFrameHeader(streamSHA, frameHashableBits, frameNumber, blocksUsed):
    '''This creates the header that is present at the beginning of every frame (excluding the first frame or image
    outputs).  These headers orient the reader, in that it tells it where it is in the stream.
    '''

    fullBitString = BitArray()

    fullBitString.append(BitArray(hex=streamSHA))
    tempPayloadHolding = ConstBitStream(frameHashableBits)
    shaHasher = hashlib.sha256()
    shaHasher.update(tempPayloadHolding.tobytes())
    frameSHA = shaHasher.digest()

    fullBitString.append(BitArray(bytes=frameSHA))
    fullBitString.append(BitArray(uint=frameNumber, length=32))
    fullBitString.append(BitArray(uint=blocksUsed, length=32))
    fullBitStringToHash = fullBitString.bytes

    crcOutput = zlib.crc32(fullBitStringToHash)
    fullBitString.append(BitArray(uint=crcOutput, length=32))

    return fullBitString
コード例 #6
0
def generate_frame_header(stream_sha, frame_hashable_bits, frame_number,
                          blocks_used):
    '''This creates the header that is present at the beginning of every frame (excluding the first frame or image
    outputs).  These headers orient the reader, in that it tells it where it is in the stream.
    '''

    full_bit_string = BitArray()

    full_bit_string.append(BitArray(hex=stream_sha))
    temp_payload_holding = ConstBitStream(frame_hashable_bits)
    sha_hasher = hashlib.sha256()
    sha_hasher.update(temp_payload_holding.tobytes())
    frame_sha = sha_hasher.digest()

    full_bit_string.append(BitArray(bytes=frame_sha))
    full_bit_string.append(BitArray(uint=frame_number, length=32))
    full_bit_string.append(BitArray(uint=blocks_used, length=32))
    full_bit_string_to_hash = full_bit_string.bytes

    crc_output = zlib.crc32(full_bit_string_to_hash)
    full_bit_string.append(BitArray(uint=crc_output, length=32))

    return full_bit_string
コード例 #7
0
ファイル: pydubbo.py プロジェクト: morningzhang/dubbo
    def _invoke(self, client):
        data = self._encode(encoder.Encoder())
        reg_header = ConstBitStream(
            'intbe:16=-9541,intbe:8=-62,intbe:8=0,uintbe:64=0,uintbe:32=%d' %
            len(data))
        client.send(reg_header.bytes)
        client.send(data)

        res_header = ConstBitStream(bytes=client.recv(16)).readlist(
            'intbe:16,intbe:8,intbe:8,uintbe:64,uintbe:32')
        length = res_header[-1]

        bytes = []
        while length > 0:
            data = client.recv(1024)
            bytes.append(data)
            length -= len(data)

        body = ConstBitStream(bytes=b"".join(bytes))
        resp_code = body.read('uintbe:8')
        if resp_code == RespCode.RESPONSE_NULL_VALUE or resp_code == RespCode.RESPONSE_NULL_VALUE_WITH_ATTACHMENTS:
            return None
        elif resp_code == RespCode.RESPONSE_WITH_EXCEPTION or resp_code == RespCode.RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS:
            p = parser.ParserV2(body)
            res = p.read_object()
            raise Exception(res)
        elif resp_code == RespCode.RESPONSE_VALUE or resp_code == RespCode.RESPONSE_NULL_VALUE_WITH_ATTACHMENTS:
            p = parser.ParserV2(body)
            res = p.read_object()
            return res
        elif resp_code == 148:
            p = parser.ParserV2(body)
            res = p.read_object()
            return res
        else:
            print(body.tobytes())
コード例 #8
0
    while (len(s) - s.pos) > 0:
        if (len(s) - s.pos) <= num_encoded_bits_per_word:
            num_bits_to_read = len(s) - s.pos
        index = s.read(num_bits_to_read).uint
        print(dictionary[index] + " ", end='')
        if (counter % 5) == 4:
            print("")
        counter += 1

    print("{}".format(num_bits_to_read))
    sys.stderr.write("encoded {} bytes to {} words\n".format(
        int(len(s) / 8), counter))
else:
    with open(args.file_to_encode_or_decode, "r") as f:
        words_to_decode = f.read()

    s = BitArray()
    words = words_to_decode.split()[0:-2]
    for word in words:
        index = dictionary[word]
        s.append(
            BitArray('uint:{}={}'.format(num_encoded_bits_per_word, index)))

    word = words_to_decode.split()[-2]
    index = dictionary[word]
    num_bits_to_encode = int(words_to_decode.split()[-1])
    s.append(BitArray('uint:{}={}'.format(num_bits_to_encode, index)))
    with open(args.decode, "wb") as f:
        f.write(s.tobytes())
コード例 #9
0
ファイル: core.py プロジェクト: lnbits/bolt11
def decode(bech32_pr: str) -> LightningInvoice:
    hrp, bech32_data = bech32_decode(bech32_pr)
    route_hints = []
    tags = {}

    if not hrp or not bech32_data or not hrp.startswith("ln"):
        raise ValueError("Bech32 is not valid.")

    matches = re.match(r"ln(bc|bcrt|tb)(\w+)?", hrp)
    assert matches, "Human readable part is not valid."

    currency, amount_str = matches.groups()
    data_part = u5_to_bitarray(bech32_data)

    # Final signature is 65 bytes, split it off.
    # signature =>
    # "a valid 512-bit secp256k1 signature of the SHA2 256-bit hash of the human-readable part
    # represented as UTF-8 bytes, concatenated with the data part (excluding the signature) with 0 bits appended
    # to pad the data to the next byte boundary, with a trailing byte containing the recovery ID (0, 1, 2, or 3)"

    if len(data_part) < 65 * 8:
        raise ValueError("Too short to contain signature")

    signature_data = data_part[-65 * 8:].tobytes()
    data = ConstBitStream(data_part[:-65 * 8])
    signature = Signature(data=signature_data,
                          signing_data=(hrp.encode("utf-8") + data.tobytes()))
    timestamp = data.read(35).uint

    # Look for tags in data

    while data.pos != data.len:
        tag, tagdata, data = _pull_tagged(data)
        data_length = len(tagdata) // 5

        if tag == "p" and data_length == 52:
            # p (1): data_length 52. 256-bit SHA256 payment_hash. Preimage of this provides proof of payment.
            tags["p"] = trim_to_bytes(tagdata).hex()

        elif tag == "x":
            # x (6): data_length variable. expiry time in seconds (big-endian). Default is 3600.
            tags["x"] = tagdata.uint

        elif tag == "d":
            # d (13): data_length variable. Short description of purpose of payment (UTF-8).
            tags["d"] = trim_to_bytes(tagdata).decode("utf-8")

        elif tag == "h" and data_length == 52:
            # h (23): data_length 52. 256-bit description of purpose of payment (SHA256).
            tags["h"] = trim_to_bytes(tagdata).hex()

        elif tag == "s" and data_length == 52:
            # s (16): data_length 52. This 256-bit secret prevents forwarding nodes from probing the payment recipient.
            tags["s"] = trim_to_bytes(tagdata).hex()

        elif tag == "c":
            # c (24): data_length variable. min_final_cltv_expiry to use for the last HTLC in the route. Default is 9.
            tags["c"] = tagdata.uint

        elif tag == "n" and data_length == 53:
            # n (19): data_length 53. 33-byte public key of the payee node.
            tags["n"] = trim_to_bytes(tagdata).hex()

        elif tag == "f":
            # f (9): data_length variable, depending on version. Fallback on-chain address.
            tags["f"] = _parse_fallback(tagdata, currency)

        elif tag == "r":
            # r (3): `data_length` variable.
            # One or more entries containing extra routing information for a private route;
            # there may be more than one `r` field, too.
            #  * `pubkey` (264 bits)
            #  * `short_channel_id` (64 bits)
            #  * `feebase` (32 bits, big-endian)
            #  * `feerate` (32 bits, big-endian)
            #  * `cltv_expiry_delta` (16 bits, big-endian)
            s = ConstBitStream(tagdata)

            while s.pos + 264 + 64 + 32 + 32 + 16 < s.len:
                route_hints.append(
                    Route(
                        public_key=s.read(264).tobytes().hex(),
                        short_channel_id=_readable_scid(s.read(64).intbe),
                        base_fee=MilliSatoshi(s.read(32).intbe),
                        ppm_fee=s.read(32).intbe,
                        cltv_expiry_delta=s.read(16).intbe,
                    ))

    # A reader MUST use the `n` field to validate the signature instead of
    # performing signature recovery if a valid `n` field is provided.

    message = bytearray([ord(c) for c in hrp]) + data.tobytes()
    sig = signature_data[0:64]

    if "n" in tags:
        payee_public_key = tags["n"]
        vk = VerifyingKey.from_string(unhexlify(payee_public_key),
                                      curve=SECP256k1)
        if not vk.verify(sig, message, sha256, sigdecode=sigdecode_string):
            raise ValueError("Could not verify public key")
    else:
        vk = VerifyingKey.from_public_key_recovery(sig, message, SECP256k1,
                                                   sha256)
        signaling_byte = signature_data[64]
        key = vk[int(signaling_byte)]
        payee_public_key = key.to_string("compressed").hex()

    return LightningInvoice(
        amount=amount_to_msat(amount_str) if amount_str else None,
        currency=currency,
        timestamp=timestamp,
        payee_public_key=payee_public_key,
        route_hints=route_hints,
        signature=signature,
        tags=tags,
    )