Skip to content

Commit

Permalink
Implement HD-Seed WIF application of BIP85
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrtj committed Jul 27, 2024
1 parent eadb923 commit a231056
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
38 changes: 37 additions & 1 deletion lib/Bitcoin/Crypto/BIP85.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use List::Util qw(all);
use Crypt::Mac::HMAC qw(hmac);
use Crypt::Digest::SHAKE;

use Bitcoin::Crypto qw(btc_prv);
use Bitcoin::Crypto::Types -types;
use Bitcoin::Crypto::Util qw(mnemonic_from_entropy);
use Bitcoin::Crypto::Exception;
Expand Down Expand Up @@ -99,6 +100,25 @@ sub derive_mnemonic
return mnemonic_from_entropy($entropy, $args->{language});
}

signature_for derive_wif => (
method => Object,
named => [
index => PositiveOrZeroInt,
{default => 0},
],
bless => !!0,
);

sub derive_wif
{
my ($self, $args) = @_;

my $spec_path = "m/83696968'/2'/$args->{index}'";

my $entropy = $self->derive_entropy($spec_path, 32);
return btc_prv->from_serialized($entropy)->to_wif;
}

1;

__END__
Expand Down Expand Up @@ -132,6 +152,8 @@ It currently implements the following applications from the BIP85 spec:
=item * C<BIP39>: L</derive_mnemonic>
=item * C<HD-Seed WIF>: L</derive_wif>
=back
=head1 INTERFACE
Expand Down Expand Up @@ -161,7 +183,7 @@ C<$path>, which can be a standard string derivation path like
C<m/83696968'/0'/0'> or an instance of L<Bitcoin::Crypto::DerivationPath>. The
derivation path must be fully hardened, as specified in the BIP.
Optional C<$length> is the desired length of the entropy in bytes. If not
Optional C<$length> is the desired length of the entropy B<in bytes>. If not
provided, full C<64> bytes of entropy will be returned. If provided and less
than C<64>, the entropy will be truncated to the derired length. If greater
than C<64>, the C<DRNG> algorithm defined in BIP85 will be used to stretch the
Expand Down Expand Up @@ -189,3 +211,17 @@ The generation index. Must be a non-negative integer. Default: C<0>
=back
=head3 derive_wif
$mnemonic = $object->derive_mnemonic(%args)
Derives wif from the master key. C<%args> can be any combination of:
=over
=item * C<index>
The generation index. Must be a non-negative integer. Default: C<0>
=back
14 changes: 14 additions & 0 deletions t/BIP85.t
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,19 @@ subtest 'should derive a mnemonic according to BIP39 application of BIP85' => su
'mystery car occur shallow stable order number feature else best trigger curious', '12 words index 1 ok';
};

subtest 'should derive a wif according to HD-Seed WIF application of BIP85' => sub {
my $bip85 = Bitcoin::Crypto::BIP85->new(
key => btc_extprv->from_serialized(
[
base58 =>
'xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb'
]
),
);

is $bip85->derive_wif, 'Kzyv4uF39d4Jrw2W7UryTHwZr1zQVNk4dAFyqE6BuMrMh1Za7uhp', 'wif ok';
is $bip85->derive_wif(index => 1), 'L45nghBsnmqaGj9Vy64FCw9AyJNi6K4LUFP4r41tYHmQLEyXUkYP', 'wif index 1 ok';
};

done_testing;

0 comments on commit a231056

Please sign in to comment.