ethought (OP)
Legendary
Offline
Activity: 1316
Merit: 1000
|
|
March 19, 2015, 07:09:45 PM |
|
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: 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.0Would be happy to provide a small bounty. thanks
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
dserrano5
Legendary
Offline
Activity: 1974
Merit: 1029
|
|
March 19, 2015, 07:19:40 PM |
|
I do have some Perl but in the bit privkey → pubkey I cheat via "use Inline" . C compiler and libssl-dev required.
|
|
|
|
ethought (OP)
Legendary
Offline
Activity: 1316
Merit: 1000
|
|
March 19, 2015, 07:25:38 PM |
|
I do have some Perl but in the bit privkey → pubkey I cheat via "use Inline" . C compiler and libssl-dev required. Interested..
|
|
|
|
dserrano5
Legendary
Offline
Activity: 1974
Merit: 1029
|
|
March 19, 2015, 08:19:49 PM |
|
#!/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
Activity: 1316
Merit: 1000
|
|
March 20, 2015, 11:36:33 AM |
|
Thanks very much. Looks great but cannot get it working unfortunately. I have /usr/include/openssl/bn.h but am getting the following error: undefined symbol: BN_init Looking in bn.h 'BN_init' does not seem to exist... Will keep trying though.
|
|
|
|
dserrano5
Legendary
Offline
Activity: 1974
Merit: 1029
|
|
March 20, 2015, 07:10:45 PM |
|
Looking in bn.h 'BN_init' does not seem to exist...
In my case: $ grep -r BN_init /usr/include/openssl/ /usr/include/openssl/bn.h:void BN_init(BIGNUM *); $ 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
Activity: 7
Merit: 0
|
|
July 08, 2018, 12:48:12 AM Last edit: July 08, 2018, 09:53:51 PM by DryPalms |
|
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 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
Activity: 7
Merit: 0
|
|
June 04, 2021, 12:32:32 PM |
|
Anyone? I am sitting here waiting for a reply for the last three years
|
|
|
|
pooya87
Legendary
Offline
Activity: 3444
Merit: 10530
|
|
June 04, 2021, 12:48:05 PM |
|
Anyone? I am sitting here waiting for a reply for the last three years 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-applicationThen you can use the library that bitcoin core uses known as libsec256k1: https://github.com/bitcoin-core/secp256k1That way you don't have to worry about the library not being complete or having any bugs.
|
. .BLACKJACK ♠ FUN. | | | ███▄██████ ██████████████▀ ████████████ █████████████████ ████████████████▄▄ ░█████████████▀░▀▀ ██████████████████ ░██████████████ █████████████████▄ ░██████████████▀ ████████████ ███████████████░██ ██████████ | | CRYPTO CASINO & SPORTS BETTING | | │ | | │ | ▄▄███████▄▄ ▄███████████████▄ ███████████████████ █████████████████████ ███████████████████████ █████████████████████████ █████████████████████████ █████████████████████████ ███████████████████████ █████████████████████ ███████████████████ ▀███████████████▀ ███████████████████ | | .
|
|
|
|
|