git / moonbite-core / test/functional/test_framework/descriptors.py · raw

#!/usr/bin/env python3# Copyright (c) 2019 Pieter Wuille# Distributed under the MIT software license, see the accompanying# file COPYING or http://www.opensource.org/licenses/mit-license.php."""Utility functions related to output descriptors"""import reINPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"GENERATOR = [0xf5dee51989, 0xa9fdca3312, 0x1bab10e32d, 0x3706b1677a, 0x644d626ffd]def descsum_polymod(symbols):    """Internal function that computes the descriptor checksum."""    chk = 1    for value in symbols:        top = chk >> 35        chk = (chk & 0x7ffffffff) << 5 ^ value        for i in range(5):            chk ^= GENERATOR[i] if ((top >> i) & 1) else 0    return chkdef descsum_expand(s):    """Internal function that does the character to symbol expansion"""    groups = []    symbols = []    for c in s:        if not c in INPUT_CHARSET:            return None        v = INPUT_CHARSET.find(c)        symbols.append(v & 31)        groups.append(v >> 5)        if len(groups) == 3:            symbols.append(groups[0] * 9 + groups[1] * 3 + groups[2])            groups = []    if len(groups) == 1:        symbols.append(groups[0])    elif len(groups) == 2:        symbols.append(groups[0] * 3 + groups[1])    return symbolsdef descsum_create(s):    """Add a checksum to a descriptor without"""    symbols = descsum_expand(s) + [0, 0, 0, 0, 0, 0, 0, 0]    checksum = descsum_polymod(symbols) ^ 1    return s + '#' + ''.join(CHECKSUM_CHARSET[(checksum >> (5 * (7 - i))) & 31] for i in range(8))def descsum_check(s, require=True):    """Verify that the checksum is correct in a descriptor"""    if not '#' in s:        return not require    if s[-9] != '#':        return False    if not all(x in CHECKSUM_CHARSET for x in s[-8:]):        return False    symbols = descsum_expand(s[:-9]) + [CHECKSUM_CHARSET.find(x) for x in s[-8:]]    return descsum_polymod(symbols) == 1def drop_origins(s):    '''Drop the key origins from a descriptor'''    desc = re.sub(r'\[.+?\]', '', s)    if '#' in s:        desc = desc[:desc.index('#')]    return descsum_create(desc)