Skip to main content

6. Diffie-Hellman

6. Diffie-Hellman

6.1. Curve25519

The X25519 function can be used in an Elliptic Curve Diffie-Hellman (ECDH) protocol as follows:

Alice generates 32 random bytes in a[0] to a[31] and transmits K_A = X25519(a, 9) to Bob, where 9 is the u-coordinate of the base point and is encoded as a byte with value 9, followed by 31 zero bytes.

Bob similarly generates 32 random bytes in b[0] to b[31], computes K_B = X25519(b, 9), and transmits it to Alice.

Using their generated values and the received input, Alice computes X25519(a, K_B) and Bob computes X25519(b, K_A).

Both now share K = X25519(a, X25519(b, 9)) = X25519(b, X25519(a, 9)) as a shared secret. Both MAY check, without leaking extra information about the value of K, whether K is the all-zero value and abort if so (see below). Alice and Bob can then use a key-derivation function that includes K, K_A, and K_B to derive a symmetric key.

The check for the all-zero value results from the fact that the X25519 function produces that value if it operates on an input corresponding to a point with small order, where the order divides the cofactor of the curve (see Section 7). The check may be performed by ORing all the bytes together and checking whether the result is zero, as this eliminates standard side-channels in software implementations.

Test vector:

Alice's private key, a:

77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a

Alice's public key, X25519(a, 9):

8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a

Bob's private key, b:

5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb

Bob's public key, X25519(b, 9):

de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f

Their shared secret, K:

4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742

6.2. Curve448

The X448 function can be used in an ECDH protocol very much like the X25519 function.

If X448 is to be used, the only differences are that Alice and Bob generate 56 random bytes (not 32) and calculate K_A = X448(a, 5) or K_B = X448(b, 5), where 5 is the u-coordinate of the base point and is encoded as a byte with value 5, followed by 55 zero bytes.

As with X25519, both sides MAY check, without leaking extra information about the value of K, whether the resulting shared K is the all-zero value and abort if so.

Test vector:

Alice's private key, a:

9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b

Alice's public key, X448(a, 5):

9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0

Bob's private key, b:

1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d

Bob's public key, X448(b, 5):

3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609

Their shared secret, K:

07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d