An Efficient and Secure Key Exchange Method: X25519 and Blake2b

Well, it all started in 1976, when Diffie and Hellman proposed the Diffie-Hellman key exchange method. And we are still using it today. The…

An Efficient and Secure Key Exchange Method: X25519 and Blake2b

Well, it all started in 1976, when Diffie and Hellman proposed the Diffie-Hellman key exchange method. And we are still using it today. The discrete log methods have been replaced by elliptic curve methods, and we have added in more authentication of the public key, but it’s still roughly the same method. For this Alice generates a, and Bob generates b, and they compute their public key values of aG and bG, respectively (and where G is the base point on the curve). When Alice receives bG, she computes a.(bG) to get abG, and Bob takes aG, and computes b.(aG) to get abG. They then have the same shared key.

So how can we speed the process up, and use secure methods? Well, one way is to use the mighty X25519 curve and the highly efficient Blake2b hashing method (created by Jean-Philippe Aumasson). For this, we can hash in the public keys of Bob and Alice, too. In the following, we pass Bob and Alice’s public key, and then compute the shared key as before (a.PKb and b.PKa) but we also hash in the public keys of Bob and Alice. For this, we take a 512-bit Blake2b hash and then take the lower 256 bits for our Rx key, and the upper 256 bits for our Tx key:

We now have two keys made from the 512-bit Blake2b hash value. The key that Alice uses for the transmit is the key that Bob will use for his receive, and the key that Bob uses for his transmit will be the key that Alice will use for her receive. Note that “||” just represent a concatenations of the data that is used for the hash. Obviously, the order of the public keys will matter in creating the shared key, so both Bob and Alice will add the public keys to the hashing method in the same order. Normally either Bob or Alice is the server, and the other one is the client. We then use different methods to compute the shared session key, dependent on whether we are creating a server or a client session key.

If Alice has a secret key of a and a public key of a.G, and Bob has a private key of b and a public key of b.G, Alice’s keys will be:

and for Bob:

Note that Blake512() identifies a 512-bit hash for Blake2b. For this, we can use PyNacl and which is a Python binding to Libsodium. The code is [here]:

import nacl.bindings as b
import binascii
bob_pk, bob_sk = b.crypto_kx_keypair()
alice_pk, alice_sk = b.crypto_kx_keypair()
print ("Bob public key: ",binascii.b2a_hex(bob_pk))
print ("Bob private key: ",binascii.b2a_hex(bob_sk))
print ("Alice public key: ",binascii.b2a_hex(alice_pk))
print ("Alice private key: ",binascii.b2a_hex(alice_sk))
bob_rx_key, bob_tx_key=b.crypto_kx_server_session_keys(bob_pk,bob_sk,alice_pk)
alice_rx_key, alice_tx_key=b.crypto_kx_client_session_keys(alice_pk,alice_sk,bob_pk)
print ("\nBob RX key: ",binascii.b2a_hex(bob_rx_key))
print ("Bob TX key: ",binascii.b2a_hex(bob_tx_key))
print ("Alice RX key: ",binascii.b2a_hex(alice_rx_key))
print ("Bob TX key: ",binascii.b2a_hex(alice_tx_key))
if (bob_rx_key == alice_tx_key): print ("\nBob's Rx key is same as Alice's Tx key")
if (alice_rx_key == bob_tx_key): print ("Alice's Rx key is same as Bob's Tx key")

A sample run is [here]:

Bob public key:  b'4fc8602318f7a27564023e206e8c69be0fca5f8011ef9b45a90a68d0f9579f1e'
Bob private key: b'd437cf35122b0af9e895d6f7c6954bf82893a6161017b50c889e31abbeb34bd3'
Alice public key: b'fdce4855f057166b5f0da4b3a6fc3504da07ac22ff5a48eca29247fdb4946376'
Alice private key: b'a16d5fb38f0697774524a1167c147167cb22a99c039887a4605cbe3779cbaf3c'
Bob RX key:  b'177cd69c0f6d2832e7b30df86eb379f5a5827cca7881fe2e625fd654826d43cd'
Bob TX key: b'71b374f04a4ffcd67515e2747127c46b0b2c7e8701bcb60372d16e260bd2000a'
Alice RX key: b'71b374f04a4ffcd67515e2747127c46b0b2c7e8701bcb60372d16e260bd2000a'
Bob TX key: b'177cd69c0f6d2832e7b30df86eb379f5a5827cca7881fe2e625fd654826d43cd'
Bob's Rx key is same as Alice's Tx key
Alice's Rx key is same as Bob's Tx key

And here is the Repl.it source:

If you want to learn more about the Blake2b and Blake3 hashes:

And Curve 25519: