python-bip32utils-0.0~git20170118.dd9c541/0000755000175000017500000000000013037714212017022 5ustar noahfxnoahfxpython-bip32utils-0.0~git20170118.dd9c541/bip32utils/0000755000175000017500000000000013037714212021022 5ustar noahfxnoahfxpython-bip32utils-0.0~git20170118.dd9c541/bip32utils/Base58.py0000755000175000017500000000411313037714212022425 0ustar noahfxnoahfx#!/usr/bin/env python # # Copyright 2014 Corgan Labs # See LICENSE.txt for distribution terms # from hashlib import sha256 __base58_alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' __base58_alphabet_bytes = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' __base58_radix = len(__base58_alphabet) def __string_to_int(data): "Convert string of bytes Python integer, MSB" val = 0 # Python 2.x compatibility if type(data) == str: data = bytearray(data) for (i, c) in enumerate(data[::-1]): val += (256**i)*c return val def encode(data): "Encode bytes into Bitcoin base58 string" enc = '' val = __string_to_int(data) while val >= __base58_radix: val, mod = divmod(val, __base58_radix) enc = __base58_alphabet[mod] + enc if val: enc = __base58_alphabet[val] + enc # Pad for leading zeroes n = len(data)-len(data.lstrip(b'\0')) return __base58_alphabet[0]*n + enc def check_encode(raw): "Encode raw bytes into Bitcoin base58 string with checksum" chk = sha256(sha256(raw).digest()).digest()[:4] return encode(raw+chk) def decode(data): "Decode Bitcoin base58 format string to bytes" # Python 2.x compatability if bytes != str: data = bytes(data, 'ascii') val = 0 for (i, c) in enumerate(data[::-1]): val += __base58_alphabet_bytes.find(c) * (__base58_radix**i) dec = bytearray() while val >= 256: val, mod = divmod(val, 256) dec.append(mod) if val: dec.append(val) return bytes(dec[::-1]) def check_decode(enc): "Decode bytes from Bitcoin base58 string and test checksum" dec = decode(enc) raw, chk = dec[:-4], dec[-4:] if chk != sha256(sha256(raw).digest()).digest()[:4]: raise ValueError("base58 decoding checksum error") else: return raw if __name__ == '__main__': assert(__base58_radix == 58) data = b'now is the time for all good men to come to the aid of their country' enc = check_encode(data) assert(check_decode(enc) == data) python-bip32utils-0.0~git20170118.dd9c541/bip32utils/BIP32Key.py0000755000175000017500000003236113037714212022634 0ustar noahfxnoahfx#!/usr/bin/env python # # Copyright 2014 Corgan Labs # See LICENSE.txt for distribution terms # import os import hmac import hashlib import ecdsa import struct import codecs from . import Base58 from hashlib import sha256 from ecdsa.curves import SECP256k1 from ecdsa.ecdsa import int_to_string, string_to_int from ecdsa.numbertheory import square_root_mod_prime as sqrt_mod MIN_ENTROPY_LEN = 128 # bits BIP32_HARDEN = 0x80000000 # choose from hardened set of child keys CURVE_GEN = ecdsa.ecdsa.generator_secp256k1 CURVE_ORDER = CURVE_GEN.order() FIELD_ORDER = SECP256k1.curve.p() INFINITY = ecdsa.ellipticcurve.INFINITY EX_MAIN_PRIVATE = codecs.decode('0488ade4', 'hex') # Version string for mainnet extended private keys EX_MAIN_PUBLIC = codecs.decode('0488b21e', 'hex') # Version string for mainnet extended public keys EX_TEST_PRIVATE = codecs.decode('04358394', 'hex') # Version string for testnet extended private keys EX_TEST_PUBLIC = codecs.decode('043587CF', 'hex') # Version string for testnet extended public keys class BIP32Key(object): # Static initializers to create from entropy or external formats # @staticmethod def fromEntropy(entropy, public=False, testnet=False): "Create a BIP32Key using supplied entropy >= MIN_ENTROPY_LEN" if entropy == None: entropy = os.urandom(MIN_ENTROPY_LEN/8) # Python doesn't have os.random() if not len(entropy) >= MIN_ENTROPY_LEN/8: raise ValueError("Initial entropy %i must be at least %i bits" % (len(entropy), MIN_ENTROPY_LEN)) I = hmac.new(b"Bitcoin seed", entropy, hashlib.sha512).digest() Il, Ir = I[:32], I[32:] # FIXME test Il for 0 or less than SECP256k1 prime field order key = BIP32Key(secret=Il, chain=Ir, depth=0, index=0, fpr=b'\0\0\0\0', public=False, testnet=testnet) if public: key.SetPublic() return key @staticmethod def fromExtendedKey(xkey, public=False): """ Create a BIP32Key by importing from extended private or public key string If public is True, return a public-only key regardless of input type. """ # Sanity checks raw = Base58.check_decode(xkey) if len(raw) != 78: raise ValueError("extended key format wrong length") # Verify address version/type version = raw[:4] if version == EX_MAIN_PRIVATE: is_testnet = False is_pubkey = False elif version == EX_TEST_PRIVATE: is_testnet = True is_pubkey = False elif version == EX_MAIN_PUBLIC: is_testnet = False is_pubkey = True elif version == EX_TEST_PUBLIC: is_testnet = True is_pubkey = True else: raise ValueError("unknown extended key version") # Extract remaining fields # Python 2.x compatibility if type(raw[4]) == int: depth = raw[4] else: depth = ord(raw[4]) fpr = raw[5:9] child = struct.unpack(">L", raw[9:13])[0] chain = raw[13:45] secret = raw[45:78] # Extract private key or public key point if not is_pubkey: secret = secret[1:] else: # Recover public curve point from compressed key # Python3 FIX lsb = secret[0] & 1 if type(secret[0]) == int else ord(secret[0]) & 1 x = string_to_int(secret[1:]) ys = (x**3+7) % FIELD_ORDER # y^2 = x^3 + 7 mod p y = sqrt_mod(ys, FIELD_ORDER) if y & 1 != lsb: y = FIELD_ORDER-y point = ecdsa.ellipticcurve.Point(SECP256k1.curve, x, y) secret = ecdsa.VerifyingKey.from_public_point(point, curve=SECP256k1) key = BIP32Key(secret=secret, chain=chain, depth=depth, index=child, fpr=fpr, public=is_pubkey, testnet=is_testnet) if not is_pubkey and public: key = key.SetPublic() return key # Normal class initializer def __init__(self, secret, chain, depth, index, fpr, public=False, testnet=False): """ Create a public or private BIP32Key using key material and chain code. secret This is the source material to generate the keypair, either a 32-byte string representation of a private key, or the ECDSA library object representing a public key. chain This is a 32-byte string representation of the chain code depth Child depth; parent increments its own by one when assigning this index Child index fpr Parent fingerprint public If true, this keypair will only contain a public key and can only create a public key chain. """ self.public = public if public is False: self.k = ecdsa.SigningKey.from_string(secret, curve=SECP256k1) self.K = self.k.get_verifying_key() else: self.k = None self.K = secret self.C = chain self.depth = depth self.index = index self.parent_fpr = fpr self.testnet = testnet # Internal methods not intended to be called externally # def hmac(self, data): """ Calculate the HMAC-SHA512 of input data using the chain code as key. Returns a tuple of the left and right halves of the HMAC """ I = hmac.new(self.C, data, hashlib.sha512).digest() return (I[:32], I[32:]) def CKDpriv(self, i): """ Create a child key of index 'i'. If the most significant bit of 'i' is set, then select from the hardened key set, otherwise, select a regular child key. Returns a BIP32Key constructed with the child key parameters, or None if i index would result in an invalid key. """ # Index as bytes, BE i_str = struct.pack(">L", i) # Data to HMAC if i & BIP32_HARDEN: data = b'\0' + self.k.to_string() + i_str else: data = self.PublicKey() + i_str # Get HMAC of data (Il, Ir) = self.hmac(data) # Construct new key material from Il and current private key Il_int = string_to_int(Il) if Il_int > CURVE_ORDER: return None pvt_int = string_to_int(self.k.to_string()) k_int = (Il_int + pvt_int) % CURVE_ORDER if (k_int == 0): return None secret = (b'\0'*32 + int_to_string(k_int))[-32:] # Construct and return a new BIP32Key return BIP32Key(secret=secret, chain=Ir, depth=self.depth+1, index=i, fpr=self.Fingerprint(), public=False, testnet=self.testnet) def CKDpub(self, i): """ Create a publicly derived child key of index 'i'. If the most significant bit of 'i' is set, this is an error. Returns a BIP32Key constructed with the child key parameters, or None if index would result in invalid key. """ if i & BIP32_HARDEN: raise Exception("Cannot create a hardened child key using public child derivation") # Data to HMAC. Same as CKDpriv() for public child key. data = self.PublicKey() + struct.pack(">L", i) # Get HMAC of data (Il, Ir) = self.hmac(data) # Construct curve point Il*G+K Il_int = string_to_int(Il) if Il_int >= CURVE_ORDER: return None point = Il_int*CURVE_GEN + self.K.pubkey.point if point == INFINITY: return None # Retrieve public key based on curve point K_i = ecdsa.VerifyingKey.from_public_point(point, curve=SECP256k1) # Construct and return a new BIP32Key return BIP32Key(secret=K_i, chain=Ir, depth=self.depth+1, index=i, fpr=self.Fingerprint(), public=True, testnet=self.testnet) # Public methods # def ChildKey(self, i): """ Create and return a child key of this one at index 'i'. The index 'i' should be summed with BIP32_HARDEN to indicate to use the private derivation algorithm. """ if self.public is False: return self.CKDpriv(i) else: return self.CKDpub(i) def SetPublic(self): "Convert a private BIP32Key into a public one" self.k = None self.public = True def PrivateKey(self): "Return private key as string" if self.public: raise Exception("Publicly derived deterministic keys have no private half") else: return self.k.to_string() def PublicKey(self): "Return compressed public key encoding" padx = (b'\0'*32 + int_to_string(self.K.pubkey.point.x()))[-32:] if self.K.pubkey.point.y() & 1: ck = b'\3'+padx else: ck = b'\2'+padx return ck def ChainCode(self): "Return chain code as string" return self.C def Identifier(self): "Return key identifier as string" cK = self.PublicKey() return hashlib.new('ripemd160', sha256(cK).digest()).digest() def Fingerprint(self): "Return key fingerprint as string" return self.Identifier()[:4] def Address(self): "Return compressed public key address" addressversion = b'\x00' if not self.testnet else b'\x6f' vh160 = addressversion + self.Identifier() return Base58.check_encode(vh160) def WalletImportFormat(self): "Returns private key encoded for wallet import" if self.public: raise Exception("Publicly derived deterministic keys have no private half") addressversion = b'\x80' if not self.testnet else b'\xef' raw = addressversion + self.k.to_string() + b'\x01' # Always compressed return Base58.check_encode(raw) def ExtendedKey(self, private=True, encoded=True): "Return extended private or public key as string, optionally Base58 encoded" if self.public is True and private is True: raise Exception("Cannot export an extended private key from a public-only deterministic key") if not self.testnet: version = EX_MAIN_PRIVATE if private else EX_MAIN_PUBLIC else: version = EX_TEST_PRIVATE if private else EX_TEST_PUBLIC depth = bytes(bytearray([self.depth])) fpr = self.parent_fpr child = struct.pack('>L', self.index) chain = self.C if self.public is True or private is False: data = self.PublicKey() else: data = b'\x00' + self.PrivateKey() raw = version+depth+fpr+child+chain+data if not encoded: return raw else: return Base58.check_encode(raw) # Debugging methods # def dump(self): "Dump key fields mimicking the BIP0032 test vector format" print(" * Identifier") print(" * (hex): ", self.Identifier().encode('hex')) print(" * (fpr): ", self.Fingerprint().encode('hex')) print(" * (main addr):", self.Address()) if self.public is False: print(" * Secret key") print(" * (hex): ", self.PrivateKey().encode('hex')) print(" * (wif): ", self.WalletImportFormat()) print(" * Public key") print(" * (hex): ", self.PublicKey().encode('hex')) print(" * Chain code") print(" * (hex): ", self.C.encode('hex')) print(" * Serialized") print(" * (pub hex): ", self.ExtendedKey(private=False, encoded=False).encode('hex')) print(" * (prv hex): ", self.ExtendedKey(private=True, encoded=False).encode('hex')) print(" * (pub b58): ", self.ExtendedKey(private=False, encoded=True)) print(" * (prv b58): ", self.ExtendedKey(private=True, encoded=True)) if __name__ == "__main__": import sys # BIP0032 Test vector 1 entropy='000102030405060708090A0B0C0D0E0F'.decode('hex') m = BIP32Key.fromEntropy(entropy) print("Test vector 1:") print("Master (hex):", entropy.encode('hex')) print("* [Chain m]") m.dump() print("* [Chain m/0h]") m = m.ChildKey(0+BIP32_HARDEN) m.dump() print("* [Chain m/0h/1]") m = m.ChildKey(1) m.dump() print("* [Chain m/0h/1/2h]") m = m.ChildKey(2+BIP32_HARDEN) m.dump() print("* [Chain m/0h/1/2h/2]") m = m.ChildKey(2) m.dump() print("* [Chain m/0h/1/2h/2/1000000000]") m = m.ChildKey(1000000000) m.dump() # BIP0032 Test vector 2 entropy = 'fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542'.decode('hex') m = BIP32Key.fromEntropy(entropy) print("Test vector 2:") print("Master (hex):", entropy.encode('hex')) print("* [Chain m]") m.dump() print("* [Chain m/0]") m = m.ChildKey(0) m.dump() print("* [Chain m/0/2147483647h]") m = m.ChildKey(2147483647+BIP32_HARDEN) m.dump() print("* [Chain m/0/2147483647h/1]") m = m.ChildKey(1) m.dump() print("* [Chain m/0/2147483647h/1/2147483646h]") m = m.ChildKey(2147483646+BIP32_HARDEN) m.dump() print("* [Chain m/0/2147483647h/1/2147483646h/2]") m = m.ChildKey(2) m.dump() python-bip32utils-0.0~git20170118.dd9c541/bip32utils/__init__.py0000644000175000017500000000007013037714212023130 0ustar noahfxnoahfxfrom bip32utils.BIP32Key import BIP32Key, BIP32_HARDEN python-bip32utils-0.0~git20170118.dd9c541/bip32gen0000755000175000017500000002242213037714212020363 0ustar noahfxnoahfx#!/usr/bin/env python # # Copyright 2014 Corgan Labs # See LICENSE.txt for distribution terms # import os, sys, argparse, re from bip32utils import * # __main__ entrypoint at bottom def ReadInput(fname, count, is_hex): "Read input from either stdin or file, optionally hex decoded" f = sys.stdin if fname == '-' else open(fname, 'rb') with f: if count is not None: n = count*2 if is_hex else count data = f.read(n) else: data = f.read() if is_hex: data = data.strip().decode('hex') return data def WriteOutput(fname, prefix, data, is_hex): "Write output to either stdout or file, optionally hex encoded" if is_hex: data = data.encode('hex') f= sys.stdout if fname == '-' else open(fname, 'w') f.write(prefix+data+'\n') def ParseKeyspec(args, input_data, keyspec, cache): """ Create a key from key specification with common args, storing intermediate keys in a cache for reuse. Assumes keyspec format already validated with regex. There are three sources of input for key generation: * Supplying entropy from stdin or file, from which the master key and seed will be generated per BIP0032. This is one option for keyspecs starting with 'm/...' or 'M/...'. Keyspecs starting with 'M' result in public- only keys. From this master key, they keyspec is recursively parsed to create child keys using the indices found in the keyspec. * Supplying an extended private key, which is imported back into a normal key. From this, normal or hardened child keys are recursively derived using the private derivation algorithm and index numbers in the keyspec. The returned key is capable of generating further normal or hardened child keys. * Supplying an extended public key, which is imported back into a public-only key. From this, public-only keys are recursively derived using the public derivation algorithm and index numbers in the keyspec. The returned key does not have a private key half and is only further capable of generating publicly derived child keys. """ key = None acc = '' # Generate initial key, either from entropy, xprv, or xpub if args.input_type == 'entropy': acc = keyspec.split('/')[0] try: key = cache[acc] except KeyError: public = (acc == 'M') key = BIP32Key.fromEntropy(entropy=input_data['entropy'], public=public, testnet=args.testnet) cache[acc] = key elif args.input_type == 'xprv': try: key = cache['xprv'] except KeyError: key = BIP32Key.fromExtendedKey(input_data['xprv']) cache['xprv'] = key else: try: key = cache['xpub'] except KeyError: key = BIP32Key.fromExtendedKey(input_data['xpub']) cache['xpub'] = key # Parse nodes, build up intermediate keys for node in keyspec.split('/'): if node in ['m', 'M']: key = cache[node] else: # Descendent or relative node if acc == '': acc = node else: acc = acc + '/' + node try: key = cache[acc] except KeyError: if key is None: key = cache[args.input_type] # Now generate child keys i = int(node.split('h')[0]) if 'h' in node: i = i + BIP32_HARDEN key = key.ChildKey(i) cache[acc] = key return key # Input sources def ReadEntropy(args): "Reads optionally hex-encoded data from source" entropy = ReadInput(args.from_file, args.amount/8, args.input_hex) if len(entropy) < args.amount/8: raise Exception("Insufficient entropy provided") if args.verbose: src = 'stdin' if args.from_file == '-' else args.from_file print("Creating master key and seed using %i bits of entropy read from %s" % (args.amount, src)) print("entropy: %s" % entropy.encode('hex')) return entropy valid_output_types = ['addr','privkey','wif','pubkey','xprv','xpub','chain'] def GetArgs(): "Parse command line and validate inputs" parser = argparse.ArgumentParser(description='Create hierarchical deterministic wallet addresses') parser.add_argument('-x', '--input-hex', action='store_true', default=False, help='input supplied as hex-encoded ascii') parser.add_argument('-X', '--output-hex', action='store_true', default=False, help='output generated (where applicable) as hex-encoded ascii') parser.add_argument('-i', '--input-type', choices=['entropy','xprv','xpub'], required=True, action='store', help='source material to generate key') parser.add_argument('-n', '--amount', type=int, default=128, action='store', help='amount of entropy to to read (bits), None for all of input') parser.add_argument('-f', '--from-file', action='store', default='-', help="filespec of input data, '-' for stdin") parser.add_argument('-F', '--to-file', action='store', default='-', help="filespec of output data, '-' for stdout") parser.add_argument('-o', '--output-type', action='store', required=True, help='output types, comma separated, from %s' % '|'.join(valid_output_types)) parser.add_argument('-v', '--verbose', action='store_true', default=False, help='verbose output, not for machine parsing') parser.add_argument('-d', '--debug', action='store_true', default=False, help='enable debugging output') parser.add_argument('chain', nargs='+', help='list of hierarchical key specifiers') parser.add_argument('-t', '--testnet', action='store_true', default=False, help='use testnet format') args = parser.parse_args() # Validate -f, --from-file is readable ff = args.from_file if ff != '-' and os.access(ff, os.R_OK) is False: raise ValueError("unable to read from %s, aborting" % ff) # Validate -F, --to-file parent dir is writeable tf = args.to_file if tf != '-': pd = os.path.dirname(os.path.abspath(tf)) if os.access(pd, os.W_OK) is False: raise ValueError("do not have permissions to create file in %s, aborting\n" % pd) # Validate -o, --output-type for o in args.output_type.split(','): if o not in valid_output_types: valid_output_display = '['+'|'.join(valid_output_types)+']' raise ValueError("output type \'%s\' is not one of %s\n" % (o, valid_output_display)) # Validate keyspecs for syntax for keyspec in args.chain: if not re.match("^([mM]|[0-9]+h?)(/[0-9]+h?)*$", keyspec): raise ValueError("chain %s is not valid\n" % keyspec) # If input is from entropy, keyspec must be absolute elif args.input_type == 'entropy' and keyspec[0] not in 'mM': raise ValueError("When generating from entropy, keyspec must start with 'm' or 'M'") # Importing extended private or public keys need relative keyspecs elif args.input_type in ['xpub','xprv'] and keyspec[0] in 'mM': raise ValueError("When generating from xprv or xpub, keyspec must start with 0..9") return args def ErrorExit(e): "Hard bailout printing exception" sys.stderr.write(sys.argv[0]+": "+e.message+'\n') sys.exit(1) if __name__ == "__main__": try: args = GetArgs() except Exception as e: ErrorExit(e) # Get common input data input_data = {} try: if args.input_type == 'entropy': input_data['entropy'] = ReadEntropy(args) elif args.input_type == 'xprv': if args.verbose: print("Importing starting key from extended private key") input_data['xprv'] = ReadInput(args.from_file, None, False).strip() elif args.input_type == 'xpub': if args.verbose: print("Importing starting key from extended public key") input_data['xpub'] = ReadInput(args.from_file, None, False).strip() except Exception as e: ErrorExit(e) # Iterate through keyspecs, create, then output cache = {} otypes = args.output_type.split(',') for keyspec in args.chain: if args.verbose: print("Keyspec: %s" % keyspec) key = ParseKeyspec(args, input_data, keyspec, cache) # Output fields in command-line supplied order for otype in otypes: prefix = '' if not args.verbose else otype+':'+' '*(8-len(otype)) if otype == 'addr': WriteOutput(args.to_file, prefix, key.Address(), False) elif otype == 'privkey': WriteOutput(args.to_file, prefix, key.PrivateKey(), args.output_hex) elif otype == 'wif': WriteOutput(args.to_file, prefix, key.WalletImportFormat(), False) elif otype == 'pubkey': WriteOutput(args.to_file, prefix, key.PublicKey(), args.output_hex) elif otype == 'xprv': WriteOutput(args.to_file, prefix, key.ExtendedKey(private=True, encoded=True), False) elif otype == 'xpub': WriteOutput(args.to_file, prefix, key.ExtendedKey(private=False, encoded=True), False) elif otype == 'chain': WriteOutput(args.to_file, prefix, key.ChainCode(), args.output_hex) if args.verbose: WriteOutput(args.to_file, '', '', False) python-bip32utils-0.0~git20170118.dd9c541/README.rst0000644000175000017500000002717713037714212020527 0ustar noahfxnoahfxIntroduction ============ .. image:: https://travis-ci.org/prusnak/bip32utils.svg?branch=master :target: https://travis-ci.org/prusnak/bip32utils The bip32utils library is a pure Python implementation of Bitcoin hierarchical deterministic wallet ("HD Wallet") ECDSA key generation as specified in BIP0032 (Bitcoin Improvement Proposal #0032). Deterministic ECDSA key generation allows creating a sequence of Bitcoin private and public ECDSA keys from an initial seed and a hierarchical set of indices. A number of benefits follow: * An entire wallet can be backed up once by storing the wallet seed or master extended private key, and all future addresses in the wallet can be restored from it. * The creation of public and private ECDSA keys may be separated from each other. That is, it is possible to create only the public ECDSA key half (and receiving address) of an ECDSA key pair, without the ability to create the private half. Thus, one can create receiving addresses on a public facing system that if compromised would not give the attacker the ability to spend bitcoin received at those addresses. A separate, offline machine can generate the corresponding private ECDSA keys and sign transactions. * Public and private ECDSA keys may be created in a hierarchy, and control over or visibility of portions of the hierarchy may be delegated to third parties. This has uses for auditing, for separating ECDSA key sequences into different logical groups or accounts, and for giving 3rd parties the ability to create spending transactions without first getting a receiving address in advance. BIP0032 is in draft stage, is subject to change, and is documented at: https://github.com/sipa/bips/blob/bip32update/bip-0032.mediawiki Python bip32gen Script ====================== This library installs the bip32gen script into $PREFIX/bin, which wraps a command-line interface around the BIP32Key class functionality described in a later section: Script Parameters ----------------- :: $ bip32gen -h usage: bip32gen [-h] [-x] [-X] -i {entropy,xprv,xpub} [-n AMOUNT] [-f FROM_FILE] [-F TO_FILE] -o OUTPUT_TYPE [-v] [-d] chain [chain ...] Create hierarchical deterministic wallet addresses positional arguments: chain list of hierarchical key specifiers optional arguments: -h, --help show this help message and exit -x, --input-hex input supplied as hex-encoded ascii -X, --output-hex output generated (where applicable) as hex-encoded ascii -i {entropy,xprv,xpub}, --input-type {entropy,xprv,xpub} source material to generate key -n AMOUNT, --amount AMOUNT amount of entropy to to read (bits), None for all of input -f FROM_FILE, --from-file FROM_FILE filespec of input data, '-' for stdin -F TO_FILE, --to-file TO_FILE filespec of output data, '-' for stdout -o OUTPUT_TYPE, --output-type OUTPUT_TYPE output types, comma separated, from addr|privkey|wif|pubkey|xprv|xpub|chain -v, --verbose verbose output, not for machine parsing -d, --debug enable debugging output -t, --testnet use testnet format The user specifies the type of input data (currently from entropy, a serialized extended private key, or serialized extended public key), the filespec to get that input data from (or stdin), the set of output fields to generate, whether to hex encode those outputs when applicable, and a list of key specifier(s). A key specifier will either start with 'm' or 'M' when using entropy as an input source; otherwise, when importing from a serialized extended key, the key specifier(s) start with the first hierarchical child index to create. For example, to generate a new master wallet key from entropy and output the serialized extended private key for that to stdout: :: $ bip32gen -i entropy -f /dev/random -n 128 -o xprv -F - m xprv9s21ZrQH143K3eqKCaAW9CvAiKR8SHdikQnR8dVs8eBxC9fYtW69k1gLRTG5o2Rn3gtz651yFGzxRFjtfjLQHmh4kT7YF3vZcZgGdfX7ZVS To generate the BIP0032 test vector #1, using entropy supplied as a hex-encoded string on stdin, and output the private ECDSA key, wallet import format for that private ECDSA key, public ECDSA key, address, and serialized extended private and public keys, hex encoding where applicable, and writing to stdout: :: $ echo 000102030405060708090A0B0C0D0E0F | \ bip32gen -v \ -i entropy -f - -x \ -o privkey,wif,pubkey,addr,xprv,xpub -F - -X \ m \ m/0h \ m/0h/1 \ m/0h/1/2h \ m/0h/1/2h/2 \ m/0h/1/2h/2/1000000000 (output not listed) BIP0032 outlines a hierarchy where individual "accounts" and key series have the following form: :: m/ih/0/k - Receiving address series for account 'i', with 'k' as index m/ih/1/k - Change address series for spends from account 'i', with 'k' as index So, to give someone the ability to create receving addresses for account 0, (but not the ability to spend from those addresses), one would export an _extended public key_ for m/0h/0 (we'll use again the entropy from BIP0032 test vector #1 for purpose of explanation, but of course this would be unique for each situation): :: $ echo 000102030405060708090A0B0C0D0E0F | \ bip32gen \ -i entropy -f - -x \ -o xpub -F - \ m/0h/0 xpub6ASuArnXKPbfEVRpCesNx4P939HDXENHkksgxsVG1yNp9958A33qYoPiTN9QrJmWFa2jNLdK84bWmyqTSPGtApP8P7nHUYwxHPhqmzUyeFG Then, to derive public child keys, that person would run the key generator using that extended public key as input: :: $ echo xpub6ASuArnXKPbfEVRpCesNx4P939HDXENHkksgxsVG1yNp9958A33qYoPiTN9QrJmWFa2jNLdK84bWmyqTSPGtApP8P7nHUYwxHPhqmzUyeFG | \ bip32gen \ -i xpub -f - \ -o addr -F - \ 0 1 2 3 4 5 6 7 8 9 1BvgsfsZQVtkLS69NvGF8rw6NZW2ShJQHr 1B1TKfsCkW5LQ6R1kSXUx7hLt49m1kwz75 1D2LvY1T3yT4xWgoXkXhAbh1fbY39owifJ 1L71JnrWfB45Z1g2et1zeDAkzrpY8eyJMH 1ACa2mfirthEwmnHVHcBEAVfTHJkajpjod 1CR1rZqA8cwbohoj9bNmcrYxx31Zx2jw4c 1PkyqPChrqwM1dee8KTMpsWWBuXgmGVNoi 1L3HVcGagSUEb2d24SfHV7Kyu6kUNpDL51 17JbSP83rPWmbdcdtiiTNqBE8MgGN8kmUk 1MWb4Pv4ZCUmbnFgA5D3MtYyhMh4q8KCrd An offline machine could generate the corresponding private keys to spend from those addresses by using an *extended private key* for the account: :: $ echo 000102030405060708090A0B0C0D0E0F | \ bip32gen \ -i entropy -f - -x \ -o xprv -F - \ m/0h/0 xprv9wTYmMFdV23N21MM6dLNavSQV7Sj7meSPXx6AV5eTdqqGLjycVjb115Ec5LgRAXscPZgy5G4jQ9csyyZLN3PZLxoM1h3BoPuEJzsgeypdKj Then to generate the corresponding private keys (here shown in wallet import format): :: $ echo xprv9wTYmMFdV23N21MM6dLNavSQV7Sj7meSPXx6AV5eTdqqGLjycVjb115Ec5LgRAXscPZgy5G4jQ9csyyZLN3PZLxoM1h3BoPuEJzsgeypdKj | \ bip32gen \ -i xprv -f - \ -o wif -F - \ 0 1 2 3 4 5 6 7 8 9 L3dzheSvHWc2scJdiikdZmYdFzPcvZMAnT5g62ikVWZdBewoWpL1 L22jhG8WTNmuRtqFvzvpnhe32F8FefJFfsLJpSr1CYsRrZCyTwKZ KwhVMKLLSMt7DemnUxhSftkdqPjWYmPKt31nmV3BB7TdVaMFzqgP KySK2geQrXWYR7f2p9C9Exr4CLngFQnnzQegSaKAfxNupqecSwdU KxSKj3b3EdHSyN3C5sSwRL7TMmxpEVkJ7Cw4fQTMUYXsCZRbmBAP L5kxG5qokHeTJSwco5JzCEdAy5TN2M2Tj2QvxGpvVuSVP5bJRAUT L3oTQGyHQvE3GkRQJkgPs9vY8NRTxdwacHu9Xu9QBPTpgHCSGume KxABnXp7SiuWi218c14KkjEMV7SjcfXnvsWaveNVxWZU1Rwi8zNQ L1Zku8j3mCiiHxZdo6NDLHv6jcA1JyNufUSHBMiznML38vNr9Agh L46bxscw878ytxNHro7ghNXuybUv8aNJAY1UudH1HUxD2pecBhR8 Python bip32utils Library ========================= The BIP32Key Class ------------------ The bip32utils python library currently has a single class, BIP32Key, which encapsulates a single node in a BIP0032 wallet hierarchy. A terminology distinction is made between an ECDSA private and public key pair and a full BIP32Key, which internally holds an ECDSA key pair and other data. A BIP32Key may act like a standard Bitcoin keypair, providing the means to sign transactions with its internal ECDSA private key or to generate a receiving address with its internal ECDSA public key. In addition, a BIP32Key can act as the parent node for a set of indexed children and thus form a tree of BIP32Key sequences. A BIP32Key may also be deemed a private or public BIP32Key, depending upon whether the secret half of the internal ECDSA key pair is present. Private BIP32Keys are able to generate either public or private child BIP32Keys, while public BIP32Keys can only generate public children. In other words, a private BIP32Key internally stores an ECDSA private key, an ECDSA public key, and some additional pseudorandom bits named the *chain code*. Public BIP32Keys are only different in that the secret half of the ECDSA key pair does not exist; only the public half does. Creating a BIP32Key ------------------- A BIP32Key may come into existence in one of four ways: * Using the BIP32Key.fromEntropy(entropy, public=False) method, one may provide a string of at least 32 bytes (128 bits) to construct a new master BIP32Key for an entire tree. From this initial >= 128 bits of entropy a new ECDSA private key, ECDSA public key, and pseudorandom chain code are derived that preserves the 128 bit security parameter as described in BIP0032. This is termed a private BIP32Key, and may be used to derive child BIP32Keys that are either private or public. If the public parameter is set to True, then the internal ECDSA private key is discarded, the resulting BIP32Key is known as a public BIP32Key, and may only be used to generate further public BIP32Keys. * Using the BIP32Key.fromExtendedKey(xkey, public=False) static method, one may provide a 78-byte serialized string that is formatted as an Extended Private Key, as documented in BIP0032. From this, the ECDSA private key, ECDSA public key, and chain code are extracted. If the public parameter is set to True, then the internal ECDSA private key is discarded, converting the resulting BIP32Key into a public BIP32Key, and may only be used to generate further public BIP32Keys. * Using the BIP32Key.fromExtendedKey(xkey) static method, one may provide a 78-byte serialized string that is formatted as an Extended Public Key, as documented in BIP0032. From this, the ECDSA public key and chain code are extracted, resulting in a public BIP32Key that may only be used to generate further public BIP32Keys. * Finally, using an instance of a BIP32Key resulting from any of the three methods above, one may call the member function ChildKey(i) to create a child BIP32Key one level lower in the hierarchy, at integer index 'i'. If the starting BIP32Key is a private one, then the resulting child BIP32Key will also be a private one, using the CKDpriv derivation formula in BIP0032. Likewise, if the starting BIP32Key is a public one (i.e., does not contain an internal ECDSA private key half), then the child BIP32Key will also be a public one, derived using the CKDpub algorithm in BIP0032. At any time, a private BIP32Key may be turned into a public one by calling the instance member function SetPublic(), which discards the internal private ECDSA key half and sets an internal flag. When creating a child BIP32Key from an existing private BIP32Key, one may also select from an alternate set of child keys, called *hardened* keys, by adding the constant BIP32_HARDEN to the integer index. A hardened child BIP32Key avoids a known issue with non-hardened child keys where a compromise of one child key may result in a compromise of all child keys in the same sequence. python-bip32utils-0.0~git20170118.dd9c541/setup.py0000755000175000017500000000104413037714212020536 0ustar noahfxnoahfx#!/usr/bin/env python from setuptools import setup setup( name = 'bip32utils', version = '0.3-3', author = 'Johnathan Corgan, Corgan Labs', author_email = 'johnathan@corganlabs.com', maintainer = 'Pavol Rusnak', maintainer_email = 'stick@gk2.sk', url = 'http://github.com/prusnak/bip32utils', description = 'Utilities for generating and using Bitcoin Hierarchical Deterministic wallets (BIP0032).', license = 'MIT', install_requires = ['ecdsa'], packages = ['bip32utils'], scripts = ['bip32gen'] ) python-bip32utils-0.0~git20170118.dd9c541/.travis.yml0000644000175000017500000000074713037714212021143 0ustar noahfxnoahfxlanguage: python # Runs jobs on container based infrastructure sudo: false # Saves pip downloads/wheels between builds cache: directories: - $HOME/.cache/pip python: - "2.6" - "2.7" - "3.2" - "3.3" - "3.4" - "3.5" install: # Optimisation: build requirements as wheels, which get cached by Travis - pip install "pip>=7.0" wheel script: - python setup.py install - cd tests ; diff -u <(./bip0032-vectors.sh) ./bip0032-vectors.out ; cd .. python-bip32utils-0.0~git20170118.dd9c541/.gitignore0000644000175000017500000000006113037714212021007 0ustar noahfxnoahfx*~ *.pyc *.pyo /bip32utils.egg-info /dist /build python-bip32utils-0.0~git20170118.dd9c541/LICENSE0000644000175000017500000000206213037714212020027 0ustar noahfxnoahfxCopyright 2014 Corgan Labs The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. python-bip32utils-0.0~git20170118.dd9c541/tests/0000755000175000017500000000000013037714212020164 5ustar noahfxnoahfxpython-bip32utils-0.0~git20170118.dd9c541/tests/pubtest.sh0000755000175000017500000000030013037714212022202 0ustar noahfxnoahfx#!/bin/sh echo Generating receiving addresses through both private and public chains using entropy bip32gen -v \ -i entropy -f vector1.bin \ -o addr -F - -X \ m/0/1/2/3 M/0/1/2/3 python-bip32utils-0.0~git20170118.dd9c541/tests/bip0032-vectors.sh0000755000175000017500000000136013037714212023265 0ustar noahfxnoahfx#!/bin/sh # BIP0032 Test vector #1 echo Generating BIP0032 test vector 1: echo 000102030405060708090A0B0C0D0E0F | \ ../bip32gen -v \ -i entropy -f - -x \ -o privkey,wif,pubkey,addr,xprv,xpub -F - -X \ m \ m/0h \ m/0h/1 \ m/0h/1/2h \ m/0h/1/2h/2 \ m/0h/1/2h/2/1000000000 # BIP0032 Test vector #2 echo Generating BIP0032 test vector 2: echo fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542 | \ ../bip32gen -v \ -i entropy -f - -x -n 512 \ -o privkey,wif,pubkey,addr,xprv,xpub -F - -X \ m \ m/0 \ m/0/2147483647h \ m/0/2147483647h/1 \ m/0/2147483647h/1/2147483646h \ m/0/2147483647h/1/2147483646h/2 python-bip32utils-0.0~git20170118.dd9c541/tests/vector1.bin0000644000175000017500000000002013037714212022231 0ustar noahfxnoahfx python-bip32utils-0.0~git20170118.dd9c541/tests/.gitignore0000644000175000017500000000000613037714212022150 0ustar noahfxnoahfx*.asc python-bip32utils-0.0~git20170118.dd9c541/tests/bip0032-vectors.out0000644000175000017500000001476713037714212023476 0ustar noahfxnoahfxGenerating BIP0032 test vector 1: Creating master key and seed using 128 bits of entropy read from stdin entropy: 000102030405060708090a0b0c0d0e0f Keyspec: m privkey: e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35 wif: L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW pubkey: 0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2 addr: 15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma xprv: xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi xpub: xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8 Keyspec: m/0h privkey: edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea wif: L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT pubkey: 035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56 addr: 19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh xprv: xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7 xpub: xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw Keyspec: m/0h/1 privkey: 3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368 wif: KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM pubkey: 03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c addr: 1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj xprv: xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs xpub: xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ Keyspec: m/0h/1/2h privkey: cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca wif: L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU pubkey: 0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2 addr: 1NjxqbA9aZWnh17q1UW3rB4EPu79wDXj7x xprv: xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM xpub: xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5 Keyspec: m/0h/1/2h/2 privkey: 0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4 wif: KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR pubkey: 02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29 addr: 1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt xprv: xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334 xpub: xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV Keyspec: m/0h/1/2h/2/1000000000 privkey: 471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8 wif: Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs pubkey: 022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011 addr: 1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam xprv: xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76 xpub: xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy Generating BIP0032 test vector 2: Creating master key and seed using 512 bits of entropy read from stdin entropy: fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542 Keyspec: m privkey: 4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e wif: KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy pubkey: 03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7 addr: 1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg xprv: xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U xpub: xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB Keyspec: m/0 privkey: abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e wif: L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj pubkey: 02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea addr: 19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ xprv: xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt xpub: xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH Keyspec: m/0/2147483647h privkey: 877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93 wif: L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr pubkey: 03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b addr: 1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk xprv: xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9 xpub: xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a Keyspec: m/0/2147483647h/1 privkey: 704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7 wif: KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2 pubkey: 03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9 addr: 1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW xprv: xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef xpub: xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon Keyspec: m/0/2147483647h/1/2147483646h privkey: f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d wif: L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF pubkey: 02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0 addr: 15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R xprv: xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc xpub: xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL Keyspec: m/0/2147483647h/1/2147483646h/2 privkey: bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23 wif: L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK pubkey: 024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c addr: 14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt xprv: xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j xpub: xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt python-bip32utils-0.0~git20170118.dd9c541/tests/import-xkey.sh0000755000175000017500000000115113037714212023011 0ustar noahfxnoahfx#!/bin/sh XPRV=$(bip32gen -i entropy -f vector1.bin -o xprv -F - m/0h) echo "Extended private key for 'm/0h' is $XPRV" echo $XPRV >xprv.asc XPUB=$(bip32gen -i entropy -f vector1.bin -o xpub -F - m/0h) echo "Extended public key for 'm/0h' is $XPUB" echo $XPUB >xpub.asc ADDR=$(bip32gen -i entropy -f vector1.bin -o addr m/0h/1) echo "Using entropy for 'm', address of 'm/0h/1' is $ADDR" ADDR2=$(bip32gen -i xprv -f xprv.asc -o addr 1) echo "Using xprv for 'm/0h', address of 'm/0h/1' is $ADDR2" ADDR3=$(bip32gen -i xpub -f xpub.asc -o addr 1) echo "Using xpub for 'M/0h', address of 'M/0h/1' is $ADDR3"