Diffie-Hellman key exchange in Javascript

The Diffie-Hellman key exchange protocol (RFC2641) is an efficient way for two parties (that do not know each other beforehand) to establish a shared secret. This secret can then be used for encrypted communication between the two parties. Because of the simplicity of the algorithm it is a feasible to implement it in Javascript. It could serve as a way to communicate between to participants of a social network in a host-proof way (meaning the host can not access the messages that are exchanged between Alice and Bob).

The following straight forward implementation is based on the ingenious BigInt Javascript library created by Leemon Baird:

function d_h()
  // Alice tries to send to Bob, they agree on a 256 bit prime
  var p = str2bigInt(
    "10883804965994030335610375728683210724614077" + 
    "5791152305372594007835539736018383", 10, 80); 
  var g = str2bigInt("2", 10, 80);       // and on a generator
  // Alice chooses her secret randomly
  var a = str2bigInt(
    "3103830701216420526524336327874353922197141754" + 
    "5159778383387464250", 10, 80);

  // Bob chooses his secret randomly
  var b = str2bigInt(
    "26264611999731746945409581849451656136966431" + 
    "516270225144913718599547", 10, 80);

  // calculate the public key
  var A = powMod(g,a,p); var B = powMod(g,b,p);

  // A and B are exchanged publicly
  // Alice and Bob can compute the same key from A and B
  var a_sec = powMod(B, a, p);
  var b_sec = powMod(A, b, p);

  alert(bigInt2str(a_sec, 10) + '\n ' + bigInt2str(b_sec, 10));

In case you wonder how to choose p and g – so did I. Turns out a generator for those numbers is part of the Crypto++ library. The following application uses this library to calculate p and g with different length.

#include "dh.h"
#include "osrng.h"

using namespace std;
using namespace CryptoPP;
using namespace TCLAP;

int main(int argc, char** argv)
                                                   // read command line
  CmdLine cmd("Diffie Hellman p g generator", ' ', "0.1");
  UnlabeledMultiArg m("bv", "bits and values", true, "");
  cmd.add( m ); cmd.parse(argc, argv);
  vector mv = m.getValue(); mv.push_back(1);
  unsigned int bv = mv[0]; unsigned int nv = mv[1];

  AutoSeededRandomPool arngA;                       // generate p and g
  RandomNumberGenerator& rngA =
  for(unsigned short i=0; i

The application uses the TCLAP library to parse the command line. The first parameter should be the width of the prime number in bits, the second optional parameter specifies how many primes and generators should be calculated.

Here's a list of p and g I generated with different widths:

128 bits:
p=197221152031991558322935568090317202983 g=2

256 bits:
0379195027 g=3

512 bits:
6276395927762259 g=3

1024 bits:
2283245879753842682719140993487 g=2

2048 bits:
59474207550469840261684005212634493995003979085986141372247 g=2

Those numbers do not have to be calculated every time but in fact can be hard-coded in your application.


#1 JVerstry wrote on December 15, 2010:


If I may give feedback, beware of your (p,g) generator. The values it returns for g are too small for sure. Moreover, it’s not clear whether your generator makes sure that g is not a primitive element over Zp. This could lead to easy brute force attacks.

For more details, you may want to read Chapter 12 of the Practical Cryptography book by Neils Fergusson and Bruce Schneier.



#2 Sebastian Schaetz wrote on December 15, 2010:


thank you for your comment. I am by no means an expert in cryptography so I am thankful. Cryptography is a field where you can easily get a lot of things wrong if you are not knowledgeable about the topic.

I’m not sure how the mistake (too small g) happened. I guess I’m somehow using the Crypto++ library in a wrong way. In their documentation however [0] they show a similarly small value for g.

Maybe it is a good idea to use the generator as specified in RFC 5114 [1].

In any case I updated the post to warn readers about the weakness.


#3 Sebastian L. wrote on October 18, 2011:

Hey Sebastian,

I checked the book “Applied Cryptography” of Bruce Schneier (Edition of 2006). On Page 587 it states (Translated from German): “The Security of the System (Diffie-Hellman) depends very much on the values of p and g. The most important thing is that p is a big number […]. g, however, can be chosen arbitrarily if it is modulo primitive to n. There is nothing to be said against choosing the smallest possible value for g – in most cases g has only one digit.” So I guess the numbers generated by your generator are ok!


#4 suzukaII wrote on December 2, 2011:

As far as I know, g is intended to be small

#5 Sebastian Schaetz wrote on January 10, 2012:

Sebastian, suzukaII, thanks for the clarification!

#6 SmallGenerator wrote on September 4, 2013:

See the explanation here on why using 2 or 3 is perfectly secure.

Leave a comment