Elizar Pepino

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() {
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)
}
``````

TRY IT!

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.

🖖🤓