-
-
Save hirokuma/bbae79effd16d8345e7fa4f5fa1d70ee to your computer and use it in GitHub Desktop.
BIP-380 output descriptors checksum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| INPUT_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 chk | |
| def 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 symbols | |
| def descsum_check(s): | |
| """Verify that the checksum is correct in a descriptor""" | |
| 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) == 1 | |
| def 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 help(): | |
| print(f"""help: | |
| {sys.argv[0]} <command> <param> | |
| command: | |
| create: create checksum | |
| check: verify checksum | |
| """) | |
| def main() -> int: | |
| if len(sys.argv) != 3: | |
| help() | |
| sys.exit(1) | |
| cmd = sys.argv[1] | |
| param = sys.argv[2] | |
| if cmd == "create": | |
| sum = descsum_create(param) | |
| print(f"sum={sum}") | |
| elif cmd == "check": | |
| chk = descsum_check(param) | |
| print(f"valid={chk}") | |
| else: | |
| help() | |
| return 0 | |
| if __name__ == '__main__': | |
| main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
BIP-380 TestVectors