In this case we will use X25519 and BLAKE2b to create a key-exchange method. For the keys of (alice_sk, alice_pk) and (bob_sk, bob_pk), we generate keys of: bob_rx, bob_tx = Blake512((bob_sk . alice_pk) || bob_pk || alice_pk) and alice_tx, alice_rx = Blake512(alice_sk . bob_pk) || bob_pk || alice_pk).
Sodium: NaCl - X25519 + BLAKE2b key-exchange method |
Outline
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? While one way is to use the mighty X25519 curve and the highly efficient Blake2b hashing method. 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 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 receiving. Note that "||" just represents a concatenation 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.
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:
\(Alice_{rx} = \textrm{Blake512}_{lower256}( (a.Bob_{pk}) || Alice_{pk} || Bob_{pk}) \)
\(Alice_{tx} = \textrm{Blake512}_{upper256}( (a.Bob_{pk}) || Alice_{pk} || Bob_{pk}) \)
Bob's keys will be:
\(Bob_{tx} = \textrm{Blake512}_{lower256}( (b.Alice_{pk}) || Alice_{pk} || Bob_{pk}) \)
\(Bob_{rx} = \textrm{Blake512}_{upper256}( (b.Alice_{pk}) || Alice_{pk} || Bob_{pk}) \)
Coding
The code is:
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:
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