The first and most important step in generating keys is to find a secure source of entropy or randomness. Creating a bitcoin key is essentially the same as “Pick a number between 1 and 2^256”. The exact method you use to pick that number does not matter as long as it is not predictable or repeatable. Bitcoin software uses the underlying operating system’s random number generators to produce 256 bits of entropy (randomness). Usually, the OS random number generator is initialized by a human source of randomness, which is why you may be asked to wiggle your mouse around for a few seconds. For the truly paranoid, nothing beats dice, pencil, and paper.
Why Random Numbers Used in Generating Keys?
More accurately, the private key can be any number between 1 and n – 1, where n is a constant (n = 1.158 * 10^77, slightly less than 2^256) defined as the order of the elliptic curve used in bitcoin. To create such a key, we randomly pick a 256-bit number and check that it is less than n – 1. In programming terms, this is usually achieved by feeding a larger string of random bits, collected from a cryptographically-secure source of randomness, into the SHA-256 hash algorithm which will conveniently produce a 256-bit number. If the result is less than n – 1, we have a suitable private key. Otherwise, we simply try again with another random number.
Do not write your own code to create a random number or use a “simple” random number generator offered by your programming language. Use a cryptographically-secure pseudo-random number generator (CSPRNG) with a seed from a source of sufficient entropy. Study the documentation of the random number generator library you choose to make sure it is cryptographically secure. Correct implementation of the CSPRNG is critical to the security of the keys.
Example of Randomly Generated Private Key
Below is a randomly generated private key shown in hexadecimal format (256 binary digits shown as 64 hexadecimal digits, each 4 bits):
Randomly generated private key (k):
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
The size of bitcoin’s private key space, 2^256, is an unfathomably large number. It is approximately 10^77 in decimal. The visible universe is estimated to contain 10^80 atoms.
To generate a new key with the Bitcoin Core Client, use the getnewaddress command. For security reasons, it displays the public key only, not the private key. To ask bitcoind to expose the private key, use the dumpprivkey command. The dumpprivkey shows the private key in a base-58 checksum encoded format called the Wallet Import Format (WIF), which we will examine in more detail in “Private Key Formats”. Here’s an example of generating and displaying a private key using these two commands:
$ bitcoind getnewaddress
1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
$ bitcoind dumpprivkey 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
The dumpprivkey command opens the wallet and extracts the private key that was generated by the getnewaddress command. It is not otherwise possible for bitcoind to know the private key from the public key unless they are both stored in the wallet.
You can also use the command-line sx tools to generate and display private keys:
New key with sx tools
$ sx newkey
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
What are Keys and Addresses in Bitcoin?
Public Keys
The public key is calculated from the private key using elliptic curve multiplication, which is irreversible: K = k * G where k is the private key, G is a constant point called the Generator Point, and K is the resulting public key. The reverse operation, known as “finding the discrete logarithm” — calculating k if you know K — is as difficult as trying all possible values of k, i.e., a brute-force search.