The Diffie-Hellman Key Exchange
By: Eric Gustin
Tags: Math, Python, Cryptography, Mathematics, Diffie Hellman

Bringing It All Together: An Example in Python of the Diffie-Hellman Key Exchange Which Utilizes the Miller-Rabin Primality Test:

We will now implement the aforementioned key exchange and algorithm in Python.

The Miller-Rabin Primality Test in Python

Below is a brief description of each function in the proceeding code which will return a pseudoprime p such that (p-1)/2 is also pseudoprime when the chooseP() function is called.

powerTests(a, m, n, k): This is step 4 of the Miller-Rabin Primality Test. We first set b equal to a^m (mod n) by utilizing the Python pow(base, exponent, modulus) function. From here, we realize that if b ≡ ±1 (mod n), then b equals 1 or n-1. If this is the case, then n is pseudoprime and we return True to indicate this finding. Otherwise, if the pseudoprimality of n has not been determined yet, then we iterate over all possible values of r and check if b^(2^r)≡-1(mod n) by utilizing the Python pow(base, exponent, modulus) function. Note that if this is the case, then b^(2^r) = n-1. So, if b^(2^r)≡-1(mod n) for any r, then n is pseudoprime and we return True to indicate this finding. Otherwise, we return False. computeMandK(n): This is step 2 of the Miller-Rabin Primality Test. We start by initializing m and k such that m = n-1 and k = 0. Note that with these initial values of m and k, the equation n-1 = m(2^k) is satisfied. However, m may not be odd, so we enter a while loop and update the values of m and k until m is odd. Note that by adding 1 to k and by dividing m by 2 on each loop iteration, the equation n-1 = m(2^k) continues to be satisfied. generateRandomInt(lowerBound, upperBound): This function is used to choose p and a, thus it is steps 1 and 3 of the Miller-Rabin Primality Test. Returns a random integer Z such that lowerBound≤Z≤upperBound. MRPrimalityTest(): Continues to perform the Miller-Rabin Primality Test on random 29-digit integers until a pseudoprime is found. isPrime(n): Performs the Miller-Rabin Primality Test on (p-1)/2. chooseP(): This is the main function from which all other functions stem from. It ensures that a pseudoprime is found that can be used for the Diffie-Hellman Key Exchange. That is, p and (p-1)/2 are pseudoprime. It also ensures that 2 has order (p-1)/2.

Simulating PersonA and PersonB With a Person Object:

To implement the remaining steps of the Diffie-Hellman Key Exchange, we need to somehow represent PersonA and PersonB so that tasks such as choosing secret integers n and m, computing and sharing g^n (mod p) and g^m (mod p), and computing the shared secret key s are possible. We will achieve this by creating a Person class that will be used to create the objects personA and personB. Here is a brief description of the data members and methods of the Person class:

Data Members:

p: The agreed upon pseudoprime which was found using the Miller-Rabin Primality Test. g: The agreed upon integer which has the same order as (ℤ/pℤ)* and 1<g<p. _secretInt: For personA, this is n and for personB this is m. intToShare: The integer that they share with the other person. intFromOtherPerson: The integer that was shared by the other person. _sharedSecretKey: The shared secret key s.

Methods:

__init__(self, p, g): Initialize all data members. chooseSecretInt(self): Secretly choose a random integer. For personA, this is n and for personB, this is m. setIntFromOtherPerson(self, intFromOtherPerson): Takes the integer that the other person shared as a parameter and sets the data member intFromOtherPerson equal to this parameter. computeIntToShare(self): Helper function for sendInt(self). Computes and returns g^(_secretInt) (mod p) by using the Python pow(g, _secretInt, p) function. sendInt(self): Returns the integer to share with the other person. computeSharedSecretKey(self): Computes the shared secret key and stores it in its _sharedSecretKey data member.

Performing the Diffie-Hellman Key Exchange:

Below is a working example of the Diffie-Hellman Key Exchange that utilizes all of the code that we have previously talked about. The program imports the Person class and the chooseP() function from MillerRabinPrimalityTest.py. The program then chooses p and g according to the Diffie-Hellman Key Exchange requirements. PersonA and PersonB are then created and they each choose a secret key. Each person then sends and receives a computed integer corresponding to steps 4 and 5 of the Diffie-Hellman Key Exchange. Finally, each person computes s and the result is printed to the console.

A sample output of the preceding program shows that our implementation of the Diffie-Hellman Key Exchange was successful!