Bitcoin Forum
May 03, 2024, 01:02:57 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Perl Private Key -> Public Address  (Read 1423 times)
ethought (OP)
Legendary
*
Offline Offline

Activity: 1316
Merit: 1000



View Profile
March 19, 2015, 07:09:45 PM
 #1

Does any one have a minimal / basic perl script that can generate a public addresses given a 32 byte private key?

Most of the perl code examples on Github are unmaintained / broken / years old and I am having troubles getting any of them working.

Something similar to this python code:

Code:
import ecdsa

secp256k1curve=ecdsa.ellipticcurve.CurveFp(115792089237316195423570985008687907853269984665640564039457584007908834671663,0,7)
secp256k1point=ecdsa.ellipticcurve.Point(secp256k1curve,0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
secp256k1=ecdsa.curves.Curve('secp256k1',secp256k1curve,secp256k1point,(1,3,132,0,10))

#--------------------------------------

import binascii, hashlib

def addy(pk):
 pko=ecdsa.SigningKey.from_secret_exponent(pk,secp256k1)
 pubkey=binascii.hexlify(pko.get_verifying_key().to_string())
 pubkey2=hashlib.sha256(binascii.unhexlify('04'+pubkey)).hexdigest()
 pubkey3=hashlib.new('ripemd160',binascii.unhexlify(pubkey2)).hexdigest()
 pubkey4=hashlib.sha256(binascii.unhexlify('00'+pubkey3)).hexdigest()
 pubkey5=hashlib.sha256(binascii.unhexlify(pubkey4)).hexdigest()
 pubkey6=pubkey3+pubkey5[:8]
 pubnum=int(pubkey6,16)
 pubnumlist=[]
 while pubnum!=0: pubnumlist.append(pubnum%58); pubnum/=58
 address=''
 for l in ['123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'[x] for x in pubnumlist]:
  address=l+address
 return '1'+address
 
print addy(0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725)
print addy(int(hashlib.sha256('something small and easy to remember but not easy to guess').hexdigest(),16))


ref: https://bitcointalk.org/index.php?topic=84238.0

Would be happy to provide a small bounty.

thanks



1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
In order to achieve higher forum ranks, you need both activity points and merit points.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
1714698177
Hero Member
*
Offline Offline

Posts: 1714698177

View Profile Personal Message (Offline)

Ignore
1714698177
Reply with quote  #2

1714698177
Report to moderator
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
March 19, 2015, 07:19:40 PM
 #2

I do have some Perl but in the bit privkey → pubkey I cheat via "use Inline" Wink. C compiler and libssl-dev required.
ethought (OP)
Legendary
*
Offline Offline

Activity: 1316
Merit: 1000



View Profile
March 19, 2015, 07:25:38 PM
 #3

I do have some Perl but in the bit privkey → pubkey I cheat via "use Inline" Wink. C compiler and libssl-dev required.

Interested..  Smiley
dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
March 19, 2015, 08:19:49 PM
 #4

Code:
#!/usr/bin/perl

use strict;
use warnings;
use Digest::SHA qw/sha256/;
use Crypt::Digest::RIPEMD160 qw/ripemd160/;
use Encode::Base58::GMP;
use Inline C => Config => LIBS => '-lssl';
use Inline C => <<'END_OF_C_CODE';
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <openssl/ec.h>
#include <openssl/bn.h>

#define NID_secp256k1       714

SV* get_pubkey (char *pk) {
    EC_KEY *k = NULL;
    EC_POINT *pub_key = NULL;
    const EC_GROUP *group = NULL;
    BIGNUM start;
    BIGNUM *priv_key;
    BN_CTX *ctx;

    BN_init(&start);
    ctx = BN_CTX_new();
    assert(ctx);

    priv_key = &start;
    BN_hex2bn(&priv_key,pk);

    k = EC_KEY_new_by_curve_name(NID_secp256k1); assert(k);
    group = EC_KEY_get0_group(k); assert(group);
    pub_key = EC_POINT_new(group); assert(pub_key);
    assert(EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)); assert(pub_key);

    char *hex = EC_POINT_point2hex(group, pub_key, POINT_CONVERSION_UNCOMPRESSED, ctx);
    SV *hex_copy = newSVpvf("%s", hex);
    OPENSSL_free(hex);

    return hex_copy;
}
END_OF_C_CODE

sub base58_gmp_to_btc {
    my ($base58) = @_;
    $base58 =~ y|0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz|;
    return $base58;
}

sub b58_gmp {
    my ($str) = @_;
    return base58_gmp_to_btc encode_base58 "0x$str", 'gmp';
}

sub checksum { return uc unpack 'H8', sha256 sha256 pack 'H*', shift }

sub hash160 { return unpack 'H*', ripemd160 sha256 pack 'H*', shift; }

my @leaders; @leaders[0,5] = (1, 3);
sub b58ck {
    my ($ver, $str) = @_;
    my $cksum = checksum "$ver$str";

    "$ver$str$cksum" =~ /^(0*)/;
    my $num_leading_0s = int +(length $1)/2;

    my $b58c = sprintf "%34s", b58_gmp  "$ver$str$cksum";

    my $b58 = $b58c;
    $b58 =~ s/ //g;
    $b58 = sprintf "%s$b58", $leaders[$ver]x$num_leading_0s;

    return $b58;
}

my $privkey = '1900966ca8703f337ad2c191718af367a04a1929685fe17e4b7fa3e1b9dd6d2d';  ## change me!
my $pubkey = get_pubkey $privkey;
my $h160 = hash160 $pubkey;
my $addr = b58ck '00', $h160;
print <<"EOF";
privkey $privkey
pubkey $pubkey
h160 $h160
addr $addr
EOF
ethought (OP)
Legendary
*
Offline Offline

Activity: 1316
Merit: 1000



View Profile
March 20, 2015, 11:36:33 AM
 #5

Thanks very much. Looks great but cannot get it working unfortunately.

I have /usr/include/openssl/bn.h but am getting the following error:

Quote
undefined symbol: BN_init

Looking in bn.h 'BN_init' does not seem to exist...

Will keep trying though.



dserrano5
Legendary
*
Offline Offline

Activity: 1974
Merit: 1029



View Profile
March 20, 2015, 07:10:45 PM
 #6

Looking in bn.h 'BN_init' does not seem to exist...

In my case:

Code:
$ grep -r BN_init /usr/include/openssl/
/usr/include/openssl/bn.h:void BN_init(BIGNUM *);

Code:
$ dpkg -l |grep ssl.*dev
ii  libssl-dev                        1.0.1e-2+deb7u15      amd64                 SSL development libraries, header files and documentation
ii  libssl-doc                        1.0.1e-2+deb7u15      all                   SSL development documentation documentation
DryPalms
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
July 08, 2018, 12:48:12 AM
Last edit: July 08, 2018, 09:53:51 PM by DryPalms
 #7

dserrano5, great piece of code, works like a charm. The inline C code based on openssl you provided generates over 1500 pubkeys per second which is 5+ times more than any native Perl implementation of secp256k1 curve.

But it seems there might be significant improvement in speed if the code written using inline C based on libsecp256k1 (#include <secp256k1.h>) library. Unfortunately, I am not familiar with C enough to do that. Can anyone rewrite dserrano5's code to use libsecp256k1 lib to generate compressed/uncompressed pubkeys from private key? It should be working many times faster.

Thanks in advance! Would be glad to donate Smiley

PS: This is kind of an old thread but I think it not worth opening a new one so I decided posting here as here is all the pre-history present. Sorry if I am wrong.

UPD: The code seems to have a memory leak because after running it for 24 hours it takes 37% of memory on my server with 48Gb RAM.
DryPalms
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
June 04, 2021, 12:32:32 PM
 #8

Anyone? I am sitting here waiting for a reply for the last three years  Grin
pooya87
Legendary
*
Offline Offline

Activity: 3444
Merit: 10530



View Profile
June 04, 2021, 12:48:05 PM
 #9

Anyone? I am sitting here waiting for a reply for the last three years  Grin
How about finding a way to call C functions from Perl, I'm not familiar with Perl so here is a link: https://stackoverflow.com/questions/4048557/calling-c-function-from-perl-within-embedded-c-application
Then you can use the library that bitcoin core uses known as libsec256k1: https://github.com/bitcoin-core/secp256k1
That way you don't have to worry about the library not being complete or having any bugs.

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!