Author

Topic: Formats of private keys supported by bitcoind? (Read 668 times)

staff
Activity: 3458
Merit: 6793
Just writing some code
Thank you, I understand that it doesn't look like a properly formatted key but if you import it into a software that accepts it, you will see that this WIF produces a bitcoin address that has a number of confirmed outbound transactions. So as far as I understand this key was successfully used to sign outbound transactions. Doesn't it make it a fully functional key across bitcoin network?
The key that has a value of 0x1 is itself a completely valid private key. However when made into a WIF private key, the only way to make a valid WIF key is to zero-pad it so that it has the same size as a 256 bit integer. So the data that gets Base58Check encoded must be 0x00000000000000000000000000000001 and that must be the data that comes out from decoding it. Just because something is a valid Base58Check encoded value does not make it a WIF private key (e.g. addresses also use Base58Check encoding). There is a difference; WIF is a specific type of Base58Check encoding (must begin with a 5, K, or L and be 51 or 52 characters long).
member
Activity: 80
Merit: 11
That is not a valid WIF key. The key is too short. It seems that the website is not making the number you enter a 256bit integer before making it a byte array to be hashed and converted to WIF. The number must be a 256 bit integer, so you will have to 0 pad the number you enter for the page to actually generate a valid WIF key.

tl;dr the site is wrong.

Thank you, I understand that it doesn't look like a properly formatted key but if you import it into a software that accepts it, you will see that this WIF produces a bitcoin address that has a number of confirmed outbound transactions. So as far as I understand this key was successfully used to sign outbound transactions. Doesn't it make it a fully functional key across bitcoin network?
staff
Activity: 3458
Merit: 6793
Just writing some code
1. On the page above, if I set a private key as a number, say 1, then the WIF looks like 26k9aD1PF, which is a valid WIF and accepted, say, by Electrum wallet. However, bitcoind says "Invalid private key format".
That is not a valid WIF key. The key is too short. It seems that the website is not making the number you enter a 256bit integer before making it a byte array to be hashed and converted to WIF. The number must be a 256 bit integer, so you will have to 0 pad the number you enter for the page to actually generate a valid WIF key.

tl;dr the site is wrong.

What kind of WIFs does the current version of bitcoind support?
There is only one kind of WIF key. What you thought was valid was in fact invalid. It was simply a number in Base58Check encoding. But that does not make it a private key in WIF.

2. I noticed that in the wallet dump all WIFs generated by bitcoind start with K or L, so as far as I understand they are for production of compressed public keys.

How do I generate this kind of WIFs from a private key as a number?

In this case, what's the difference from steps described on http://gobittest.appspot.com/PrivateKey?
Compressed keys have an extra 0x01 byte on the end of the payload that is hashed for the checksum.
legendary
Activity: 1456
Merit: 1081
I may write code in exchange for bitcoins.
Here is some python code to get a hex string into WIF.  I think I modified this code a bit but the original source was a blog post called 'bitcoin the hard way".

Code:
import hashlib

b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def base58encode(n):
  result = ''
  while n > 0:
    result = b58[n%58] + result
    n /= 58
  return result

def base256decode(s):
  result = 0
  for c in s:
    result = result * 256 + ord(c)
  return result

def countLeadingChars(s, ch):
  count = 0
  for c in s:
    if c == ch:
      count += 1
    else:
      break
  return count

# https://en.bitcoin.it/wiki/Base58Check_encoding
def base58CheckEncode(version, payload):
  s = chr(version) + payload
  checksum = hashlib.sha256(hashlib.sha256(s).digest()).digest()[0:4]
  result = s + checksum
  leadingZeros = countLeadingChars(result, '\0')
  return '1' * leadingZeros + base58encode(base256decode(result))

def privateKeyToWif(key_hex, compressed=False):
  if compressed:
    key_hex=key_hex+'01'
  return base58CheckEncode(0x80, key_hex.decode('hex'))

I think that explains it as well as any prose I could write up.
member
Activity: 80
Merit: 11
I'm using this page http://gobittest.appspot.com/PrivateKey to generate WIFs for importing keys via "bitcoin-cli.exe importprivkey .... ".

Randomly generated keys result in WIFs that start with 5 and I can successfully import them into bitcoind wallet.

I have a few questions re this:

1. On the page above, if I set a private key as a number, say 1, then the WIF looks like 26k9aD1PF, which is a valid WIF and accepted, say, by Electrum wallet. However, bitcoind says "Invalid private key format".

Is there a way around it or bitcoind code has some extra restrictions re WIFs?

What kind of WIFs does the current version of bitcoind support?


2. I noticed that in the wallet dump all WIFs generated by bitcoind start with K or L, so as far as I understand they are for production of compressed public keys.

How do I generate this kind of WIFs from a private key as a number?

In this case, what's the difference from steps described on http://gobittest.appspot.com/PrivateKey?
Jump to: