Public Diffie-Hellman Parameter Service/Tool

UPDATE October 2018: Since our safe prime database has gotten so large, we have released a new API and safe prime page. We will continue to support both API versions so nothing breaks, but you are encouraged to explore and make use of the new features. Our Public DH parameter service has been running continuously since late May, 2015. Counts as at October 22nd, 2018 for each prime size:

  • 2048 bits: ~1,100,000 safe primes
  • 3072 bits: ~465,000 safe primes
  • 4096 bits: ~525,000 safe primes
  • 8192 bits: ~ 82,000 safe primes

In light of the [updated: then] recent Logjam discussions, periodic creating and updating of OpenSSH, OpenSSL, and OpenVPN Diffie-Hellman parameters has a renewed sense of importance. We already had our own DH parameter generation tools and have been using them for many moons, but when discussing same with some of our clients, the consensus was that it would be nice if there were a public and free service that generated a constant stream of new safe primes and generators in a format that would be easily scriptable for periodic updates/replacements for all OpenSSL based uses, as well as OpenSSH installations.

To answer that call, we have created a public dhparam/SSH moduli service, in addition to releasing dhtool, the underlying program that generates the safe primes and generators, as well as providing options to verify them. Details of the service itself are provided below, but first we feel it is important to discuss the notion of what constitutes a suitable generator. Put simply, we followed the Wei Dai method, as he stated: "find g such that g is a quadratic residue mod p." OpenSSL/OpenSSH parameters are quadratic nonresidues, and as a result, if you run openssl dhparam -check against parameters generated by dhtool (and thus the services presented here as well), it will complain about DH_NOT_SUITABLE_GENERATOR or that it cannot verify the generator. To get an idea of what this is all about and really means, this stackexchange post appears to cover it in one. To summarize, OpenSSL prefers to leak one bit by using quadratic nonresidues rather than limit the DH shared secret to half the possible values. Wei Dai, RFC3526, and ourselves prefer to limit the DH shared secret to half the possible values (in part because the shared secret is relative in size to the modulus itself unlike the private exponents which are typically much smaller). The difference in choice appears small and we are unable to find any conclusive evidence that one is better than the other, but we cannot overlook Wei Dai's choices here and decided to follow suit with him rather than OpenSSL.

Trust/Underlying Methods

Letting someone else generate any parameters for your own Diffie-Hellman encryption process certainly does introduce the possibility of malicious/intentionally bad Diffie-Hellman moduli. All of the dhtool relevant code sections are readily available to peruse, review and verify. Specifically, dhtool first finds a suitable prime q without extensive prime number verification, and then performs quick checks of its 2q+1 would-be safe prime counterpart. If both numbers appear to be prime without exhaustive verification, then exhaustive verification commences and each of q and 2q+1 are both subjected to 192 rounds of Miller-Rabin primality testing. While the Handbook of Applied Cryptography states specifically that all we are really doing is increasing the running time required in this final stage, we feel that the extra rounds of Miller-Rabin testing are worth it for semi-static DH parameters. Considering we don't wish to run actual proof tests on each of the generated parameters, HAC states: "Since the error probability of primes can be efficiently brought down to acceptably low levels (see Note 4.49 but note the dependence on t), there appears to be no reason for mandating the use of provable primes over probable primes." Our choice of t=192 is in our opinion "acceptably low level." Once the safe prime and its Sophie Germain counterpart are verified per the aforementioned, we then select our generator. See the introductory paragraphs above for commentary on our choice to ensure that g is a quadratic residue mod p.

We are a registered Australian business, and have no interest in generating malicious numbers. Still, given the nature of how these DH parameters are intended to be used, we encourage you to verify our own outputs as well as to review the code itself as to how we are generating these should you have any doubts. As to why we have chosen to make the service freely available, there is no additional cost to us in providing the service to the public at large versus generating these only for our own use (the generation process runs in constant time regardless of how many/whether anyone actually downloads them).

Download dhtool

The binary and source for dhtool is bundled with the HeavyThing library itself if you are interested in verifying existing dhparam files, or /etc/ssh/moduli files, or generating ones yourself. The download link for our library is in the top right of every page on our site, along with the SHA256 sum of the download itself. If you have downloaded the same version and your SHA256 does not match, it has been modified by parties other than ourselves.

The public DH parameter service

We have dedicated 48 CPU cores to the task of continuously generating 2048, 3072, 4096 and 8192 bit DH parameters, and the public service we present here allows access to the most-recent 128 of each. Anyone familiar with generating these safe primes will be well-aware of the long runtimes associated with the larger parameters, which is in part why we feel a public service to do this is useful. A quick and simple example can be seen in-browser: Click here for the most recent 2048 bit dhparam PEM file. Details of the service options are provided below, but in addition to providing PEM files suitable for use with OpenSSL/OpenVPN, we also present all of the most-recent DH parameters as an OpenSSH compatible moduli file: Click here for the most recent OpenSSH moduli file version.

This makes it easy to acquire and update DH parameters via simple command line scripts (curl, wget, etc.) The base url of the service is https://2ton.com.au/dhparam/BITSIZE where BITSIZE is one of 2048, 3072, 4096, 8192. Without specifying any additional options, the URL for a given BITSIZE will return the most-recently-generated DH parameter file (in PEM format suitable for use with OpenSSL/OpenVPN). The service also accepts a trailing /ssh option to produce /etc/ssh/moduli compatible output of ALL of the most-recent 128 DH parameters. If you are interested in accessing a specific index among them, you can also add a trailing /INDEX option to the end of the base URL, where INDEX is a value between 0 and 127 inclusive, 0 being the most-recent, 127 being the least-recent. Depending on the size of the parameters themselves and how many CPU cores we dedicated to generating each size determines the update frequency (and thus how old the least-recent one is). At the time of this writing, we have dedicated 1 CPU core to 2048 bit parameters, 3 CPU cores to 3072 bit parameters, 8 CPU cores to 4096 bit parameters, and 36 CPU cores to 8192 bit parameters. As a result, the average span of 2048 bit parameters (most-recent to least-recent time span) is approximately 3 hours. If you grab the /ssh version, that includes UTC timestamps at the beginning of each line in descending order so you can get an idea of the actual age and update frequencies that we are generating. The 8192 bit paramaters OTOH are considerably more expensive to generate, and the average generation time is somewhere around every 30 minutes. Specific command line examples follow:

# to acquire the latest 2048 bit dhparam:
$ curl https://2ton.com.au/dhparam/2048
# similarly for other bit sizes
$ curl https://2ton.com.au/dhparam/3072
$ curl https://2ton.com.au/dhparam/4096
$ curl https://2ton.com.au/dhparam/8192
# To acquire the 4th most recent 2048 bit dhparam:
$ curl https://2ton.com.au/dhparam/2048/3
# To acquire the latest 4096 bit /etc/ssh/moduli file:
$ curl https://2ton.com.au/dhparam/4096/ssh

dhtool Utility

The service described above is fed by an indefinite bash while:; loop that runs our own dhtool program to generate DH parameters. This can be used to generate and verify standard dhparam PEM files, as well as convert a DH PEM file to an /etc/ssh/moduli compatible line, as well as verify the contents of an entire /etc/ssh/moduli file. Usage examples follow.

Usage and options

$ ./dhtool
Usage:
To create a new DH parameter file (similar to openssl dhparam):
./dhtool [-XX] SIZE
Where SIZE is size in bits of the safe prime you want, XX specifies how many cores to use

To verify an existing dhparam file, -or- an OpenSSH moduli file:
./dhtool filename

To convert an existing dhparam file to an OpenSSH moduli compatible line:
./dhtool -convert filename

Creating new DH parameters

./dhtool [-XX] SIZE

By default, dhtool will use all available CPU cores. The -XX can be used to limit this to lower numbers, and sanity checks are performed on the value that is passed. While our public service only accepts 2048, 3072, 4096, and 8192 bit sizes, dhtool can be used to produce any bit size you want. Please note however that if you want to generate HUGE DH parameters, you will need to adjust the bigint_maxwords setting and recompile dhtool.

Verifying an existing DH parameter file or SSH moduli

./dhtool filename

By passing dhtool a filename, either a DH parameter file in PKCS#3 PEM format, or an /etc/ssh/moduli file, dhtool will perform rigorous verification of the safe prime, its Sophie Germain counterpart, as well as determine whether the generator(s) are quadratic residues mod p, and if not, presents an alternative that is. (You'll note that with all OpenSSL generated DH parameters, our verifier will state such and provide an alternative generator).

Converting a PEM file to SSH compatible moduli line

./dhtool -convert filename

By passing dhtool a PEM filename with the -convert option, it will convert the PEM format to a line suitable for inclusion in an /etc/ssh/moduli file. Please note that in doing so, all fields except the Time, Generator, and Modulus are hard coded.