def child(self, index): '''Returns the child HDPrivateKey at a particular index. Raises ValueError for indices >= 0x8000000. ''' # if index >= 0x80000000, raise a ValueError if index >= 0x80000000: raise ValueError('child number should always be less than 2^31') # data is the SEC compressed and the index in 4 bytes big-endian data = self.point.sec() + int_to_big_endian(index, 4) # get hmac_sha512 with chain code, data h = hmac_sha512(self.chain_code, data) # the new public point is the current point + # the first 32 bytes in big endian * G point = self.point + big_endian_to_int(h[:32]) * G # chain code is the last 32 bytes chain_code = h[32:] # depth is current depth + 1 depth = self.depth + 1 # parent_fingerprint is the fingerprint of this node parent_fingerprint = self.fingerprint() # child number is the index child_number = index # return the HDPublicKey instance return HDPublicKey( point=point, chain_code=chain_code, depth=depth, parent_fingerprint=parent_fingerprint, child_number=child_number, testnet=self.testnet, )
def from_seed(cls, seed, testnet=False): h = hmac_sha512(b'Bitcoin seed', seed) private_key = PrivateKey(secret=big_endian_to_int(h[:32])) chain_code = h[32:] return cls( private_key=private_key, chain_code=chain_code, testnet=testnet, )
def from_seed(cls, seed, testnet=False): # get hmac_sha512 with b'Bitcoin seed' and seed h = hmac_sha512(b'Bitcoin seed', seed) # create the private key using the first 32 bytes in big endian private_key = PrivateKey(secret=big_endian_to_int(h[:32])) # chaincode is the last 32 bytes chain_code = h[32:] # return an instance of the class return cls( private_key=private_key, chain_code=chain_code, testnet=testnet, )
def xpub_child(self, index): if index >= 0x80000000: raise ValueError('child number should always be less than 2^31') data = self.point.sec() + int_to_big_endian(index, 4) h = hmac_sha512(key=self.chain_code, msg=data) point = self.point + big_endian_to_int(h[:32]) * G chain_code = h[32:] depth = self.depth + 1 parent_fingerprint = self.fingerprint() child_number = index return HDPublicKey( point=point, chain_code=chain_code, depth=depth, parent_fingerprint=parent_fingerprint, child_number=child_number, testnet=self.testnet, )
def xprv_child(self, index): if index >= 0x80000000: data = int_to_big_endian(self.private_key.secret, 33) + int_to_big_endian(index, 4) else: data = self.private_key.point.sec() + int_to_big_endian(index, 4) h = hmac_sha512(self.chain_code, data) secret = (big_endian_to_int(h[:32]) + self.private_key.secret) % N private_key = PrivateKey(secret=secret) chain_code = h[32:] depth = self.depth + 1 parent_fingerprint = self.pub.hash160()[:4] child_number = index return HDPrivateKey( private_key=private_key, chain_code=chain_code, depth=depth, parent_fingerprint=parent_fingerprint, child_number=child_number, testnet=self.testnet, )
def child(self, index): '''Returns the child HDPrivateKey at a particular index. Hardened children return for indices >= 0x8000000. ''' # if index >= 0x80000000 if index >= 0x80000000: # the message data is the private key secret in 33 bytes in # big-endian and the index in 4 bytes big-endian. data = int_to_big_endian(self.private_key.secret, 33) + int_to_big_endian(index, 4) else: # the message data is the public key compressed SEC # and the index in 4 bytes big-endian. data = self.private_key.point.sec() + int_to_big_endian(index, 4) # get the hmac_sha512 with chain code and data h = hmac_sha512(self.chain_code, data) # the new secret is the first 32 bytes as a big-endian integer # plus the secret mod N secret = (big_endian_to_int(h[:32]) + self.private_key.secret) % N # create the PrivateKey object private_key = PrivateKey(secret=secret) # the chain code is the last 32 bytes chain_code = h[32:] # depth is whatever the current depth + 1 depth = self.depth + 1 # parent_fingerprint is the fingerprint of this node parent_fingerprint = self.fingerprint() # child number is the index child_number = index # return a new HDPrivateKey instance return HDPrivateKey( private_key=private_key, chain_code=chain_code, depth=depth, parent_fingerprint=parent_fingerprint, child_number=child_number, testnet=self.testnet, )