June 5, 2019

# Generating ECDH Key Pair Using Go

## What is ECDH?

Elliptic-curve Diffie–Hellman (ECDH) is an anonymous key agreement protocol that allows two parties, each having an elliptic-curve public–private key pair, to establish a shared secret over an insecure channel. This shared secret may be directly used as a key, or to derive another key. The key, or the derived key, can then be used to encrypt subsequent communications using a symmetric-key cipher. It is a variant of the Diffie–Hellman protocol using elliptic-curve cryptography.

Wiki

There’s an excellent article about Elliptic Curve Cryptography from Cloudflare’s blog. Check it out here.

## Here’s the code

```
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"github.com/pkg/errors"
)
func main() {
p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(errors.Wrap(err, "Could not generate private key"))
}
privateKey := fmt.Sprintf("%x", p.D.Bytes())
pBytes := elliptic.Marshal(p.PublicKey.Curve, p.PublicKey.X, p.PublicKey.Y)
publicKey := fmt.Sprintf("%x", pBytes)
fmt.Println("Private Key:", privateKey)
fmt.Println("Public Key:", publicKey)
}
```

Running the ☝🏽 code will print something like the following:

## Let’s break the code down

### 1. Private key generation.

```
p, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(errors.Wrap(err, "Could not generate private key"))
}
```

We generate a private key using `ecdsa.GenerateKey`

function. This function takes two arguments: `elliptic.Curve`

and `io.Reader`

and returns an instance of `ecdsa.PrivateKey`

and an `error`

if there is one.

For this example, I decided to use `elliptic.P256()`

for the curve and `rand.Reader`

as the random reader.

Note:

`elliptic.P256()`

is no longer safe to use btw, but I have my reasons which I will discuss on the later part of this series.

### 2. Extract both the private and public keys’ hex values.

```
privateKey := fmt.Sprintf("%x", p.D.Bytes())
```

The `ecdsa.PrivateKey`

struct definition looks like this:

```
type PrivateKey struct {
PublicKey
D *big.Int
}
```

So to get the readable/string value of the private key, we have to get to `D *big.Int`

instance first, and then call `.Bytes()`

and store the result to a hex(base16) placeholder string `"%x"`

.

```
pBytes := elliptic.Marshal(p.PublicKey.Curve, p.PublicKey.X, p.PublicKey.Y)
publicKey := fmt.Sprintf("%x", pBytes)
```

The `ecdsa.PublicKey`

struct definition looks like this:

```
type PublicKey struct {
elliptic.Curve
X, Y *big.Int
}
```

Getting the hex value of the public key needs a bit of extra work. For this example, we use `elliptic.Marshal`

. There are, of course, other ways to do it, but this came to mind first while I was writing this article.

For the next part of this series, we will explore some good use cases for ECDH.

🖖🤓