1. Introduction

The article is devoted to the development of the library that implements the Diffie – Hellman cryptographic algorithm of key exchange. The library appeared as a result of the necessity to use the Diffie – Hellman algorithm without the involvement of any third-party libraries.

2. Diffie – Hellman Algorithm of Key Exchange

2.1 Description of the Algorithm

Diffie – Hellman algorithm is an algorithm that allows two parties to get the shared secret key using the communication channel, which is not protected from the interception but is protected from modification.

Diffie – Hellman algorithm is extremely simple in its idea and with it has a rather high level of cryptographic stability, which is based on the supposed complexity of the discrete problem of taking the logarithm.

Supposing there are two participants of the exchange (let’s call them Alice and Bob, as it is traditionally established in cryptography). Both of them know two numbers P and G. These numbers are not secret and can be known to anyone. The goal of Alice and Bob is to obtain the shared secret key to help them to exchange messages in future.

For this, they generate two big random numbers (so called private keys): Alice - number Xa, Bob - number Xb. After this, Alice computes the value of the public key:

Ya=(G^Xa) mod P

and sends it to Bob.

In his turn, Bob computes the value of his public key:

Yb=(G^Xb) mod P

and sends it to Alice.

At the second stage, on the basis of her private key and the public key, received from Bob, Alice computes the value

and they can be used as the secret key by Alice and Bob. In practical implementations, numbers of 10^100 order are used for Xa and Xb, for P - 10^300. The G number often has the value in the range of the first ten.

2.2 Brief Survey of Some Existing Implementations

There are many cryptographic libraries that include the Diffie – Hellman algorithm. But we cannot always afford to use the whole third-party library. Using the Windows Crypto API functions can be the alternative. But there are also pitfalls here. For security purposes, Windows Crypto API doesn’t allow to receive the computed private key in its pure form, but only some program entity, which can be used for the organizing of message encryption with the help of this key. Often it is enough but there are situations when before the usage of the computed secret key, it is necessary to perform some operations with it, which are not supported by Windows Crypto API, or to use this key as the secret key for your own algorithm of data encryption. I faced just this very situation.

3. C++ Library, Which Implements the Algorithm

3.1 Class ULong of Long Integer with the Arbitrary Dimension

Diffie – Hellman algorithm is very simple but operates with very big numbers. Thus, the main complexity for its implementation is the creation of the entity, which can perform arithmetical operations over these big numbers.

It receives a number of bytes that are allocated for the storage of the number as a parameter of the pattern. The class implements all simple arithmetical operations, which are intrinsic for the standard unsigned int.

It is worth considering the internal representation of a number in the memory. It is analogous to the standard representation of integers.

For example, the number

0x6578906578997781821055

will be represented in the internal buffer of the ULong class in the following form:

The GenerateExchangeData function generates the public key, which is sent to the second party. The latter, in its turn, can generate its own public key and send it to the first party. Having received this key, the first party can compute the shared secret key with the help of CompleteExchangeData function. By analogy, the second party can compute the same secret key, whereupon both parties can exchange messages that were encrypted with its help.

For the generation of random numbers Xa and Xb , the CryptAcquireContext and CryptGenRandom functions from Windows Crypto API are used:

Comments and Discussions

Just a quick note - this implementation assumes that the char keyword is signed by default. While this is true for most compilers, it is not the default when compiling with the Android NDK, as the "signed-ness" of char can be controlled by a gcc compiler switch. To use this with such a compiler, you should either change the gcc compiler flag to have char be signed by default, or change all uses of char in the code to signed char.

This code works great otherwise, and is nicely cross platform once this char issue sorted out.