Diffie-Hellman Key Exchange

22 May 2020

This post introduces the Diffie-Hellman key exchange protocol. In the previous post we saw how to build a private set intersection (PSI) protocol on top of the Paillier cryptosystem. We can also build a PSI protocol on top of the Diffie-Hellman key exchange protocol, as we’ll see next time.

The problem

Alice and Bob want to send encrypted messages to each other using a symmetric encryption scheme, so they need a shared secret key for encryption and decryption. How do they agree on a secret key without revealing it to Eve who is eavesdropping on all their communications?

The solution

The solution to the problem is to find two secret-based one-way functions whose composition is commutative. Let’s break this down…

Note that cryptographic hash functions with secret salts, although one-way, generally do not meet the requirement because their composition is not commutative: \(SHA256(secret_1 \Vert SHA256(secret_2 \Vert input))\) is not the same as \(SHA256(secret_2 \Vert SHA256(secret_1 \Vert input))\).

The original proposal from Diffie and Hellman is to use modular exponentiation as detailed below. This is because it is easy to compute \(g^e \mod p\) but difficult to compute the values of \(g\) and \(e\) given only the output and the modulus \(p\). So if you pick two secret exponents \(a\) and \(b\) you get two one-way functions: \(f_1(x) = x^a \mod p\) and \(f_2(x) = x^b \mod p\). Moreover, the composition of these functions is commutative because \((g^a)^b = (g^b)^a \mod p\).

The protocol

  1. Alice randomly generates a private key \(a\), and picks a large prime \(p\) and a number \(g\), which is a primitive root modulo \(p\).
  2. Alice calculates \(A = g^a \mod p\).
  3. Alice sends \(p\), \(g\), and the calculated value \(A\) to Bob.
  4. Bob randomly generates a private key \(b\).
  5. Bob calculates \(g^{ab} \mod p\) by calculating \(A^b \mod p\).
  6. Bob calculates \(B = g^b \mod p\).
  7. Bob sends the calculated value \(B\) back to Alice.
  8. Alice calculates \(g^{ab} \mod p\) by calculating \(B^a \mod p\).

Alice and Bob now share a secret key \(g^{ab} \mod p\). Eve the eavesdropper has seen only \(g\), \(p\), \(A\), and \(B\). She is unable to derive the value of \(a\) from \(A\) or \(b\) from \(B\) efficiently without solving the discrete logarithm problem. And without either of those values she is unable to calculate the secret key.

Code

As usual, I have implemented the Diffie-Hellman key exchange protocol in my learning repository, and the usual warning applies:

WARNING: This library is not recommended for production use. It was written for learning purposes only.

const diffieHellman = require("./build/cryptosystem/diffie-hellman");

const alice = new diffieHellman.Party(); // Slow! Finding appropriate prime numbers.
const { g, p } = alice;
const bob = new diffieHellman.Party({ g, p });

const aliceIntermediateValue = alice.raise(g);
const bobIntermediateValue = bob.raise(g);

const aliceSecret = alice.raise(bobIntermediateValue);
const bobSecret = bob.raise(aliceIntermediateValue); // Same as aliceSecret

Summary

In this post we’ve seen how the Diffie-Hellman key exchange protocol allows two parties to agree on a single secret without an eavesdropper discovering what it is. Also note that Alice and Bob do not reveal their respective private keys to each other. This is an important fact, as we’ll see in the next post, where we build a PSI protocol on top of this.

comments powered by Disqus