From 3bef51eec2299403467e621ae660cef3f9256ac8 Mon Sep 17 00:00:00 2001 From: Determinant Date: Tue, 17 Nov 2020 18:47:40 -0500 Subject: update frozen deps --- frozen_deps/base58/__init__.py | 130 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 frozen_deps/base58/__init__.py (limited to 'frozen_deps/base58/__init__.py') diff --git a/frozen_deps/base58/__init__.py b/frozen_deps/base58/__init__.py new file mode 100644 index 0000000..ff2fa18 --- /dev/null +++ b/frozen_deps/base58/__init__.py @@ -0,0 +1,130 @@ +'''Base58 encoding + +Implementations of Base58 and Base58Check encodings that are compatible +with the bitcoin network. +''' + +# This module is based upon base58 snippets found scattered over many bitcoin +# tools written in python. From what I gather the original source is from a +# forum post by Gavin Andresen, so direct your praise to him. +# This module adds shiny packaging and support for python3. + +from hashlib import sha256 +from typing import Union + +__version__ = '2.0.1' + +# 58 character alphabet used +BITCOIN_ALPHABET = \ + b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +RIPPLE_ALPHABET = b'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz' + +# Retro compatibility +alphabet = BITCOIN_ALPHABET + + +def scrub_input(v: Union[str, bytes]) -> bytes: + if isinstance(v, str): + v = v.encode('ascii') + + return v + + +def b58encode_int( + i: int, default_one: bool = True, alphabet: bytes = BITCOIN_ALPHABET +) -> bytes: + """ + Encode an integer using Base58 + """ + if not i and default_one: + return alphabet[0:1] + string = b"" + while i: + i, idx = divmod(i, 58) + string = alphabet[idx:idx+1] + string + return string + + +def b58encode( + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET +) -> bytes: + """ + Encode a string using Base58 + """ + v = scrub_input(v) + + nPad = len(v) + v = v.lstrip(b'\0') + nPad -= len(v) + + p, acc = 1, 0 + for c in reversed(v): + acc += p * c + p = p << 8 + result = b58encode_int(acc, default_one=False, alphabet=alphabet) + return alphabet[0:1] * nPad + result + + +def b58decode_int( + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET +) -> int: + """ + Decode a Base58 encoded string as an integer + """ + v = v.rstrip() + v = scrub_input(v) + + decimal = 0 + for char in v: + decimal = decimal * 58 + alphabet.index(char) + return decimal + + +def b58decode( + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET +) -> bytes: + """ + Decode a Base58 encoded string + """ + v = v.rstrip() + v = scrub_input(v) + + origlen = len(v) + v = v.lstrip(alphabet[0:1]) + newlen = len(v) + + acc = b58decode_int(v, alphabet=alphabet) + + result = [] + while acc > 0: + acc, mod = divmod(acc, 256) + result.append(mod) + + return b'\0' * (origlen - newlen) + bytes(reversed(result)) + + +def b58encode_check( + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET +) -> bytes: + """ + Encode a string using Base58 with a 4 character checksum + """ + v = scrub_input(v) + + digest = sha256(sha256(v).digest()).digest() + return b58encode(v + digest[:4], alphabet=alphabet) + + +def b58decode_check( + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET +) -> bytes: + '''Decode and verify the checksum of a Base58 encoded string''' + + result = b58decode(v, alphabet=alphabet) + result, check = result[:-4], result[-4:] + digest = sha256(sha256(result).digest()).digest() + + if check != digest[:4]: + raise ValueError("Invalid checksum") + + return result -- cgit v1.2.3