What is Diffie-Hellman key exchange?
Diffie-Hellman key exchange is a mathematical method/algorithm to establish a secure connection between two parties over an untrusted channel through the creation of a shared secret between them. The exchange is done in such a way so the server can’t see the shared secret, meaning that any messages encrypted through it are only readable by the intended recipients(and not the server). Diffie-Hellman key exchange is often used in cryptography for things such as end to end encryption.
What are the mathematics?
The mathematics of Diffie-Hellman are defined as following:
- Private Key = random bytes
- Public Key = Generator^PrivateKey mod prime
- SharedSecret = OtherPublicKey^PrivateKey mod prime
The computed shared secret is the same value between both parties, and if it gets computed on the client the server doesn’t have access to it
Hyperparameters
In this implementation of Diffie-Hellman, the hyperparameters used are:
- The 2048-bit prime mentioned in rfc3526
- A generator of value 2
- 256-bit private keys
What issues does the module have?
Unfortunately, lua, unlike some other programming languages(for example python), doesn’t provide exact large integer arithmetic. More specifically lua integers stop being precise after their value surpasses 2^53. To counteract this, I had to handle calculations manually, this was done by doing calculations on lists of smaller numbers, and this in turn caused significant increase in processing time. After many optimizations, this module now takes 0.05 seconds per modular exponentiation. This means that it takes around 100 milliseconds for a user to compute their public key and shared secret, if calculations are done in parallel on two separate clients.
Other than that the module hasn’t been tested against side-channel attacks or attacks of any other form, and probably contains many vulnerabilities related to my code and not the encryption scheme itself. However the module does contain the option to create non-pseudorandom private keys through the use of API calls to random.org
API
The module currently contains the following functions:
- .P property: key: returns the prime number being used
- hexify(key): string: converts a generated key to a hex representation
- randomPrivateKey(): key: creates pseudorandom 256 bit private key
- securePrivateKey(): key: creates true random 256 bit key using random.org randomness
- hexPrivateKey(hex: string): key: creates a private key from its hex representation
- computePublicKey(privateKey: key): key: computes the public key tied to a private key (this is the one supposed to be sent over the network / server boundary)
- computeSharedSecret(privateKey: key, publicKey: key): key: computes the shared secret between the two parties, this function is meant to be used on the client where the arguments being passed in are the private key of that client and the shared public key of the other recipient.
Example Usage
--Require the module
local DH = require(script.MainModule)
print("Prime:", DH.hexify(DH.P))
local privateKey = DH.randomPrivateKey()
local privateKey2 = DH.randomPrivateKey()
--Private keys are meant to be calculated on the client
--We do everything on the server here for example simplicity
print("Bob's private key:", DH.hexify(privateKey))
warn("Alice's private key:", DH.hexify(privateKey2))
local t = os.clock()
local publicKey = DH.computePublicKey(privateKey)
local publicKey2 = DH.computePublicKey(privateKey2)
print("Public keys computed in:", os.clock()-t)
print("Bob's public key:", DH.hexify(publicKey))
warn("Alice's public key:", DH.hexify(publicKey2))
t = os.clock()
local sharedSecret1 = DH.computeSharedSecret(privateKey, publicKey2)
local sharedSecret2 = DH.computeSharedSecret(privateKey2, publicKey)
print("Shared secrets computed in:", os.clock()-t)
print("Bob's secret:", DH.hexify(sharedSecret1))
warn("Alice's secret:", DH.hexify(sharedSecret2))
local successful = DH.hexify(sharedSecret1) == DH.hexify(sharedSecret2)
print("Algorithm ran successfully:", successful)
Example Output
Other Uses
Apart from communication between clients, this module can also be used for secure communications between servers in cross-server messaging contexts where the servers are treated as if they’re talking clients and the server in between is Roblox systems.
Where to Find
The module is distributed to the creator store and available through the following link:
https://create.roblox.com/store/asset/72784368950427
It can also be used by simply requiring the module through the id:
local DH = require(72784368950427)


