Skip to content

Instantly share code, notes, and snippets.

@gray
Last active December 26, 2016 23:03
Show Gist options
  • Save gray/ba70b951e734f239108da22aa84bd477 to your computer and use it in GitHub Desktop.
Save gray/ba70b951e734f239108da22aa84bd477 to your computer and use it in GitHub Desktop.
Convert bitcoin private key to address
use Crypt::OpenSSL::Bignum;
use Crypt::OpenSSL::EC;
use Crypt::RIPEMD160;
use Digest::SHA qw(sha256);
use Encode::Base58::GMP;
sub wif2addr {
my $wif = shift;
my $bytes = pack 'H*', decode_base58($wif, 'bitcoin')->Rmpz_get_str(16);
my $compressed = 38 == length($bytes) ? 1 : 0;
my $nid = 714; # secp256k1
my $ecgroup = Crypt::OpenSSL::EC::EC_GROUP::new_by_curve_name($nid);
my $eckey = Crypt::OpenSSL::EC::EC_POINT::new($ecgroup);
my $bn = Crypt::OpenSSL::Bignum->new_from_bin(unpack 'xa32', $bytes);
Crypt::OpenSSL::EC::EC_POINT::mul($ecgroup, $eckey, $bn, \0, \0, \0);
my $form = $compressed
? &Crypt::OpenSSL::EC::POINT_CONVERSION_COMPRESSED
: &Crypt::OpenSSL::EC::POINT_CONVERSION_UNCOMPRESSED;
$bytes = Crypt::OpenSSL::EC::EC_POINT::point2oct($ecgroup, $eckey, $form, \0);
my $hash = "\0" . Crypt::RIPEMD160->hash(sha256 $bytes);
my $checksum = unpack 'a4', sha256 sha256 $hash;
my $addr = unpack 'H*', "$hash$checksum";
return '1' . encode_base58("0x$addr", 'bitcoin');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment