Exemple #1
0
 def test_valid_checksum(self):
     """Test checksum creation and validation."""
     for test in VALID_CHECKSUM:
         hrp, _ = bech32.bech32_decode(test)
         self.assertIsNotNone(hrp)
         pos = test.rfind('1')
         test = test[:pos+1] + chr(ord(test[pos + 1]) ^ 1) + test[pos+2:]
         hrp, _ = bech32.bech32_decode(test)
         self.assertIsNone(hrp)
Exemple #2
0
    def doit(given_addr, path=None, addr_fmt=None, script=None):
        if not script:
            try:
                # prefer using xpub if we can
                mk = BIP32Node.from_wallet_key(master_xpub)
                sk = mk.subkey_for_path(path[2:])
            except PublicPrivateMismatchError:
                mk = BIP32Node.from_wallet_key(simulator_fixed_xprv)
                sk = mk.subkey_for_path(path[2:])


        if addr_fmt == AF_CLASSIC:
            # easy
            assert sk.address() == given_addr

        elif addr_fmt & AFC_PUBKEY:

            pkh = sk.hash160(use_uncompressed=False)

            if addr_fmt == AF_P2WPKH:
                hrp, data = bech32_decode(given_addr)
                decoded = convertbits(data[1:], 5, 8, False)
                assert hrp in {'tb', 'bc' }
                assert bytes(decoded[-20:]) == pkh
            else:
                assert addr_fmt == AF_P2WPKH_P2SH
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert len(expect) == 20
                assert hash160(b'\x00\x14' + pkh) == expect

        elif addr_fmt & AFC_SCRIPT:
            assert script, 'need a redeem/witness script'
            if addr_fmt == AF_P2SH:
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert hash160(script) == expect

            elif addr_fmt == AF_P2WSH:
                hrp, data = bech32_decode(given_addr)
                assert hrp in {'tb', 'bc' }
                decoded = convertbits(data[1:], 5, 8, False)
                assert bytes(decoded[-32:]) == sha256(script).digest()

            elif addr_fmt == AF_P2WSH_P2SH:
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert hash160(b'\x00\x20' + sha256(script).digest()) == expect

            else:
                raise pytest.fail(f'not ready for {addr_fmt:x} yet')
        else:
            raise ValueError(addr_fmt)

        return sk if not script else None
Exemple #3
0
def patch(state: Optional[Dict], delegating: Optional[Dict],
          config: Config) -> Dict:
    tasks = [
        _patch_schedule_task(task, int(x["height"]), config)
        for x in state.get("tasks") or [] for task in x.get("Schedule", [])
    ]
    if delegating:
        for cluster in delegating.get("clusters", None) or []:
            t: str = modulo_to_time(cluster["modulo"], config)
            tasks.extend({
                "handler_name":
                "delegating/accrue",
                "time":
                t,
                "data":
                base64.standard_b64encode(
                    bytes(
                        bech32.convertbits(bech32.bech32_decode(acc)[1], 5,
                                           8))).decode()
            } for acc in cluster["accounts"])

    tasks.append({
        "handler_name":
        "referral/status-bonus",
        "time":
        height_to_time(((config.initial_height - 1) // ONE_WEEK_BLOCKS + 1) *
                       ONE_WEEK_BLOCKS, config)
    })

    return {
        "params": {
            "day_nanos": str(24 * 60**2 * 10**9 // config.time_quotient)
        },
        "tasks": tasks
    }
Exemple #4
0
def cardano_shelly_check(match: regex.Match):
    text = match.groupdict().get('valu')
    # Bech32 decoding
    ret = bech32.bech32_decode(text)
    if ret == (None, None):
        return None, {}
    return ('ada', text), {}
Exemple #5
0
    def doit(given_addr, path, addr_fmt):
        mk = BIP32Node.from_wallet_key(master_xpub)
        sk = mk.subkey_for_path(path[2:])

        if addr_fmt == AF_CLASSIC:
            # easy
            assert sk.address() == given_addr

        elif addr_fmt & AFC_PUBKEY:

            pkh = sk.hash160(use_uncompressed=False)

            if addr_fmt == AF_P2WPKH:
                hrp, data = bech32_decode(given_addr)
                decoded = convertbits(data[1:], 5, 8, False)
                assert hrp in {'tb', 'bc'}
                assert bytes(decoded[-20:]) == pkh
            else:
                assert addr_fmt == AF_P2WPKH_P2SH
                assert given_addr[0] in '23'
                expect = a2b_hashed_base58(given_addr)[1:]
                assert len(expect) == 20
                assert hash160(b'\x00\x14' + pkh) == expect

        elif addr_fmt & AFC_SCRIPT:
            raise pytest.fail('multisig/p2sh addr not handled')
        else:
            raise ValueError(addr_fmt)
Exemple #6
0
    def validate(self):
        decoded_address = bech32.bech32_decode(
            self.request.address.decode('utf-8'))
        hrp = decoded_address[0]
        data = decoded_address[1]

        if hrp not in self.hrp_table:
            return False

        if data is None:
            return False
        """
        test = []
        for i in data:
            test.append(hex(i))

        print(test)

        test = []
        converted  = bech32.convertbits(decoded_address[1], 5, 8, False)
        for i in converted:
            test.append(hex(i))

        print(test)
        """

        return True
def encode_fallback(fallback, currency):
    """ Encode all supported fallback addresses.
    """
    if currency == 'bc' or currency == 'tb':
        fbhrp, witness = bech32_decode(fallback)
        if fbhrp:
            if fbhrp != currency:
                raise ValueError("Not a bech32 address for this currency")
            wver = witness[0]
            if wver > 16:
                raise ValueError("Invalid witness version {}".format(
                    witness[0]))
            wprog = u5_to_bitarray(witness[1:])
        else:
            addr = base58.b58decode_check(fallback)
            if is_p2pkh(currency, addr[0]):
                wver = 17
            elif is_p2sh(currency, addr[0]):
                wver = 18
            else:
                raise ValueError(
                    "Unknown address type for {}".format(currency))
            wprog = addr[1:]
        return tagged('f', bitstring.pack("uint:5", wver) + wprog)
    else:
        raise NotImplementedError(
            "Support for currency {} not implemented".format(currency))
Exemple #8
0
def is_bech32(data: str) -> bool:
    # ignore if we are testing
    if os.environ.get("JIGU_BECH32_VALIDATE", "1") == "0":
        return True
    return bech32.bech32_decode(data) != (
        None,
        None,
    )
def test_bech32():
    testBechStr = "band1m5lq9u533qaya4q3nfyl6ulzqkpkhge9q8tpzs"
    hrp, bz = bech32_decode(testBechStr)
    assert hrp == BECH32_ADDR_ACC_PREFIX, "Invalid bech32 prefix"
    assert bz is not None, "result should not be empty"

    result = bech32_encode(BECH32_ADDR_VAL_PREFIX, bz)
    assert result == "bandvaloper1m5lq9u533qaya4q3nfyl6ulzqkpkhge9v30z8m", "invalid encoding"
Exemple #10
0
    def is_valid_address(cls, address: Address) -> bool:
        """
        Check if the address is valid.

        :param address: the address to validate
        """
        result = bech32_decode(address)
        return result != (None, None) and result[0] == cls.address_prefix
def bech32decode(bech):
    ''' Decode bech32 string into prefix and bytearray of data
    '''
    hrp, data = bech32.bech32_decode(bech)
    # Return early if we couldn't parse the input string
    if data is None:
        return hrp, False
    converted = bech32.convertbits(data, 5, 8, False)
    return hrp, converted
Exemple #12
0
 def _from_bech32(cls, bech: str, prefix: str) -> PublicKey:
     hrp, bz = bech32_decode(bech)
     assert hrp == prefix, "Invalid bech32 prefix"
     bz = convertbits(bz, 5, 8, False)
     self = cls(_error_do_not_use_init_directly=True)
     self.verify_key = VerifyingKey.from_string(
         bytes(bz[5:]), curve=SECP256k1, hashfunc=hashlib.sha256
     )
     return self
Exemple #13
0
def _bech32_decode(bech32: str,
                   *,
                   allowed_hrp: Set[str] = None) -> Tuple[str, List[int]]:
    hrp, data = bech32_decode(bech32)

    if None in (hrp, data) or (allowed_hrp and hrp not in allowed_hrp):
        raise ValueError(f"Invalid Human Readable Prefix (HRP): {hrp}.")

    return hrp, data
Exemple #14
0
def AddressTest(rpc: RPC) -> None:
    #Test a variety of valid addresses.
    for _ in range(50):
        test(rpc,
             bytes([0]) + os.urandom(32), False,
             "Meros rejected a valid address.")

    #Invalid checksum.
    invalidChecksum: str = encodeAddress(os.urandom(33))
    if invalidChecksum[-1] != 'q':
        invalidChecksum = invalidChecksum[:-1] + 'q'
    else:
        invalidChecksum = invalidChecksum[:-1] + 't'
    test(rpc, invalidChecksum, True,
         "Meros accepted an address with an invalid checksum.")

    #Invalid version byte.
    test(rpc,
         bytes([255]) + os.urandom(32), True,
         "Meros accepted an address with an invalid version byte.")

    #Invalid length.
    test(rpc, os.urandom(32), True,
         "Meros accepted an address with an invalid length.")
    test(rpc, os.urandom(34), True,
         "Meros accepted an address with an invalid length.")

    #Create a random address for us to mutate while preserving the checksum.
    randomKey: bytes = os.urandom(32)
    unchanged: str = encodeAddress(bytes([0]) + randomKey)
    #Sanity check against it.
    test(rpc, unchanged, False, "Meros rejected a valid address.")

    #Mutate it as described in https://github.com/sipa/bech32/issues/51#issuecomment-496797984.
    #Since we can insert any amount of 'q's, run this ten times.
    #It should be noted that this first insertion decodes to the same byte vector.
    #That said, the reference code is able to detect it as invalid due to its padding properties.
    #Because of that, it's noted here as an invalid case, to ensure compliance.
    for i in range(10):
        mutated: str = unchanged[:-1] + CHARSET[CHARSET.find(unchanged[-1])
                                                ^ 1]
        #Just i would be 0 on the first run, which would be a NOP.
        #Therefore, a valid and unmodified address.
        mutated += "q" * (i + 1)
        mutated = mutated[:-1] + CHARSET[CHARSET.find(mutated[-1]) ^ 1]

        #Sanity check that our mutation worked.
        decoded: Union[Tuple[None, None],
                       Tuple[str, List[int]]] = bech32_decode(mutated)
        if decoded is Tuple[None, None]:
            raise Exception("Mutation stopped the checksum from passing.")

        test(
            rpc, mutated, True,
            "Meros accepted an address which had been mutated yet still passed the checksum."
        )
Exemple #15
0
def decodeAddress(
  address: str
) -> bytes:
  decoded: Union[Tuple[None, None], Tuple[str, List[int]]] = bech32_decode(address)
  if decoded[1] is None:
    raise TestError("Decoding an invalid address.")
  res: List[int] = convertbits(decoded[1], 5, 8)
  if res[0] != 0:
    raise TestError("Decoding an address which isn't a Public Key.")
  return bytes(res[1:33])
def test_invoice_decode(node_factory, impl):
    capacity = 10**7
    node1 = node_factory.get_node(implementation=impl)

    amount = int(capacity / 10)
    payment_request = node1.invoice(amount)
    hrp, data = bech32_decode(payment_request)

    assert hrp and data
    assert hrp.startswith('lnbcrt')
Exemple #17
0
    def _from_bech32(cls, bech: str, prefix: str) -> "Address":
        hrp, bz = bech32_decode(bech)
        assert hrp == prefix, "Invalid bech32 prefix"
        if bz is None:
            raise DecodeError("Cannot decode bech32")
        eight_bit_r = convertbits(bz, 5, 8, False)
        if eight_bit_r is None:
            raise ConvertError("Cannot convert to 8 bit")

        return cls(bytes(eight_bit_r))
Exemple #18
0
    def network(self):
        decoded_address = bech32.bech32_decode(
            self.request.address.decode('utf-8'))
        hrp = decoded_address[0]

        for name, networks in self.request.currency.networks.items():
            for netw in networks:
                if hrp == netw:
                    return name

        return ""
Exemple #19
0
 def decode_bytes(bech32_string):
     try:
         hrp, data = bech32_decode(bech32_string)
     except:
         return None, None
     if not hrp:
         return None, None
     deconverted = convertbits(data, 5, 8, False)
     assert deconverted
     decoded = bytes(deconverted)
     return hrp, decoded
Exemple #20
0
def test_n_decoding():
    # We flip the signature recovery bit, which would normally give a different
    # pubkey.
    hrp, data = bech32_decode(
        lnencode(LnAddr(RHASH, amount=24, tags=[('d', '')]), PRIVKEY))
    databits = u5_to_bitarray(data)
    databits.invert(-1)
    lnaddr = lndecode(bech32_encode(hrp, bitarray_to_u5(databits)))
    assert hexlify(lnaddr.pubkey.serialize(compressed=True)) != PUBKEY

    # But not if we supply expliciy `n` specifier!
    hrp, data = bech32_decode(
        lnencode(
            LnAddr(RHASH,
                   amount=24,
                   tags=[('d', ''), ('n', unhexlify(PUBKEY))]), PRIVKEY))
    databits = u5_to_bitarray(data)
    databits.invert(-1)
    lnaddr = lndecode(bech32_encode(hrp, bitarray_to_u5(databits)))
    assert hexlify(lnaddr.pubkey.serialize(compressed=True)) == PUBKEY
Exemple #21
0
    def address_type(self):
        if len(self.request.address) == 0:
            return ""

        decoded_address = bech32.bech32_decode(
            self.request.address.decode('utf-8'))
        hrp = decoded_address[0]

        if hrp not in self.hrp_table:
            return ""

        return hrp
def bech32_to_scripthash(address):
    hrp, data = bech32.bech32_decode(address)
    witver, witprog = bech32.decode(hrp, address)
    script = [witver, len(witprog)] + witprog
    script = ''.join('{:02x}'.format(x) for x in script)
    scripthash = hashlib.sha256(binascii.unhexlify(script)).hexdigest()
    rev = ''
    i = len(scripthash) - 2
    while i >= 0:
        rev += scripthash[i:i + 2]
        i -= 2
    return rev
Exemple #23
0
def convert_prefix(in_val: str) -> str:
    prefix = ""
    for key in replaceable_map:
        if in_val.startswith(key):
            prefix = key[:-1]
            break

    if not prefix:
        raise ValueError(f"Cannot decode string {in_val}")

    _, data = bech32.bech32_decode(in_val)
    return bech32.bech32_encode(conversion_map[prefix], data)
Exemple #24
0
    def validate(self):
        decoded_address = bech32.bech32_decode(
            self.request.address.decode('utf-8'))
        data = decoded_address[1]

        if self.network == "":
            return False

        if data is None:
            return False

        return True
Exemple #25
0
def is_valid_address(address: str) -> bool:
    if not (len(address) == 43 and address.islower()):
        return False

    prefix, data = bech32_decode(address)
    if prefix is None or data is None:
        return False

    if prefix == 'htdf' and len(data) == 32:
        return True

    return False
 def __get_seed_keys(self):
     """
     retrieve the nodeids of the ln seed nodes from lseed.bitcoinstats.com
     """
     domain = "lseed.bitcoinstats.com"
     srv_records = dns.resolver.query(domain, "SRV")
     res = []
     for srv in srv_records:
         bech32 = str(srv.target).rstrip(".").split(".")[0]
         data = bech32_decode(bech32)[1]
         decoded = convertbits(data, 5, 4)
         res.append("".join(
             ['{:1x}'.format(integer) for integer in decoded])[:-1])
     return res
Exemple #27
0
def to_val_pubkey(data: AccPubKey) -> ValPubKey:
    """Converts an account pubkey into a validator pubkey.

    Args:
        data (AccPubKey): account pubkey

    Raises:
        ValueError: if provided string is not Bech32

    Returns:
        ValPubKey: validator pubkey
    """
    vals = bech32_decode(data)
    if vals[1] is None:
        raise ValueError(f"invalid bech32: {data}")
    return ValPubKey(bech32_encode("terravaloperpub", vals[1]))
Exemple #28
0
def to_val_address(data: AccAddress) -> ValAddress:
    """Converts an account address into a validator operator address.

    Args:
        data (AccAddress): account address

    Raises:
        ValueError: if provided string is not Bech32

    Returns:
        ValAddress: validator operator address
    """
    vals = bech32_decode(data)
    if vals[1] is None:
        raise ValueError(f"invalid bech32: {data}")
    return ValAddress(bech32_encode("terravaloper", vals[1]))
Exemple #29
0
def decode(pr: str) -> Invoice:
    """ Super naïve bolt11 decoder,
    only gets payment_hash, description/description_hash and amount in msatoshi.
    based on https://github.com/rustyrussell/lightning-payencode/blob/master/lnaddr.py
    """
    hrp, data = bech32_decode(pr)
    if not hrp:
        raise ValueError("Bad bech32 checksum")

    if not hrp.startswith("ln"):
        raise ValueError("Does not start with ln")

    data = u5_to_bitarray(data)

    # Final signature 65 bytes, split it off.
    if len(data) < 65 * 8:
        raise ValueError("Too short to contain signature")
    data = bitstring.ConstBitStream(data[:-65 * 8])

    invoice = Invoice()

    m = re.search("[^\d]+", hrp[2:])
    if m:
        amountstr = hrp[2 + m.end():]
        if amountstr != "":
            invoice.amount_msat = unshorten_amount(amountstr)

    # pull out date
    data.read(35).uint

    while data.pos != data.len:
        tag, tagdata, data = pull_tagged(data)

        data_length = len(tagdata) / 5

        if tag == "d":
            invoice.description = trim_to_bytes(tagdata).decode("utf-8")
        elif tag == "h" and data_length == 52:
            invoice.description = hexlify(
                trim_to_bytes(tagdata)).decode("ascii")
        elif tag == "p" and data_length == 52:
            invoice.payment_hash = hexlify(
                trim_to_bytes(tagdata)).decode("ascii")

    return invoice
Exemple #30
0
def is_valid_address(address) -> bool:
    """
    Check if given string is valid one address
    NOTE: This function is NOT thread safe due to the C function used by the bech32 library.

    Parameters
    ----------
    address: str
        String to check if valid one address

    Returns
    -------
    bool
        Is valid address
    """
    if not address.startswith('one1'):
        return False
    hrp, _ = bech32_decode(address)
    if not hrp:
        return False
    return True