def get_child(self, child_number, is_prime=None, as_private=True): """Derive a child key. :param child_number: The number of the child key to compute :type child_number: int :param is_prime: If True, the child is calculated via private derivation. If False, then public derivation is used. If None, then it is figured out from the value of child_number. :type is_prime: bool, defaults to None :param as_private: If True, strips private key from the result. Defaults to False. If there is no private key present, this is ignored. :type as_private: bool Positive child_numbers (less than 2,147,483,648) produce publicly derived children. Negative numbers (greater than -2,147,483,648) uses private derivation. NOTE: Python can't do -0, so if you want the privately derived 0th child you need to manually set is_prime=True. NOTE: negative numbered children are provided as a convenience because nobody wants to remember the above numbers. Negative numbers are considered 'prime children', which is described in the BIP32 spec as a leading 1 in a 32 bit unsigned int. This derivation is fully described at https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-functions # nopep8 """ boundary = 0x80000000 if abs(child_number) >= boundary: raise ValueError("Invalid child number %s" % child_number) # If is_prime isn't set, then we can infer it from the child_number if is_prime is None: # Prime children are either < 0 or > 0x80000000 if child_number < 0: child_number = abs(child_number) is_prime = True elif child_number >= boundary: child_number -= boundary is_prime = True else: is_prime = False else: # Otherwise is_prime is set so the child_number should be between # 0 and 0x80000000 if child_number < 0 or child_number >= boundary: raise ValueError( "Invalid child number. Must be between 0 and %s" % boundary) if not self.private_key and is_prime: raise ValueError( "Cannot compute a prime child without a private key") if is_prime: # Even though we take child_number as an int < boundary, the # internal derivation needs it to be the larger number. child_number = child_number + boundary child_number_hex = long_to_hex(child_number, 8) if is_prime: # Let data = concat(0x00, self.key, child_number) data = b'00' + self.private_key.get_key() else: data = self.get_public_key_hex() data += child_number_hex # Compute a 64 Byte I that is the HMAC-SHA512, using self.chain_code # as the seed, and data as the message. I = hmac.new( unhexlify(self.chain_code), msg=unhexlify(data), digestmod=sha512).digest() # Split I into its 32 Byte components. I_L, I_R = I[:32], I[32:] if long_or_int(hexlify(I_L), 16) >= SECP256k1.order: raise InvalidPrivateKeyError("The derived key is too large.") c_i = hexlify(I_R) private_exponent = None public_pair = None if self.private_key: # Use private information for derivation # I_L is added to the current key's secret exponent (mod n), where # n is the order of the ECDSA curve in use. private_exponent = ( (long_or_int(hexlify(I_L), 16) + long_or_int(self.private_key.get_key(), 16)) % SECP256k1.order) # I_R is the child's chain code else: # Only use public information for this derivation g = SECP256k1.generator I_L_long = long_or_int(hexlify(I_L), 16) point = (_ECDSA_Public_key(g, g * I_L_long).point + self.public_key.to_point()) # I_R is the child's chain code public_pair = PublicPair(point.x(), point.y()) child = self.__class__( chain_code=c_i, depth=self.depth + 1, # we have to go deeper... parent_fingerprint=self.fingerprint, child_number=child_number_hex, private_exponent=private_exponent, public_pair=public_pair, network=self.network) if child.public_key.to_point() == INFINITY: raise InfinityPointException("The point at infinity is invalid.") if not as_private: return child.public_copy() return child
def get_child(self, child_number, is_prime=None, as_private=True): """Derive a child key. :param child_number: The number of the child key to compute :type child_number: int :param is_prime: If True, the child is calculated via private derivation. If False, then public derivation is used. If None, then it is figured out from the value of child_number. :type is_prime: bool, defaults to None :param as_private: If True, strips private key from the result. Defaults to False. If there is no private key present, this is ignored. :type as_private: bool Positive child_numbers (less than 2,147,483,648) produce publicly derived children. Negative numbers (greater than -2,147,483,648) uses private derivation. NOTE: Python can't do -0, so if you want the privately derived 0th child you need to manually set is_prime=True. NOTE: negative numbered children are provided as a convenience because nobody wants to remember the above numbers. Negative numbers are considered 'prime children', which is described in the BIP32 spec as a leading 1 in a 32 bit unsigned int. This derivation is fully described at https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-functions # nopep8 """ boundary = 0x80000000 if abs(child_number) >= boundary: raise ValueError("Invalid child number %s" % child_number) # If is_prime isn't set, then we can infer it from the child_number if is_prime is None: # Prime children are either < 0 or > 0x80000000 if child_number < 0: child_number = abs(child_number) is_prime = True elif child_number >= boundary: child_number -= boundary is_prime = True else: is_prime = False else: # Otherwise is_prime is set so the child_number should be between # 0 and 0x80000000 if child_number < 0 or child_number >= boundary: raise ValueError( "Invalid child number. Must be between 0 and %s" % boundary) if not self.private_key and is_prime: raise ValueError( "Cannot compute a prime child without a private key") if is_prime: # Even though we take child_number as an int < boundary, the # internal derivation needs it to be the larger number. child_number = child_number + boundary child_number_hex = long_to_hex(child_number, 8) if is_prime: # Let data = concat(0x00, self.key, child_number) data = b'00' + self.private_key.get_key() else: data = self.get_public_key_hex() data += child_number_hex # Compute a 64 Byte I that is the HMAC-SHA512, using self.chain_code # as the seed, and data as the message. I = hmac.new(unhexlify(self.chain_code), msg=unhexlify(data), digestmod=sha512).digest() # Split I into its 32 Byte components. I_L, I_R = I[:32], I[32:] if long_or_int(hexlify(I_L), 16) >= SECP256k1.order: raise InvalidPrivateKeyError("The derived key is too large.") c_i = hexlify(I_R) private_exponent = None public_pair = None if self.private_key: # Use private information for derivation # I_L is added to the current key's secret exponent (mod n), where # n is the order of the ECDSA curve in use. private_exponent = ((long_or_int(hexlify(I_L), 16) + long_or_int(self.private_key.get_key(), 16)) % SECP256k1.order) # I_R is the child's chain code else: # Only use public information for this derivation g = SECP256k1.generator I_L_long = long_or_int(hexlify(I_L), 16) point = (_ECDSA_Public_key(g, g * I_L_long).point + self.public_key.to_point()) # I_R is the child's chain code public_pair = PublicPair(point.x(), point.y()) child = self.__class__( chain_code=c_i, depth=self.depth + 1, # we have to go deeper... parent_fingerprint=self.fingerprint, child_number=child_number_hex, private_exponent=private_exponent, public_pair=public_pair, network=self.network) if child.public_key.to_point() == INFINITY: raise InfinityPointException("The point at infinity is invalid.") if not as_private: return child.public_copy() return child