Bitcoin Forum
May 06, 2024, 07:44:48 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Manually convert a Binary or HEX private key to WIF, then find the Public Key  (Read 447 times)
Chris! (OP)
Legendary
*
Offline Offline

Activity: 1382
Merit: 1122



View Profile
September 17, 2018, 10:03:18 PM
 #1

I've learned over the years how to generate a private key with HEX (from binary - coin flips) B6 (dice) but I've always used an air-gapped system to take said private key and find the corresponding Public Key and address.

I would like to figure out what the actual formula is for finding a Public Key from a Private Key. If anyone knows how to do this with a bech32 address that would be amazing. I currently have a private key in binary and HEX and wasn't sure how to get it into WIF format manually either. If the Public Key can be located with a binary or HEX Private Key, that'd be even better.

From what I've read, the public key to Bitcoin address would be extremely tedious and IMO it's not worth the time (if it's technically possible within a human lifetime). I'm also not worried about someone having my public key, so would have no issue plugging that into any computer and having it find the corresponding address.

This looks like a great link, but if someone could explain a lot more in depth what exactly the formula should look like, whether this is possible with pen and paper and/or a scientific calculator, and roughly what timeframe it would take to complete (i.e 5 years assuming you work on it 12hrs/day vs. 20-30 mins) I would really appreciate it!
"If you don't want people to know you're a scumbag then don't be a scumbag." -- margaritahuyan
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714981488
Hero Member
*
Offline Offline

Posts: 1714981488

View Profile Personal Message (Offline)

Ignore
1714981488
Reply with quote  #2

1714981488
Report to moderator
1714981488
Hero Member
*
Offline Offline

Posts: 1714981488

View Profile Personal Message (Offline)

Ignore
1714981488
Reply with quote  #2

1714981488
Report to moderator
1714981488
Hero Member
*
Offline Offline

Posts: 1714981488

View Profile Personal Message (Offline)

Ignore
1714981488
Reply with quote  #2

1714981488
Report to moderator
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3388
Merit: 6581


Just writing some code


View Profile WWW
September 18, 2018, 12:12:42 AM
Last edit: September 18, 2018, 02:29:19 AM by achow101
Merited by Chris! (3), ABCbits (1)
 #2

There are multiple mathematical formulas and algorithms involved in both the calculation of a public key from a private key, and from a public key to a bech32 address.

I would estimate that it would take you a few decades to do either of these algorithms. With a computer to do some precomputation, you can probably do it in a few years.



For public key from a private key, Andrew Poelstra has a pretty good post describing it here: https://bitcointalk.org/index.php?topic=1534028.msg15594185#msg15594185 along with a precomputed table for you.



For the Bech32 calculation, you will need to be able to do two different hash functions: SHA256 and RIPEMD160. Then you also need to calculate the checksum which uses a BCH error correcting code.

For SHA256, Ken Shirriff has a pretty good blog post about how to do SHA256 by hand for mining. It's the same operations, just on different data. Also, you are doing only 1 SHA256 computation, not 2 as mining requires. You perform the SHA256 on your serialized public key in compressed form.

For RIPEMD160, I don't think anyone has really explained how to do by hand (and I don't really want to be cause it is long and takes a lot of time which I don't have). The algorithm is described in this paper with pseudocode given in Appendix A. It is similar to SHA256 in that the message is broken up into chunks which are XOR'd initially with some initial values and then later with the previous chunk.. You would like use a similar method as described in the SHA256 blog post but with the modifications to be able to do RIPEMD160. You perform RIPEMD160 on the above SHA256.

For calculating the checksum, you use the algorithm described under the Checksum section in the BIP. The gist of it is that, given a list of numbers, you apply multiple polynomials on all of the numbers and the "sum" of the results is the checksum (it's a lot more complicated than that and I don't remember all of the details). The python code given in the bech32_polymod() function describes how to do this. Note that ^= in python means XOR, not exponentiation.

To calculate the final bech32 string, you first need to convert the hash160 into a list of numbers usable for bech32's checksum calculation. You do this by splitting up the 160 bit hash into 5 bit chunks. Each 5 bit chunk is then a number so you now have a list of 5 bit numbers. You prepend to that the witness version, which is 0, so the list now starts with the number 0. Then you prepend to that an expansion of the human readable part of a bech32 string, bc. This is expanded by using the bech32_hrp_expand() function in the python code given in the BIP. You will get a list of numbers like so: [3, 3, 0, 2, 3]. So the resulting list of numbers will be 39 numbers in length and begin with [3, 3, 0, 2, 3, 0, .... Lastly you append six 0's to the end of the list which represent the positions that the checksum will go in. Now you do the bech32_polymod() function on this list of numbers and the resulting value you get back is the checksum.

Now you must convert all of these numbers to characters. You do this by breaking the checksum into 5 bit chunks to get a list of 6 numbers. Then, given the list of numbers containing the witness version number, the hash160, and the checksum, convert each number to the corresponding character using the lookup table described in the BIP. Note that you do not need to do this to the expanded human readable part. The resulting bech32 address is the human readable part concatenated to the character '1' concatenated to the characters for the witness version number, the hash160, and the checksum. So it will begin with bc1....

Regarding the human readable part expansion, that is done because the human readable part can be any ascii character and the numbers in the list of numbers need to be in the interval [0, 32). However ASCII can have numbers outside of that interval, so the expansion is done to have the higher bits, then the lower bits so it all fits in the interval.

Bech32 would probably only really take a few days / weeks. You just need to be careful to not make a mistake. The thing that takes a while would be privkey to pubkey.

Chris! (OP)
Legendary
*
Offline Offline

Activity: 1382
Merit: 1122



View Profile
September 18, 2018, 01:38:55 AM
 #3

There are multiple mathematical formulas and algorithms involved in both the calculation of a public key from a private key, and from a public key to a bech32 address.

I would estimate that it would take you a few decades to do either of these algorithms. With a computer to do some precomputation, you can probably do it in a few years.



For public key from a private key, Andrew Poelstra has a pretty good post describing it here: https://bitcointalk.org/index.php?topic=1534028.msg15594185#msg15594185 along with a precomputed table for you.



For the Bech32 calculation, you will need to be able to do two different hash functions: SHA256 and RIPEMD160. Then you also need to calculate the checksum which uses a BCH error correcting code.

For SHA256, Ken Shirriff has a pretty good blog post about how to do SHA256 by hand for mining. It's the same operations, just on different data. Also, you are doing only 1 SHA256 computation, not 2 as mining requires. You perform the SHA256 on your serialized public key in compressed form.

For RIPEMD160, I don't think anyone has really explained how to do by hand (and I don't really want to be cause it is long and takes a lot of time which I don't have). The algorithm is described in this paper with pseudocode given in Appendix A. It is similar to SHA256 in that the message is broken up into chunks which are XOR'd initially with some initial values and then later with the previous chunk.. You would like use a similar method as described in the SHA256 blog post but with the modifications to be able to do RIPEMD160. You perform RIPEMD160 on the above SHA256.

For calculating the checksum, you use the algorithm described under the Checksum section in the BIP. The gist of it is that, given a list of numbers, you apply multiple polynomials on all of the numbers and the "sum" of the results is the checksum (it's a lot more complicated than that and I don't remember all of the details). The python code given in the bech32_polymod() function describes how to do this. Note that ^= in python means XOR, not exponentiation.

To calculate the final bech32 string, you first need to convert the hash160 into a list of numbers usable for bech32's checksum calculation. You do this by splitting up the 160 bit hash into 5 bit chunks. Each 5 bit chunk is then a number so you now have a list of 5 bit numbers. You prepend to that the witness version, which is 0, so the list now starts with the number 0. Then you prepend to that an expansion of the human readable part of a bech32 string, bc. This is expanded by using the bech32_hrp_expand() function in the python code given in the BIP. You will get a list of numbers like so: [3, 3, 0, 2, 3]. So the resulting list of numbers will be 39 numbers in length and begin with [3, 3, 0, 2, 3, 0, .... Lastly you append six 0's to the end of the list which represent the positions that the checksum will go in. Now you do the bech32_polymod() function on this list of numbers and the resulting value you get back is the checksum.

Now you must convert all of these numbers to characters. You do this by breaking the checksum into 5 bit chunks to get a list of 6 numbers. Then, given the list of numbers containing the witness version number, the hash160, and the checksum, convert each number to the corresponding character using the lookup table described in the BIP. Note that you do not need to do this to the expanded human readable part. The resulting bech32 address is the human readable part concatenated to the character '1' concatenated to the characters for the witness version number, the hash160, and the checksum. So it will begin with bc1....

Regarding the human readable part expansion, that is done because the human readable part can be any ascii character and the numbers in the list of numbers need to be in the interval [0, 32). However ASCII can have numbers outside of that interval, so the expansion is done to have the higher bits, then the lower bits so it all fits in the interval.

So it sounds like going from a public key to any address is just completely out of the question, which is what I expected. I may attempt to learn how to do a private key to public key, but even so it's a lot to go over. Thanks so much for the post and I'll see if it's something I can achieve some day.
pebwindkraft
Sr. Member
****
Offline Offline

Activity: 257
Merit: 343


View Profile
September 18, 2018, 09:36:27 PM
Merited by suchmoon (4), DarkStar_ (4), bones261 (2), ABCbits (1), Chris! (1)
 #4

whereas Andrew has provided an extensive answer, I thought I'd add two and a half more things.
I had this confusion with keys in hex and WIF, and then how to come to bitcoin addresses. So I made a small picture, which
I posted on a thread in bitcoin.SE.

Quote
If the Public Key can be located with a binary or HEX Private Key, that'd be even better.
Without BECH32, this link http://gobittest.appspot.com/Address shows how to come from priv key to a bitcoin address.
More on addresses here and here.

Chris! (OP)
Legendary
*
Offline Offline

Activity: 1382
Merit: 1122



View Profile
September 24, 2018, 09:59:11 PM
 #5

whereas Andrew has provided an extensive answer, I thought I'd add two and a half more things.
I had this confusion with keys in hex and WIF, and then how to come to bitcoin addresses. So I made a small picture, which
I posted on a thread in bitcoin.SE.

Quote
If the Public Key can be located with a binary or HEX Private Key, that'd be even better.
Without BECH32, this link http://gobittest.appspot.com/Address shows how to come from priv key to a bitcoin address.
More on addresses here and here.



Thanks! Now I just need to learn how to do all of this math or at least find out what I can do on my own and what I should use a computer for.
TheArchaeologist
Sr. Member
****
Offline Offline

Activity: 310
Merit: 727


---------> 1231006505


View Profile WWW
September 25, 2018, 10:44:53 AM
 #6

whereas Andrew has provided an extensive answer, I thought I'd add two and a half more things.
I had this confusion with keys in hex and WIF, and then how to come to bitcoin addresses. So I made a small picture, which
I posted on a thread in bitcoin.SE.

Do you have or know of an updated picture including bech32 addresses from Public Key?

Sooner or later you're going to realize, just as I did, that there's a difference between knowing the path and walking the path
pebwindkraft
Sr. Member
****
Offline Offline

Activity: 257
Merit: 343


View Profile
September 25, 2018, 12:26:36 PM
 #7

whereas Andrew has provided an extensive answer, I thought I'd add two and a half more things.
I had this confusion with keys in hex and WIF, and then how to come to bitcoin addresses. So I made a small picture, which
I posted on a thread in bitcoin.SE.

Do you have or know of an updated picture including bech32 addresses from Public Key?
no, I don't. BIP173 and this link is all I have for now...

when someone sends me some [sh|b]itcoins, I might do a picture  Grin Cheesy Wink
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!