Author

Topic: Go lang - Create a random Bitcoin address (Read 2152 times)

legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
March 29, 2015, 11:27:10 AM
#14
TacoTime,

Thank you!

How would I implement this in my current script?

I am not necessarily trying to vanity gen I am trying to create new addresses as quickly as possible and have them be as random as possible.

The reason I want to use Go is because I have seen a considerable difference in the speed.

C# is pretty slow, 2-3 keys a second, same with Python.

Go seems to be considerably faster, C would probably be the best.

Uh

Code:
for someCondition {
// Generate keypairs.
aKeypair, err := ecdsa.GenerateKey(btcec.S256(), crand.Reader)
if err != nil {
return err
}
pubkeyBtcec := btcec.PublicKey{aKeypair.PublicKey.Curve,
aKeypair.PublicKey.X,
aKeypair.PublicKey.Y}
keypairBtcec := btcec.PrivateKey{aKeypair.PublicKey, aKeypair.D}

// Create a map to json marshal
keypairMap := make(map[string]string)
keypairMap["pubkey"] = hex.EncodeToString(pubkeyBtcec.SerializeCompressed())
keypairMap["privkey"] = hex.EncodeToString(keypairBtcec.Serialize())

// Store the address in case anyone wants to use it for BTC
pkh, err := btcutil.NewAddressPubKey(pubkeyBtcec.SerializeCompressed(),
&btcnet.MainNetParams)
if err != nil {
return err
}
keypairMap["address"] = pkh.EncodeAddress()

b, err := json.Marshal(keypairMap)
if err != nil {
return err
}

fmt.Printf("%v\n", b)
}

Hey, thank you!

I actually figured it out.

I just generated a 64 char random string using hex characters and then used hex.decode string to get the private key from bytes.

Here is the output after my changes, a lot more random, the 6 digits at the end are a loop counter:

Code:
4aeaaaec1b84ef3015c4ee1d0f094facd02536205ae819276e38f74c7a4605b6 676651
 18PrXNBbxrg2KWNvnbfLzSwpxR4ynyoH3S 1B7UGMtbNgX8PbavqsNNJQdAw7FPSaViPr
22d5620d8a500ba446f0322d1607469e390f2f03d4c901cb1f09999448c64e8d 676652
 1DXpuk7BWz6EK9PScUpCBwn9ksGnyrAwqn 15n21bF8JhEytL4nkHSvuPJkEpogkfZ3tN
0b645864934c1639e2731ca911a81d7329b0c47a0e6ee6f0cfbcb1e5781c00d4 676653
 13qF3EAno4gc7Hqswq8oC2kGHfShVHTwEp 1C8ZEB1huzjqhPcrWrFA3F6yi9imn28ST2
bcf5aaf9cb77265e716d09a66972d260340aa250e8777c5ff894453591d1245b 676654
 1BuGZmB8WBVeYAm42Aa6jJgqZq9QVHJvpY 128SK4muV5FjmAiiS92p5GndxstnxBXkA7
d0f346b06fbb93a42e7279a76c075df6f7e9b1e6a04afb0e0fc8f8a61818aeff 676655
 19Vu5xPZYQAy2e5houeLL57FRgqAGRYxWA 17qHRE3RDiTuZEc471nAG4Qa5tmCAFQG78
15c1d5345cfc0fa64a6facc6af108460a13d8119469099aaf44ed8dc2ad86983 676656
 1PwHUPUdBLkn4BMvcVGcbTE2FLjGCUxSkc 13YYjBVFJNnaRzxzTiJ29exDbMCP4JNz2N
0bc524534c51273cd5849c30bcca59e46d679eb9eda4bdeae874f27e513126c4 676657
 1JTXZcZTAnN5MZFe7SJeF1SmTWxUKSntZm 19nWRU971Nq46iHJYFdZA82LXaVJ2YEFKa
7b3f70bcf37faf29227e863f028f1cf13021052967028e5d33fb9ad5e94751ff 676658
 12sk7CVxCLNwU5tuAh8DzW9nBJgJXSjcpT 1EEt7ubWnWZqUcCmpfBcUQ2Xznv87Hc3XW
ee0e7e097dba72484edc80bf4d9efd33f1bd3f65e950b105cdf9a02783bc3531 676659
 16pg6BBYRnPL34LPbAenkBRgCk7urG7AZZ 1DMJkLkDdrR2gXFrkaxtk6iqpjaRwqs1Qs
4acb6803f4707a8f0a4e12cbe5d422b5f84f1c36e2615c6efc926444d5e1f4cc 676660
 126SjxtjNMdGr3FGUtJAa67GsYWj9D59dr 1Hk3krWGxiviPyLNyBAM9MdWXLJT2nKJ6q
a381da6f8679b7e0b41d5c08221e807f3078bf52cb379cbb5a2b2ef791b47c2a 676661
 19yuDgVSxWr8uGT1r2j6CNhTijoY22QEAL 13mzLF8SqEpsup2fUN7WMv366AK4NCktL7
9eb0bfe95e16347627e0d76d3a494a746fb12738d1131bee756c12064ff3c7ba 676662
 1Gwr2Yr4tmYE2d4c2VHoZZomMMUYArmBRw 1MBbt7yKWoqLnsXu6C62UcCAoEW6vg4hJD
legendary
Activity: 1484
Merit: 1005
TacoTime,

Thank you!

How would I implement this in my current script?

I am not necessarily trying to vanity gen I am trying to create new addresses as quickly as possible and have them be as random as possible.

The reason I want to use Go is because I have seen a considerable difference in the speed.

C# is pretty slow, 2-3 keys a second, same with Python.

Go seems to be considerably faster, C would probably be the best.

Uh

Code:
for someCondition {
// Generate keypairs.
aKeypair, err := ecdsa.GenerateKey(btcec.S256(), crand.Reader)
if err != nil {
return err
}
pubkeyBtcec := btcec.PublicKey{aKeypair.PublicKey.Curve,
aKeypair.PublicKey.X,
aKeypair.PublicKey.Y}
keypairBtcec := btcec.PrivateKey{aKeypair.PublicKey, aKeypair.D}

// Create a map to json marshal
keypairMap := make(map[string]string)
keypairMap["pubkey"] = hex.EncodeToString(pubkeyBtcec.SerializeCompressed())
keypairMap["privkey"] = hex.EncodeToString(keypairBtcec.Serialize())

// Store the address in case anyone wants to use it for BTC
pkh, err := btcutil.NewAddressPubKey(pubkeyBtcec.SerializeCompressed(),
&btcnet.MainNetParams)
if err != nil {
return err
}
keypairMap["address"] = pkh.EncodeAddress()

b, err := json.Marshal(keypairMap)
if err != nil {
return err
}

fmt.Printf("%v\n", b)
}
newbie
Activity: 57
Merit: 0
I want to have a good BTC address . It's easy to remember. How to create it ?

Thanks a lot !
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
DON'T use your own cryptographic randomness source. DO use ecdsa.GenerateKey and crypto/rand.

https://github.com/monero-project/urs/blob/master/messagesign.go#L46-L82

Looping that would be naive because continual crand calls can be expensive... if you're trying to vanity gen, I would use BIP32 and just continually derive new addresses from a master seed until you found the one you want.

https://github.com/btcsuite/btcutil/tree/master/hdkeychain
https://github.com/btcsuite/btcwallet/tree/master/waddrmgr

TacoTime,

Thank you!

How would I implement this in my current script?

I am not necessarily trying to vanity gen I am trying to create new addresses as quickly as possible and have them be as random as possible.

The reason I want to use Go is because I have seen a considerable difference in the speed.

C# is pretty slow, 2-3 keys a second, same with Python.

Go seems to be considerably faster, C would probably be the best.
legendary
Activity: 1484
Merit: 1005
DON'T use your own cryptographic randomness source. DO use ecdsa.GenerateKey and crypto/rand.

https://github.com/monero-project/urs/blob/master/messagesign.go#L46-L82

Looping that would be naive because continual crand calls can be expensive... if you're trying to vanity gen, I would use BIP32 and just continually derive new addresses from a master seed until you found the one you want.

https://github.com/btcsuite/btcutil/tree/master/hdkeychain
https://github.com/btcsuite/btcwallet/tree/master/waddrmgr
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
The 3b prefix is interesting because 3b41b7a14a1db1f2c8 is 18 characters (you'd expect 16 if it was a 64 bit value being displayed in hex).

My guess is that you also have something going on with your outputting.


Probably, hmm.

I wish I knew more about Go and this data in general.

I have a Python script that does exactly what I want but it's slowwww, like 2 keys a second.

I would really like to modify VanityGen as it is optimized for speed.
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
The 3b prefix is interesting because 3b41b7a14a1db1f2c8 is 18 characters (you'd expect 16 if it was a 64 bit value being displayed in hex).

My guess is that you also have something going on with your outputting.
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
Then why are you doing this?

Code:
padded := make([]byte, 32)

(I am assuming that is what gives you the zeros along with your widening to 64 bit ints?)

If each "random" is only 4 bytes (32 bits) then you'd need to use 8 such random numbers for one 256 bit value.

Unfortunately I have never written any code in Go so can't give you "the answer" but what you are basically going to have to do is work out how to put together the smaller random numbers into the 256 bit value (piece by piece).


No problem, you are helping me by talking it out and I appreciate it!
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
Then why are you doing this?

Code:
padded := make([]byte, 32)

(I am assuming that is what gives you the zeros)


This could be the issue but I think the real issue is the size of the integer I am converting to bytes.

Wouldn't it be more random to generate a random byte string than use big integers to convert to bytes?

The outcome I would like to see is no uniformity between each generated private key, like now there is:

00000000000000000000000000000000000000000000003b41b7a14a1db1f2c8

and then

00000000000000000000000000000000000000000000003b8f1d236b25aef01a

I want:

219380471027f01298401284012a74801247012479120947102947102947102947120f

and then

123969348182361276387129388129u0d030498092f9102901920391283778d8379287
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
Then why are you doing this?

Code:
padded := make([]byte, 32)

(I am assuming that is what gives you the zeros along with your widening to 64 bit ints?)

If each "random" is only 4 bytes (32 bits) then you'd need to use 8 such random numbers for one 256 bit value.

Unfortunately I have never written any code in Go so can't give you "the answer" but what you are basically going to have to do is work out how to put together the smaller random numbers into the 256 bit value (piece by piece).
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
Yes, it is all of the 0 padding.

If you take any random address you find on the internet, I can almost guarantee the private key in hex won't start with all of those 0's.

That is what I am trying to eliminate.
legendary
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
Perhaps the issue is the zero padding (although that seemingly has been done on purpose and I don't grok Go)?
sr. member
Activity: 384
Merit: 250
Looks random to me, I don't see any indication of uniformity...unless I'm missing something?
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
Hello,

I am trying to generate a random Bitcoin address using Go lang but my current setup isn't very random, lol.


 This is the current output from the code below:
Code:
000000000000000000000000000000000000000000000039bebc16a4f5c1002e
 1PFeGBpmGPjyUUHxdEqcDnYsxeyUn7xV77 1BjhbdBuDSjiCvNp48tjz6tpNcYRsBiiCm
00000000000000000000000000000000000000000000003a0c2198c5fdbdfd80
 1Gs8MNmFCnCy3fzR4LmTcCu4FgF9njMyLR 1DJZSjW6sZC1PMvisFiDj6WGan7hPtbQFj
00000000000000000000000000000000000000000000003a59871ae705bafad2
 1LwZ2nX1TTTw5iiYFNQj16dpnQwGNd4nBW 1Lhj5X5N9Lms4VpbboMD41nFKgyeen2MAA
00000000000000000000000000000000000000000000003aa6ec9d080db7f824
 1NRGfrjrEUzMcpEGF5mh9SVNw2NdaYAQET 1HhZikzy4oHy8kDcBuXwM7fiYZhvV2NrtA
00000000000000000000000000000000000000000000003af4521f2915b4f576
 18obhg39sdA4vpTgNKsidqNHYpw2iyvBoU 1698kvdkrLFnK5BT1PU7aa5WP43DEUGQDi
00000000000000000000000000000000000000000000003b41b7a14a1db1f2c8
 16dVjGbfNEJj73v4ZbTrp5HbSbgjqR97FQ 1BJRdzncmbqcmsaeCvFzvp2MWNv34ndj6i
00000000000000000000000000000000000000000000003b8f1d236b25aef01a
 1J3PtXyY1ktmCdECVzVRRKPBTyjmuJfPs9 14Rw7d98cvGciKou7sBtfM1jx1zzQWUf2Q

Code:
rint := rand.Intn(9223372036854775807)
var rint64 int64
rint64 = int64(rint)

// Initialise big numbers with small numbers
count, one := big.NewInt(rint64), big.NewInt(rint64)

// Create a slice to pad our count to 32 bytes
padded := make([]byte, 32)

// Loop forever
for {
// Increment our counter
count.Add(count, one)

// Copy count value's bytes to padded slice
copy(padded[32-len(count.Bytes()):], count.Bytes())

// Get public key
_, public := btcec.PrivKeyFromBytes(btcec.S256(), padded)

// Get compressed and uncompressed addresses
caddr, _ := btcutil.NewAddressPubKey(public.SerializeCompressed(), &btcnet.MainNetParams)
uaddr, _ := btcutil.NewAddressPubKey(public.SerializeUncompressed(), &btcnet.MainNetParams)

Any help would be appreciated and most likely rewarded.
Jump to: