4

I'm looking for a command line address calculator, where I can put in my private exponent and get out a bitcoin address in Base-58 encode. Does anyone know some free software that will allow me to do this? Basically like http://brainwallet.org/ but off line.

Thanks.

2 Answers 2

1

I've cached a command line Bitcoin address generator posted a while ago on BitcoinTalk. Note that I've not tested it more than once, but it should at least give you a place to start.

0

Using openssl, you can convert private keys to public keys from the command line. The following command gives you the public key from a known private key. Part of it is from the same script that has been posted on BitcoinTalk some time ago and referred in this answer.

The private key should be in the form of a PEM file like this:

$ cat private_key.pem

-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIMURrYd6CTHlrrV0JOxnze9ldaq3mRYMnYJ8195GldAVoAcGBSuBBAAK
oUQDQgAEANPTV3v+8AMXnIPaerOWziyc6tHbmbhORhbVKv1ACYuO+ohlFaV6QaOz
/AGjoSXV0ZeKxq7FijsAdBzeu23Fgg==
-----END EC PRIVATE KEY-----

Note: if you have a private key in hex format, then you should convert it to PEM format, using the procedure described here.

As said, to obtain the public key from the private key we use openssl:

$ openssl ec -pubout /dev/null

-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEANPTV3v+8AMXnIPaerOWziyc6tHbmbhO
RhbVKv1ACYuO+ohlFaV6QaOz/AGjoSXV0ZeKxq7FijsAdBzeu23Fgg==
-----END PUBLIC KEY-----

In order to convert a public key to a bitcoin address, we need some steps:

First we need to compute the hash160 of the public key. This can be done as follows:

$ openssl ec -pubout /dev/null |
  openssl ec -pubin -pubout -outform DER 2>/dev/null |
  tail -c 65 |
  openssl dgst -sha256 -binary |
  openssl dgst -rmd160 -binary |
  xxd -p -c 80

ab085c55b735d4a811df3f55e6508634f1ce1e27

Then the hash160 has to be used to calculate the checksum as follows:

$ echo -n "ab085c55b735d4a811df3f55e6508634f1ce1e27" |
  xxd -p -r |
  openssl dgst -sha256 -binary |
  openssl dgst -sha256 -binary |
  xxd -p -c 80 |
  head -c 8

7801f8dc

The hash160, combined with the checksum and with the first byte "00", can be encoded using base 58. This gives us the address:

base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})

encodeBase58() {
    # 58 = 0x3A
    bc 0) { n%3A ; n/=3A }" |
    tac |
    while read n
    do echo -n ${base58[n]}
    done
}
$ printf "%34s\n" "$(encodeBase58 "00$1$(checksum "$char$1")")" |
  sed "y/ /1/"

1GbLZiNzi7DTB4UowMuyqJw5Bh95yCbu3R

Putting all together, we can use the function publicKeyToAddress, as defined below. This can be part of a bash script, or you can type it on the command line.

base58=({1..9} {A..H} {J..N} {P..Z} {a..k} {m..z})

encodeBase58() {
    # 58 = 0x3A
    bc 0) { n%3A ; n/=3A }" |
    tac |
    while read n
    do echo -n ${base58[n]}
    done
}

checksum() {
    xxd -p -r /dev/null |
    tail -c 65 |
    openssl dgst -sha256 -binary |
    openssl dgst -rmd160 -binary |
    xxd -p -c 80
    )
}
$ openssl ec -pubout /dev/null | publicKeyToAddress

1GbLZiNzi7DTB4UowMuyqJw5Bh95yCbu3R

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.