You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

#### 145 lines 3.5 KiB Python Raw Blame History

 ```# pylint: disable=missing-docstring,too-many-function-args ``` ``` ``` ```import hashlib ``` ```import re ``` ``` ``` ```P = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 ``` ```A = 0 ``` ```Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 ``` ```Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 ``` ```G = (Gx, Gy) ``` ``` ``` ``` ``` ```def inv(a, n): ``` ``` lm, hm = 1, 0 ``` ``` low, high = a % n, n ``` ``` while low > 1: ``` ``` r = high / low ``` ``` nm, new = hm - lm * r, high - low * r ``` ``` lm, low, hm, high = nm, new, lm, low ``` ``` return lm % n ``` ``` ``` ``` ``` ```def get_code_string(base): ``` ``` if base == 2: ``` ``` return '01' ``` ``` elif base == 10: ``` ``` return '0123456789' ``` ``` elif base == 16: ``` ``` return "0123456789abcdef" ``` ``` elif base == 58: ``` ``` return "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ``` ``` elif base == 256: ``` ``` return ''.join([chr(x) for x in range(256)]) ``` ``` else: ``` ``` raise ValueError("Invalid base!") ``` ``` ``` ``` ``` ```def encode(val, base, minlen=0): ``` ``` code_string = get_code_string(base) ``` ``` result = "" ``` ``` while val > 0: ``` ``` result = code_string[val % base] + result ``` ``` val /= base ``` ``` if len(result) < minlen: ``` ``` result = code_string[0] * (minlen - len(result)) + result ``` ``` return result ``` ``` ``` ``` ``` ```def decode(string, base): ``` ``` code_string = get_code_string(base) ``` ``` result = 0 ``` ``` if base == 16: ``` ``` string = string.lower() ``` ``` while string: ``` ``` result *= base ``` ``` result += code_string.find(string[0]) ``` ``` string = string[1:] ``` ``` return result ``` ``` ``` ``` ``` ```def changebase(string, frm, to, minlen=0): ``` ``` return encode(decode(string, frm), to, minlen) ``` ``` ``` ``` ``` ```def base10_add(a, b): ``` ``` if a is None: ``` ``` return b[0], b[1] ``` ``` if b is None: ``` ``` return a[0], a[1] ``` ``` if a[0] == b[0]: ``` ``` if a[1] == b[1]: ``` ``` return base10_double(a[0], a[1]) ``` ``` return None ``` ``` m = ((b[1] - a[1]) * inv(b[0] - a[0], P)) % P ``` ``` x = (m * m - a[0] - b[0]) % P ``` ``` y = (m * (a[0] - x) - a[1]) % P ``` ``` return (x, y) ``` ``` ``` ``` ``` ```def base10_double(a): ``` ``` if a is None: ``` ``` return None ``` ``` m = ((3 * a[0] * a[0] + A) * inv(2 * a[1], P)) % P ``` ``` x = (m * m - 2 * a[0]) % P ``` ``` y = (m * (a[0] - x) - a[1]) % P ``` ``` return (x, y) ``` ``` ``` ``` ``` ```def base10_multiply(a, n): ``` ``` if n == 0: ``` ``` return G ``` ``` if n == 1: ``` ``` return a ``` ``` if (n % 2) == 0: ``` ``` return base10_double(base10_multiply(a, n / 2)) ``` ``` if (n % 2) == 1: ``` ``` return base10_add(base10_double(base10_multiply(a, n / 2)), a) ``` ``` return None ``` ``` ``` ``` ``` ```def hex_to_point(h): ``` ``` return (decode(h[2:66], 16), decode(h[66:], 16)) ``` ``` ``` ``` ``` ```def point_to_hex(p): ``` ``` return '04' + encode(p[0], 16, 64) + encode(p[1], 16, 64) ``` ``` ``` ``` ``` ```def multiply(privkey, pubkey): ``` ``` return point_to_hex(base10_multiply(hex_to_point(pubkey), decode(privkey, 16))) ``` ``` ``` ``` ``` ```def privtopub(privkey): ``` ``` return point_to_hex(base10_multiply(G, decode(privkey, 16))) ``` ``` ``` ``` ``` ```def add(p1, p2): ``` ``` if len(p1) == 32: ``` ``` return encode(decode(p1, 16) + decode(p2, 16) % P, 16, 32) ``` ``` return point_to_hex(base10_add(hex_to_point(p1), hex_to_point(p2))) ``` ``` ``` ``` ``` ```def hash_160(string): ``` ``` intermed = hashlib.sha256(string).digest() ``` ``` ripemd160 = hashlib.new('ripemd160') ``` ``` ripemd160.update(intermed) ``` ``` return ripemd160.digest() ``` ``` ``` ``` ``` ```def dbl_sha256(string): ``` ``` return hashlib.sha256(hashlib.sha256(string).digest()).digest() ``` ``` ``` ``` ``` ```def bin_to_b58check(inp): ``` ``` inp_fmtd = '\x00' + inp ``` ``` leadingzbytes = len(re.match('^\x00*', inp_fmtd).group(0)) ``` ``` checksum = dbl_sha256(inp_fmtd)[:4] ``` ``` return '1' * leadingzbytes + changebase(inp_fmtd + checksum, 256, 58) ``` ``` ``` ```# Convert a public key (in hex) to a Bitcoin address ``` ``` ``` ``` ``` ```def pubkey_to_address(pubkey): ``` ``` return bin_to_b58check(hash_160(changebase(pubkey, 16, 256))) ```