6. Public & Private Keys

I wanted to start part two of this course with crypto-wallets. Because they will be the software, you need to install and set up for part II. But I thought the keys are only a part of the things a crypto-wallet manages for you and the most important part. So, I think keys should have their own lesson.

This lesson won't go into the details of elliptic curve cryptography (ECC). There are better resources to understand this topic. If you want to learn the technical details, I recommend the free ebook Practical Cryptography for Developers that has a part that explains ECC .

Security Best Practices

If I learned one thing about cryptography, it's that you should never ever give away your private key or seed phrase. If you don't understand anything from the book I linked before or written in this lesson, at least keep that small piece of know-how in mind.

This rule means you should only ever type your private key in a secure crypto-wallet app and never in a text file on your PC or smartphone. It's too long for the usual human to remember without much work, so for backup write it down on paper. This way no one who uses your computers can read it from your hard drive.

In some countries, you might fear that the government will be after your keys, but the more likely threat is your house burning down or water damage. So, make sure you have copies at different safe locations.

If you need a private key for development and tests that you will hard-code in a source file, make sure you don't use this development key for your everyday crypto dealings. This way, it's not so bad when your key ends up on GitHub, S3, etc.

The same goes for your seed phrase, which is a way to write down a private key as a list of short words. As a developer, you work directly with private keys, but end-users use their private key in the form of a seed phrase when they move it around between crypto-wallets and paper.

It's also good to know that you shouldn't show people your addresses and public keys without a good reason. While no one can directly steal your tokens without your private key, an attacker can send tokens to your address for phishing. These could lead you to some web apps that try to scam you into using your private key to do something dumb.

What are Keys?

A key, private or public, is just some kind of data. In the specific case of ECC, these two keys are very big numbers. So big that you will store them as string or BigIntegerin JavaScript.

Figure 1: ECC Keys

Private Key

A private key for ECC is a randomly generated integer that can look something like this in hexadecimal:
57cfa2d774eab59998a0b87d641b504aaefeae12f244db08d77e019e6d90afb9

In Ethereum and many other blockchain networks, this key must be smaller than a special prime number.

This big prime number looks like this in hexadecimal:
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

The reason why this exact prime number is used is out of the scope of this course (you can read about it in the book I linked above). But the limit set by that prime number is important! Not every random integer is a valid private key, and if you want to generate your own, it has to be smaller than that prime number.

  let privateKey

  do {
    privateKey = generateRandomInteger()
  } while(privateKey > 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn)

Public Key

A public key for ECC is two integers that are concatenated together. Both of these integers can have the private key length, but they aren't random. These two numbers are calculated from the private key.

A public key can look like this:
0453a07319d6d7a34d1bf3363415a316c0f5cd4cb5fe49f414b1c9d7b420169b652cf466ed56ec01733a9726ee27017ad66e384eefc2d6897aa61d3157cc1273eb

The function used to calculate a public key from a private key is based on a specific algorithm and some predefined parameters. All systems interacting with the Ethereum network have to use the same algorithm and parameters to get the same results.

  let privateKey

  do {
    privateKey = generateRandomInteger()
  } while(privateKey > 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn)

  const publicKey = generatePublicKey(privateKey)

Seed Phrase

A seed phrase, also known as a secret recovery phrase, is a list of 12-24 short random words used to generate one or more private keys and, in turn, public keys and addresses in the end.

A seed phrase could look like this:
forget wing follow flip swallow achieve correct view dinner witness hybrid proud

While you can generate a private key directly, many crypto-wallet apps use a seed phrase to generate them for you. Many people use multiple addresses, and if you're developing with Ethereum and using it for day-to-day things, you will at least need two addresses and two private keys.

The idea of a seed phrase is that it's a random list of words, but the algorithm to generate multiple private keys from that phrase is deterministic. This allows to generate multiple keys from one phrase and recover all these keys from one seed phrase. Otherwise, you would have to write down every single private key on its own.

  const seedPhrase = [
    "forget", "wing", "follow",
    "flip", "swallow", "achieve",
    "correct", "view", "dinner",
    "witness", "hybrid", "proud"
  ]

  const keyGenerator = initKeyGenerator(seedPhrase)
  
  const keys = []
  for(let i = 0; i < 10; ++i) {
    const privateKey = keyGenerator(i)
    const publicKey = generatePublicKey(privateKey)
    const address = keccak256(publicKey).toString().slice(0,20)
    keys.push({ privateKey, publicKey, address})
  }

The downside of this is that if your seed phrase gets stolen, all private keys generated from it are stolen too. This means everything true for your private key is also true ten-fold for your seed phrase because it's the same as multiple private keys.

Never write your seed phrase down on your PC or smartphone outside of a crypto-wallet app, never store it in an S3 bucket, or GitHub, etc. To recover your keys when you lose your smartphone or laptop, or they break, you can write the seed phrase on a piece of paper and store it in a safe location.

What are the Keys Used for?

So, you know what the keys are and how you should handle them, but what exactly is their purpose?

Private and public keys are used for different tasks. Their usage follows from the fact that everyone can have your public keys, and no one should ever have your private keys.

Signing Messages with the Private Key

The private key is used mainly to sign data. Signing means you attach a signature to the data. A signature is created with a signature algorithm that uses your private key and the data that needs to be signed.

The idea is that the signature data can't be generated without having the private key.

A signature could look like this in its Base64 version:
MEQCIEamErEp0wjW2nBCwPJyMWB1UEb8UHaEFeUDko88MOs/AiB5daIS5j1stXRetBsEWbvd0TeoYsfucmADmxFUxbE2oQ==

The public key is used to verify that signature. If you sign something with a private key, the related public key, in combination with a signing algorithm, the signature, and the signed data, will either lead to a "yes, this signature is from the correct private key" or not.

Since you are the only one who has your private keys, you are the only one who can create these signatures. If your keys get stolen, other people can pretend they are the original owners (i. e. you). If you lose your private key, you can't create correct signatures anymore, and systems with your public key won't believe that you are indeed who you pretend to be.

In Figure 2, you see how the three parts interact with each other.

Figure 2: Signing and verification

Enctypting Messages with the Public Key

You learned you can use the public key to verify a signature, but that's not all it can do. The public key can also encrypt a message that only the corresponding private key can decrypt.

If you want to use asymetric encryption to communicate privately, you have to exchange public keys. Everyone with your public key can then send you messages that only you can read.

Figure 3 shows the simplified process. For performance reasons, the message in that picture is usually not the actual data you want to send, but a symmetric encryption key that will be exchanged with the private key holder and then used to encrypt/decrypt all messages flowing between the two parties.

Figure 3: Encryption and decryption

Conclusion

In this lesson, you learned that keys are just numbers. Very big numbers, that have specific properties. They are often displayed in hexadecimal, which makes things a bit confusing for beginners.

These keys are used together with ECC-based algorithms and in the case of Ethereum, with a specific set of parameters that are the same in the whole Ethereum network to ensure, all participants have the same results when signing and verifying data.

In the next lesson, you will learn more about externally owned accounts, and how they relate to the keys we discussed here.