Bitcoin-Crypto

 view release on metacpan or  search on metacpan

lib/Bitcoin/Crypto/Key/ExtPrivate.pm  view on Meta::CPAN

				chain_code => $cc,
			);
		}
	);
}

sub get_public_key
{
	my ($self) = @_;

	my $public = Bitcoin::Crypto::Key::ExtPublic->new(
		_key_instance => $self->raw_key('public'),
		chain_code => $self->chain_code,
		child_number => $self->child_number,
		parent_fingerprint => $self->parent_fingerprint,
		depth => $self->depth,
		network => $self->network,
		purpose => $self->purpose,
	);

	return $public;
}

sub derive_key_bip44
{
	my ($self, %data) = @_;
	my $path = Bitcoin::Crypto::BIP44->new(
		%data,
		coin_type => $self,
	);

	return $self->derive_key($path);
}

sub _derive_key_partial
{
	my ($self, $child_num, $hardened) = @_;
	my $key = $self->raw_key;

	my $hmac_data;
	if ($hardened) {

		# zero byte + key data - 32 bytes
		$hmac_data = "\x00" . $key;
	}
	else {

		# public key data - SEC compressed form
		$hmac_data = $self->raw_key('public_compressed');
	}

	# child number - 4 bytes
	$hmac_data .= ensure_length pack('N', $child_num), 4;

	my $data = hmac('SHA512', $self->chain_code, $hmac_data);
	my $tweak = substr $data, 0, 32;
	my $chain_code = substr $data, 32, 32;

	Bitcoin::Crypto::Exception::KeyDerive->trap_into(
		sub {
			$key = ecc->add_private_key($key, $tweak);
			die_no_trace 'verification failed' unless ecc->verify_private_key($key);
		},
		"key $child_num in sequence was found invalid"
	);

	return $self->new(
		_key_instance => $key,
		chain_code => $chain_code,
		child_number => $child_num,
		parent_fingerprint => $self->get_fingerprint,
		depth => $self->depth + 1,
	);
}

1;

__END__
=head1 NAME

Bitcoin::Crypto::Key::ExtPrivate - Bitcoin extended private keys

=head1 SYNOPSIS

	use Bitcoin::Crypto qw(btc_extprv);
	use Bitcoin::Crypto::Util qw(generate_mnemonic to_format)

	# generate mnemonic words first
	my $mnemonic = generate_mnemonic;
	print "Your mnemonic is: $mnemonic";

	# create ExtPrivateKey from mnemonic (without password)
	my $key = btc_extprv->from_mnemonic($mnemonic);
	my $ser_key = to_format [base58 => $key->to_serialized];
	print "Your exported master key is: $ser_key";

	# derive child private key
	my $path = "m/0'";
	my $child_key = $key->derive_key($path);
	my $ser_child_key = to_format [base58 => $child_key->to_serialized];
	print "Your exported $path child key is: $ser_child_key";

	# create basic keypair
	my $basic_private = $child_key->get_basic_key;
	my $basic_public = $child_key->get_public_key->get_basic_key;

=head1 DESCRIPTION

This class allows you to create an extended private key instance. Extended keys
can be used to securely generate as many addresses as needed through key
derivation. This allows for long-term, reusable wallet with a single backup.

Moreover, you can use an extended private key to:

=over

=item * generate extended public keys

=item * derive extended keys using standard bip44 or a custom path

=item * restore keys from mnemonic codes, seeds and serialized form



( run in 1.690 second using v1.01-cache-2.11-cpan-437f7b0c052 )