# Bitcoin Generate Private Key C++

I’ve been wondering how Bitcoin addresses are generated. This post and the ones following will explore, step by step, how to transform a Bitcoin private key to a public address.

I know that Bitcoin public and private keys are Elliptic Curve DSA (ECDSA) key pairs, and I’ve seen the `Q = dG`

explanation on a few sites, but they leave out some details. I want to experiment for myself, so this post describes how to derive a public key from a private key with runnable code.

- Public Key Cryptography, or Asymmetric Cryptography, is a cryptographic system that uses pairs of keys: Public Key and Private Key. It is one of the most important (if not the most important) part of cryptocurrency protocols, and it is used in sev.
- Apr 29, 2018 Bitcoin Private Key Generator 2019 Bitcoin Private Key Scanner Marcene Kolb. Unsubscribe from Marcene Kolb? Cancel Unsubscribe. Subscribe Subscribed Unsubscribe 161.
- Question: How many public keys per private key / address? I'm curious about the structure of the relationship(s) between Bitcoin addresses, public keys, and private keys. My previous assumption was that from each private key would derive only one public key, and one address via nested RIPEMD160 and SHA256 one-way hash functions.

This is the first post in a four-part series titled “Computing a Bitcoin Address”. Here are all the articles in the series:

- Part 1: Private to Public Key (this post)
- Part 2: Public Key to (Hex) Address
- Part 3: Base58Check Encoding
- Part 4: Wallet Import Format (WIF)

The accepted Stack Overflow answer from the linked elliptic curve question above says that in the `Q = dG`

equation, `Q`

is the public key and `d`

is the private key, but does not explain `G`

, the group parameter. Luckily, some Googling quickly finds that Bitcoin uses the `secp256k1`

ECDSA curve.

Jul 16, 2018 We’ll use this private key throughout the article to derive both a public key and the address for the Bitcoin wallet. What we want to do is to apply a series of conversions to the private key to get a public key and then a wallet address. Most of these conversions are called hash functions. Generate a Bitcoin address. With this generator it is possible to generate a random Bitcoin address.By clicking on the generate button based on the selection the Bitcoin public, wallet and private key then is generated. All keys can be copied to clipboard with the corresponding copy button.

Next, I looked at the OpenSSL`libcrypto`

C library, in `EC_KEY_generate_key`

(the function mentioned in the Stack Overflow post). Here’s the line that performs the multiplication:

In this case, I’m supplying `priv_key`

, and `pub_key`

is the output parameter, so I just need the appropriate group for the first parameter. OpenSSL has already defined the `secp256k1`

curve, so it’s just a matter of getting the right data representation. Here is the header for `EC_POINT_mul`

from the OpenSSL library:

Looks like we need an `EC_GROUP`

. To create one we call `EC_GROUP_new_by_curve_name`

.

Putting everything together, here’s a function `priv2pub`

that computes a public key from a private key (disclaimer: the code has no error-checking so don’t use this in production):

The function assumes that the input private key is in hex, and returned public key is in hex as well. I had to first convert the private key to `BIGNUM`

, which is OpenSSL’s number representation for arbitrary precision arithmetic. The computed public key is an OpenSSL `EC_POINT`

data structure, which represents a curve coordinate. The curve coordinate is converted back to hex using `EC_POINT_point2hex`

. Public keys can either be compressed or uncompressed, and the format of the output of `priv2pub`

depends on the `form`

input parameter, which can be one of three values.

To test this function, I found a sample public/private key pair from this Bitcoin wiki article. The private key from the article is `18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725`

and the public key is `0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6`

. The public key begins with `0x04`

so we know it’s in uncompressed form (see section 2.3.3) and is 65 bytes long (see ANSI X9.62 for more details).

I used the following `main`

function to test if `priv2pub`

can compute the public key using the private key from the example:

I save the code above to a file `priv2pub.c`

:

Success!

Let’s try another example. I generated a private key with bitaddress.org, `5JQZaZrYCbJ1Kb96vFBMEefrQGuNfHSqbHbviC3URUNGJ27frFe`

, but it’s in Base58Check encoding and not hex. We’ll deal with Base58 encoding later so for now I went to the “Wallet Details” tab at bitaddress.org, entered the base58 key, and found that the private key in hex is `4DD3D47E491C5D34F9540EBF3444E3D6675015A46B61AF37B4EB7F17DDDF4E61`

and the public key is `0492EDC09A7311C2AB83EF3D133331D7B73117902BB391D9DAC3BE261547F571E171F16775DDA6D09A6AAF1F3F6E6AA3CFCD854DCAA6AED0FA7AF9A5ED9965E117`

. Let’s check what our code says:

Hurrah!

### A Racket Version

I’m using Racket, a modern LISP dialect, to experiment with Bitcoin so I want a Racket version of my conversion function as well. Fortunately, Racket has an FFI that enables Racket code to call C functions directly.

First I create a slightly different version of my C function:

The difference is an extra parameter and the representation of the public key output. This new function uses `EC_POINT_point2oct`

to return a byte string instead of a hex string. The problem is that the hex conversion function, `EC_POINT_point2hex`

, allocates, but I don’t want to manually manage memory in Racket. Because `priv2pub_bytes`

consumes an additional buffer parameter, Racket can allocate a buffer controlled by the GC prior to calling the function, and then pass in this allocated buffer.

Next I use Racket’s FFI to create a Racket wrapper function for the `priv2pub_bytes`

C function. The FFI requires a library file, so I compile the `.c`

file to a `.so`

library.

This creates a dynamic library file named `libpriv2pub.so.1.0`

.

To create a Racket value for this library, we use the Racket `ffi-lib`

function:

The first argument to `ffi-lib`

is the path of the library and the second argument specifies a list of acceptable version numbers.

Once we have a hook into the C library, we can create Racket wrappers for individual functions in the library. We use the Racket `get-ffi-obj`

function to do this:

This creates a Racket function `priv2pub_bytes`

where the first argument is a (Racket) string, the second is an integer indicating whether the output should be in compressed or uncompressed form, and the third is the output buffer. A pointer to the output buffer is also returned by the function. We make the size the output buffer equal to the uncompressed form since that is the maximum size.

Let’s make things easier to use with a couple more functions:

### Bitcoin Generate Private Key C Key

`priv-key->pub-key`

consumes a private key in hex and returns an uncompressed public key, also in hex. `priv-key->pub-key/compressed`

is similar except it returns a compressed public key (note that this function extracts only the first 33 bytes of the output buffer).

Testing our examples again, with the Racket (extended) REPL, we see that our Racket functions produce the same results:

### Software

### Private Key Bitcoin

The C code from this post is available here and the Racket code is available here. In this post, I’m using OpenSSL 1.0.1e and gcc 4.7.2, running in Debian 7.0. I had to install the `libssl-dev`

package to get the proper header files.