Understanding Bitcoin Public and Private Keys (3rd Edition)

Everyone serious about Bitcoin security should try to understand this diagram:

Numbers

Skip ahead if you completely understand what binary, decimal, and hexidecimal means.

Decimal means that each digit has 10 possibilities (0,1,2,3,4,5,6,7,8, or 9). The number 6.15 has 3 digits, and by-the-way, this particular total “size” is how many bitcoin one should try to achieve in owning. The first digit is 6, the second digit is 1, the third is 5. These digits could have been any of 0,1,2,3,4,5,7,8, or 9.

In decimal we count 0,1,2,3,4,5,6,7,8,9, and then we run out of digits, so we add a new “1” to the left, and go back down to zero: 10 – The “1” is new, and the “0” used to be “9”.

Binary means there are only 2 possibilities (0 and 1).

In binary, we count from 0, first 1, then 10! See that? it seems like a big jump, but that’s because you are thinking in decimal.

10 in decimal is the number of fingers you hopefully have – the fact that we have 10 fingers is why each “digit” (digit also means finger) has 10 possibilites.

But “10” written in binary is the number of thumbs you have. Imagine counting with thumbs… 1, 10, 11, 100, 101, 111, 1000, 1001 etc.

It may help, if this is your first time seeing this, to count for a while in binary using a pen an paper, to get your head around it. It’s like learning to count for the first time, and not intuitive.

Hexidecimal (hex=6, decimal=10) means 16 possibilities (0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f), where a=10, b=11, c=12, d=13, e=14, and f=15.

Similar to how in playing cards, for some games, the Jack=11, Queen=12, King=13, Ace=14 or 1. A Letter can represent a number, which is the point.

The greater the possibilities that one digit can represent, the shorter it is to write a big number. eg 2047 is decimal. In binary, it takes more digits to write: 11111111111 (eleven digits, relevant later). And in hex, it’s the shortest, 7FF

Summary:

The Random Binary, the Checksum, and the Private Key:

The private key is a binary number first. It can be converted into other forms later. But its essence is a binary number, as that’s what computers understand. Here is an example of a private key in binary:

01000011111 10101110110 01001000001 01001101000 10000100011 10001011011 00100110111 11010000011 11001000001 10111110010 00010101000 00101110110 01100001101 11000010011 01101111001 11001010111 10011010000 01001110000 01000010010 00001110011 10011110101 11000110011 10101101110 00100111111

Notice it’s in groups of 11 digits. Twenty four groups of 11 numbers. 24×11=264 binary digits.

This is how a computer sees the key, the same number, no spacing:

010000111111010111011001001000001010011010001000010001110001011011001001101111101000001111001000001101111100100001010100000101110110011000011011100001001101101111001110010101111001101000001001110000010000100100000111001110011110101110001100111010110111000100111111

It’s a really big number. In decimal, it works out to this:

7,869,270,257,961,728,227,967,109,454,183,816,220,476,881,432,001,550,169,555,390,346,110,510,455,025,983

I hope you’re convinced it’s a big number. Notice it is the same value, and shorter to write.

Anyway, part of the private key is randomly generated, and the final little bit, called the checksum, is calculated mathematically, with the input being the random component. This is an engineering design (that software wallets agree to using) so that if data is entered incorrectly, a computer can pick up that the checksum does not match the entered data, and can warn the user. If there is a typing error and the checksum doesn’t match what is expected, the wallet can say “excuse me, I think you made an error” – however, the user can force the issue and choose to continue. The checksum is not part of the bitcoin code. It’s there for our safety.

Put in another way… At the time of key creation, this random bit…

01000011111 10101110110 01001000001 01001101000 10000100011 10001011011 00100110111 11010000011 11001000001 10111110010 00010101000 00101110110 01100001101 11000010011 01101111001 11001010111 10011010000 01001110000 01000010010 00001110011 10011110101 11000110011 10101101110 001

By mathematical design, generates only this exact checksum…

00111111

And they are put together to form the final key. See this article on how to make a private key from scratch, and see how the checksum is calculated. Notice that the 8 digit checksum when put together with the last 3 random digits, makes a nice 11 digit group like all the others (11 digits are needed to make a BIP39 word, discussed later).

A different random binary would produced a different checksum. When the user puts this key in a wallet, and says “this is the key I previously made, please show me my addresses”, if one single digit is wrong, the wallet software will know and generate a warning.

I’ve harped on a bit here, but it’s crucial to understand this for many reasons.

Private Key Conversion

It’s difficult for a human to write down a binary private key accurately, and to enter it into a software wallet accurately. Errors can lead to loss of bitcoin. Your handwriting can’t make use of a checksum to detect an error, only a computer can when you type.

One solution is to convert the binary into decimal. This makes it easier and shorter to write down.

If the binary was broken into 11 digits, then the biggest “size” a binary can hold is 2048 (0 to 2047 inclusive). This is 00000000000 to 11111111111 inclusive in binary.

Then the private key can be 24 groups of decimal numbers, each number 0 to 2047. Much easier to write, but still error prone.

The solution to this error risk problem was BIP39. This is a protocol that suggests we all use a list of protocol-defined words, and I suspect they were chosen in such a way that one word is unlikely to be misread as another word.

This list contains 2048 words, in alphabetical order. Go look at the list. It’s also in various laguages. Each is given a number from 0 to 2047. This way, each decimal number in the private key can be written down as a word. There is nothing special about a word that it should have a particular number. It’s just defined in the protocol, and if we all use the protocol, then the words = numbers.

This is where seed words come from. When you enter a seed word phrase in a software wallet, it converts the words into 11 digit binaries, and then pastes them all together (in order) to produce a giant 264 digit binary number, the private key (The last word contains some checksum digits and are not random, remmeber?). For a 12 word seed the private key is half as long, 132 bits.

It is unfortunate that the original source of BIP 39 words, which is stored in GitHub, is numbered from 1 to 2048, instead of 0 to 2047. This is just the Github formatting not an intentional design.

To illustrate the problem, if the private key starts with an 11 digit zero, like this, “00000000000” then we need the first word on the list which represents a zero binary. The first word on the list is “abandon” and it represents zero. But unfortunately it is labeled “1”. This is wrong. The binary of 1 is 00000000001, and this is not what we want. Because of this formatting, ALL words therefore are labelled 1 higher than the number they encode.

We might produce a binary from coin tosses, and a computer can help us to get the last 8 digits shown in italics:

010000111111010111011001001000001010011010001000010001110001011011001001101111101000001111001000001101111100100001010100000101110110011000011011100001001101101111001110010101111001101000001001110000010000100100000111001110011110101110001100111010110111000100111111

The first thing to do is break this number up into chunks of 11 digits:

01000011111 10101110110 01001000001 01001101000 10000100011 10001011011 00100110111 11010000011 11001000001 10111110010 00010101000 00101110110 01100001101 11000010011 01101111001 11001010111 10011010000 01001110000 01000010010 00001110011 10011110101 11000110011 10101101110 00100111111

Then we calculate the decimal for each “chunk” of 11 digits:

543, 1398, 577, 616, 1059, 1115, 311, 1667, 1601, 1522, 168, 374, 781, 1555, 889, 1623, 1232, 624, 530, 115, 1269, 1587, 1390, 319

Then we look up the words in a table:

For decimal 543, which word do we use? Dry, duck, or dumb?

Well, this list is from Github, so the words are labelled from 1 onwards. So every number is too high by 1. So we have to subtract 1 to find the word we want. So word 544, dumb, actually represents 543, the number we want.

The next number is 1398, so we use word 1399 from the table and so one.

These are the words:

dumb put else escape love merge cheap spare sight salad bench conduct giant second hundred slab old evoke drastic attack pact shoe punch child

Notice how the words that start with a letter lower in the alphabet represent a smaller number, and the words higher in the alphabet represent a higher number. This is obvious only after you appreciate how the words are ordered and why.

The Extended Private Key

Examine this diagram again:

This image has an empty alt attribute; its file name is screen-shot-2021-01-23-at-6.21.26-pm.png

The extended private key is produced from the binary private key, (and passphrase, and derivation path) using mathematical functions you or I don’t need to know.

Note how adding a passphrase completely changes the downstream extended private key. Modifying the derivation path also changes the downstream data. It’s best not to play with the default derivation path your wallet software gives you, but do write it down. Discussing derivation paths in more detail I’ll reserve for another article, perhaps one day, or I’ll add an appendix one day.

The extended private key is ultimately responsible for the production of ALL the bitcoin addresses in a wallet, AND the ability to SPEND from those addresses. The diagram shows that this Key produces many individual private keys (non-extended, just regular private keys) and each one produces a regular individual public key which produces a single address.

The extended private key also produces the extended PUBLIC Key discussed next.

Each individual private key can not reveal the extended private key. This is my understanding, but I’m not a cryptography expert so can’t verify that for sure, but it makes sense. It might be possible though, that an individual private key might reveal the next private key in the list, again, not sure. Just never reveal ANY private key to anyone and you’ll be fine.

Definitely though, each public key can not reveal the individual private key, or any private key for that matter. That is important to know.

I generated a test wallet at https://iancoleman.io/bip39/ , a great place to practice making dummy wallets (Never make your reall wallet this way on an internet connected computer).

This is what an extended private key looks like:

Notice it is labelled “Account” Extended Private Key. I don’t know why Ian does that, and it has caused me confusion, and I imagine others as well.

Notice also it starts with an “x”. This means legacy addresses will be created. These are the old addresses that start with”1″. Legacy addresses are also called P2PKH, pay to public key hash.

Private keys (or public keys) that start with “y” indicate that addresses that start with “3” will be generated. These addresses are also called (P2SH, Pay to script hash).

Also, keys that start with “z” will generate native segwit, or Bech32, addresses. They start with bc1q.

Finally, keys that start with upper case X, Y, or Z, produce addresses for multisignature wallets.

The Extended Public Key

The purpose of the extended public key is not immediately obvious. If you examine the bottom section of the diagram, you’ll notice that possesion of te extended public key can let your wallet software produce all the same Bitcoin addresses that the extended private key produced, in the same order. The wallet will look identical. So what’s the difference?

A wallet created with the extended private key has the power to spend.

A wallet created with the public key can not spend. It is commonly called a “watching” wallet. You can put this on an unsecure computer and not lose your private keys, and still be able to see your balance and copy an address to send to someone as an invoice.

You should still gaurd you extended public key because anyone who has access to it can look up the balance of your wallet and know all your addresses. Not only will they know your current balance, they can look up your balances in the future as well. It’s sort of like your bank statement.

Gaurd your financial privacy well. Guard your financial keys (bitcoin private keys) even more.

Note: extended public keys look like this:

Instead of starting with “xprv” the public keys start with “xpub”. Or “ypub”, “zpub”, “Xpub”, “Ypub” and “Zpub”. (Capitals indicate multisignature keys).

Conclusion:

I hope this is a clear explanation to help you understand a difficult topic. If you do, it makes it easier to understand a lot more about how Bitcoin works.

Feel free to contact me if you need help on this, or mentorship with bitcoin storage generally.

Understanding this subject makes making your own seed with dice a bit easier to understand, and also multisig wallet generation makes a bit more sense too. As will PGP encryption.

Other Links

A great article that will help you understand derivation paths.

%d bloggers like this: